Ejemplo n.º 1
0
/********************************************************************
函数功能:将一块数据复制到交换区。同时将原来的块删除,
          并将该块内Addr所在页前面的页面复制回原来的块。
入口参数:Addr:要复制出来的块地址。
返    回:原来块的地址。
备    注:如果在复制回去的过程中,出现错误,
          那么说明原来的块已经损坏,需要重新影射到一个好的块。
          这时返回的地址就是重新影射过后的地址。
********************************************************************/
uint32 FlashCopyBlockToSwap(uint32 Addr)
{
 uint32 SwapAddr;
 uint32 i;
 uint32 BlockStartAddr;
 
 BlockStartAddr=(Addr)&(~(FLASH_BLOCK_SIZE-1));  //计算块起始地址
 
 while(1)
 {
  SwapAddr=FlashGetNextSwapBlock(); //获取下一个交换区
  if(0x00==(FlashEraseBlock(SwapAddr)&0x01)) //如果擦除成功
  {
   for(i=0;i<FLASH_BLOCK_SIZE/FLASH_PAGE_SIZE;i++)  //将对应块中所有页复制到交换区中
   {
    //复制一页
    if(0x01&FlashCopyPage(BlockStartAddr+i*FLASH_PAGE_SIZE,SwapAddr+i*FLASH_PAGE_SIZE))
    {
     //如果复制失败,则说明该交换块已经损坏,查找下一个可用的交换块
     goto BadSwapBlock;
    }
   }
   //全部复制完毕,则擦除掉原来的块
   if(0x01==(FlashEraseBlock(BlockStartAddr)&0x01)) //如果擦除失败
   {
    Addr=FlashDealBadBlock(Addr,1); //处理擦除时遇到的坏块
    BlockStartAddr=(Addr)&(~(FLASH_BLOCK_SIZE-1));  //计算块起始地址
   }
   //将前面部分不会写到的页复制回去
   for(i=0;i<(Addr-BlockStartAddr)/FLASH_PAGE_SIZE;i++)
   {
    //复制一页
    if(0x01&FlashCopyPage(SwapAddr+i*FLASH_PAGE_SIZE,BlockStartAddr+i*FLASH_PAGE_SIZE))
    {
     //如果复制失败,则处理该坏块
     //注意FlashDealBadBlock返回的是当前正在操作的扇区地址,
     //需要取出其块地址加上Addr原来的扇区地址合成新的扇区地址
     Addr=(FlashDealBadBlock(BlockStartAddr+i*FLASH_PAGE_SIZE,2)&(~(FLASH_BLOCK_SIZE-1)))
         +(Addr&(FLASH_BLOCK_SIZE-1));
     BlockStartAddr=(Addr)&(~(FLASH_BLOCK_SIZE-1));  //计算块起始地址
    }
   }
   return Addr; //复制完毕,返回
  }
  else //否则,擦除失败
  {
   BadSwapBlock:
   //标志该块擦除时被损坏
   FlashMarkBadCurrentSwapBlock();
  }
 }
 return Addr;
}
Ejemplo n.º 2
0
/////////////////////////////////////////////////////
//
//	FlashWriteConfig(void)
//
//	read READBUF bytes data from flash
//	store data in global variable pcContentBuf[READBUF]
//
//	Return Value:
//	0:Error
//	1:Succssed
//
//////////////////////////////////////////////////////
int FlashWriteConfig()
{
	unsigned long offset;
	int tmp,rtn;
	//int flashfd;
	
	FlashEraseBlock(0);
	rtn=FlashWrite(offset, pcContentBuf,READBUF);
	
	if( rtn < 0 )
	{
		printf("Flash read fail\n");
		return 0;
	}
		
	return 1;
	
}
static uint32_t ProgramApplicationCode(void)
{
    uint32_t ret = FTFx_OK;
    uint32_t dest;
    uint32_t size;
    uint8_t i;

    /* Erase upper half of Pflash */
    for (i = P_BLOCK_NUM/2 ; i < P_BLOCK_NUM; i++)
    {
        dest = P_FLASH_BASE + i*(P_FLASH_SIZE/P_BLOCK_NUM);
        ret |= FlashEraseBlock(&flashSSDConfig, dest, g_FlashLaunchCommand);
        if (FTFx_OK != ret)
        {
            PRINTF("\r\nFlash Erase Upper Block Error, Address: 0x%x", (int)dest);
            return ret;
        }
    }

    /*******************************************************************
        Program upper block with exact same data from lower half except
        the last sector ( for swap inficator).
        This includes security information, for use when we swap blocks
    *******************************************************************/
    dest = P_FLASH_BASE + P_FLASH_SIZE/2;
    size = P_FLASH_SIZE/2 - 2*P_SECTOR_SIZE;
    ret = FlashProgram(&flashSSDConfig, dest, size, P_FLASH_BASE, g_FlashLaunchCommand);
    if (FTFx_OK != ret)
    {
      PRINTF("\r\nFlashProgram Error, Pflash half program, Address: 0x%x", (int)dest);
      return ret;
    }
    /* program data to upper Pflash half for verification */
    ret |= FlashProgram(&flashSSDConfig, PSWAP_UPPERDATA_ADDR, PGM_SIZE_BYTE, pgmData, g_FlashLaunchCommand);
    /* Program data to lower Pflash half*/
    for (i = 0; i < PGM_SIZE_BYTE; i ++)
    {
        pgmData[i] = (i+0x10);
    }
    ret |= FlashEraseSector(&flashSSDConfig,PSWAP_LOWERDATA_ADDR, P_SECTOR_SIZE,g_FlashLaunchCommand);
    ret |= FlashProgram(&flashSSDConfig, PSWAP_LOWERDATA_ADDR, PGM_SIZE_BYTE, pgmData, g_FlashLaunchCommand);
    return (ret);
}
Ejemplo n.º 4
0
/********************************************************************
函数功能:获取下一个可用的备用块。
入口参数:无。
返    回:找到的块地址。
备    注:在该函数中会先擦除,只有成功擦除的才被返回。
********************************************************************/
uint32 FlashGetNewRemapBlock(void)
{
 uint32 i,Addr;
 for(i=0;i<FLASH_BAD_BLOCKS_REMAP;i++)
 {
  if(FLASH_BLOCK_OK==FlashRemapBlockStatus[i]) //如果该块还未用
  {
   Addr=FLASH_BAD_BLOCK_REMAP_ADDR+i*FLASH_BLOCK_SIZE; //计算地址
   if(0x01==(FlashEraseBlock(Addr)&0x01))  //如果擦除失败
   {
    FlashRemapBlockStatus[i]=FLASH_BLOCK_BAD;  //标志该块为已经损坏
   }
   else //否则,擦除成功
   {
    FlashRemapBlockStatus[i]=FLASH_BLOCK_USED; //标志为该块已被使用    
    return Addr; //返回地址
   }
  }
 }
 return -1; //如果找不到,则返回-1。
}
Ejemplo n.º 5
0
/********************************************************************
函数功能:保存坏块表到FLASH的特定位置。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void FlashSaveBadBlockTable(void)
{
 uint32 i,j,k,Sum;
 
 for(i=0;i<FLASH_BLOCKS_TABLE;i++) //标志为准备擦除
 {
  FlashWriteCommand(0x80);
  FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*(i+1) - FLASH_PAGE_SIZE);
  FlashSetPortAsOut();  //总线设置为输出口
  FlashWriteByte(0x00);  //将第一字节设置为0,表示准备擦除
  //剩余字节写0xFF
  for(j=1;j<FLASH_PAGE_SIZE;j++)
  {
   FlashWriteByte(0xFF);
  }
  FlashWritePage(); //写页
 }
 
 for(i=0;i<FLASH_BLOCKS_TABLE;i++) //将坏块表写入这三块
 {
  FlashEraseBlock(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i); //擦除一块
  FlashWriteCommand(0x80);
  FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i); //写入第一块的开始位置
  FlashSetPortAsOut();  //总线设置为输出口
  FlashWriteByte(0x00);  //将第1字节设置为0
  FlashWriteByte(0x55);  //将第2字节设置为0x55
  FlashWriteByte(0xAA);  //将第3字节设置为0xAA
  FlashWriteByte(0xFF);  //将第4字节设置为0xFF
  Sum=0x1FE;
  //接着写坏块数量,并统计校验和
  FlashWriteByte((FlashBadBlocksCount>>24)&0xFF);
  Sum+=(FlashBadBlocksCount>>24)&0xFF;
  FlashWriteByte((FlashBadBlocksCount>>16)&0xFF);
  Sum+=(FlashBadBlocksCount>>16)&0xFF;
  FlashWriteByte((FlashBadBlocksCount>>8)&0xFF);
  Sum+=(FlashBadBlocksCount>>8)&0xFF;
  FlashWriteByte((FlashBadBlocksCount)&0xFF);
  Sum+=(FlashBadBlocksCount)&0xFF;
  j=8; //写了8字节
  //保存坏块表
  for(k=0;k<sizeof(FlashBadBlockTable[0][0])*FLASH_BAD_BLOCKS_REMAP*2;k++)
  {
   if(0==(j&(FLASH_PAGE_SIZE-1))) //如果超过了页,则需要重新写新页
   {
    FlashWritePage(); //写页
    FlashWriteCommand(0x80);
    FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i + j);
    FlashSetPortAsOut();  //总线设置为输出口
   }
   Sum+=((uint8 *)FlashBadBlockTable)[k]; //求校验和
   FlashWriteByte(((uint8 *)FlashBadBlockTable)[k]);  //写一字节
   j++;
  }
  //保存重影射区的状态表
  for(k=0;k<sizeof(FlashRemapBlockStatus[0])*FLASH_BAD_BLOCKS_REMAP;k++)
  {
   if(0==(j&(FLASH_PAGE_SIZE-1))) //如果超过了页,则需要重新写新页
   {
    FlashWritePage(); //写页
    FlashWriteCommand(0x80);
    FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i + j);
    FlashSetPortAsOut();  //总线设置为输出口
   }
   Sum+=((uint8 *)FlashRemapBlockStatus)[k]; //求校验和
   FlashWriteByte(((uint8 *)FlashRemapBlockStatus)[k]);  //写一字节
   j++;
  }
  for(;0!=(j&(FLASH_PAGE_SIZE-1));j++) //将剩余部分写入0xFF
  {
   FlashWriteByte(0xFF);
  }
  FlashWritePage();   //写页
  
  //已完成写状态及校验和写入到该块的倒数第二页
  FlashWriteCommand(0x80);
  FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*(i+1) - 2*FLASH_PAGE_SIZE);
  FlashSetPortAsOut();  //总线设置为输出口
  FlashWriteByte(0x00);  //将第一字节设置为0,表示已经写入
  //将校验和取反加1,这样累加结果就为0
  Sum=(~Sum)+1;
  //写校验和
  FlashWriteByte((Sum>>24)&0xFF);
  FlashWriteByte((Sum>>16)&0xFF);
  FlashWriteByte((Sum>>8)&0xFF);
  FlashWriteByte((Sum)&0xFF);
  //剩余字节写0xFF
  for(j=5;j<FLASH_PAGE_SIZE;j++)
  {
   FlashWriteByte(0xFF);
  }
  FlashWritePage(); //写页
 }
}
Ejemplo n.º 6
0
/* erase flash, addr is base of a block of a byte-wide flash */
FlashError_t
BDMFlashEraseBlock( unsigned int addr )
{
    return (FlashEraseBlock( &Flash,
                             addr /* base of sector of byte-wide flash */ ));
}