WinCE Eboot中的OEM Flash函数

来源:互联网 发布:在淘宝上退货的流程 编辑:程序博客网 时间:2024/05/17 04:11

作者:ARM-WinCE

 

EBOOT中提供了操作Flash的功能,可以将下载的WinCE image烧到Flash当中,这需要实现一些Flash相关的OEM函数。

 

这些OEM函数会在BLCOMMON模块中被调用,也就是在blcommon.c文件的DownloadImage函数中被调用。在DownloadImage函数中,一般image文件的header会被先下载并进行解析。然后调用OEMIsFlashAddr判断image所在的区域,如果是在Flash的地址空间内,那么接下来会下载image文件并调用Flash相关的OEM函数将Flash擦除并写入。下面简单介绍一下这些函数:

 

1. BOOL OEMIsFlashAddr(DWORD dwAddr)

该函数用于判断下载的WinCE image文件是在Flash区域中还是在RAM区域中,dwAddrimage文件的地址,如果在Flash区域中返回TRUE,否则返回FALSE,给个微软的例子:

  1. #define FLASH_START      0
  2. #define FLASH_LENGTH     0x02000000
  3. BOOL OEMIsFlashAddr(DWORD dwAddr)
  4. {
  5.         //根据Flash的起始地址和长度判断该地址是否在Flash区域内
  6.         if ((dwAddr >= FLASH_START) && (dwAddr < (FLASH_START + FLASH_LENGTH)))
  7.         {
  8.                 return(TRUE);
  9.         }
  10.     return(FALSE);
  11. }

 

2. BOOL OEMStartEraseFlash(DWORD dwStartAddr, DWORD dwLength)

该函数用于初始化Flash的擦除,dwStartAddr表示要擦除的起始地址,dwLength为长度。通过这两个参数计算Flash中要被擦除的起始block和最后一个block,以及要擦除多少个block,给个微软的例子:

  1. BOOL OEMStartEraseFlash (DWORD dwStartAddr, DWORD dwLength)
  2. {
  3.     ULONG i = 0;
  4.     ULONG nNumBlocks = 0;
  5.     //判断起始地址和终止地址是否都在Flash区域内
  6.     if (!OEMIsFlashAddr(dwStartAddr) || !OEMIsFlashAddr(dwStartAddr + dwLength - 1))
  7.     {
  8.         return(FALSE);
  9.     }
  10.     //确认该起始地址是Block对齐的
  11.     if (dwStartAddr % FLASH_BLOCK_SIZE)
  12.     {
  13.         return(FALSE);
  14.     }
  15.     //确认长度是4字节对齐
  16.     if (dwLength & 0x03)
  17.     {
  18.         return(FALSE);
  19.     }
  20.     //根据Flash的基地址和Flash的Block大小计算要擦除的起始block和最后一个
  21.     //block以及多少个Block
  22.     gnStartBlock = (dwStartAddr - FLASH_BASE) / FLASH_BLOCK_SIZE;
  23.     gnEndBlock   = ((dwStartAddr + dwLength + (FLASH_BLOCK_SIZE - 1) - FLASH_BASE) / FLASH_BLOCK_SIZE);
  24.     gnBlocks     = (int)(gnEndBlock - gnStartBlock);
  25.     gnBlockCount = gnStartBlock;
  26.     EdbgOutputDebugString("Erasing flash blocks: start block = %d  end block = %d/r/n", gnStartBlock, gnEndBlock);
  27.     return(TRUE);
  28. }

 

3. void OEMContinueEraseFlash (void)

该函数用于擦除Flash区域,它会在image下载后被调用来擦除Flash中的block,给个微软的例子:

  1. void OEMContinueEraseFlash(void)
  2. {
  3.     UCHAR nEraseCount = BLOCK_ERASE_STEP;   //要擦除的块
  4.     //确认所有需要擦除的block都被擦除了
  5.     if (!gnBlocks || (gnBlockCount == gnEndBlock))
  6.         return;
  7.     //擦除block
  8.     while ((gnBlockCount < gnEndBlock) && nEraseCount)
  9.     {
  10.         if (CFI_Erase_Block((unsigned32*)BLOCK_ADDR(gnBlockCount), 0, NULL) != PASS)
  11.         {
  12.             EdbgOutputDebugString("ERROR: OEMContinueEraseFlash - flash erase error (block number %d)./r/n", gnBlockCount);
  13.             return;
  14.         }
  15.         ++gnBlockCount;
  16.         --nEraseCount;
  17.     }
  18.     return;
  19. }

 

4. BOOL OEMFinishEraseFlash (void)

该函数用于确认Flash中所有的block都被擦除完成,给个微软的例子:

  1. BOOL OEMFinishEraseFlash(void)
  2. {
  3.     EdbgOutputDebugString("INFO: Finishing flash erase.../r/n");
  4.     while(gnBlocks && (gnBlockCount != gnEndBlock))
  5.     {
  6.         OEMContinueEraseFlash();
  7.     }
  8.     return(TRUE);
  9. }

 

5. BOOL OEMWriteFlash(DWORD dwImageStart, DWORD dwImageLength)

该函数用于将下载的image写入到Flash当中,dwImageStart为被写入imageFlash中的起始地址,dwImageLengthimage的大小,给个微软的例子:

  1. BOOL OEMWriteFlash(DWORD dwImageStart, DWORD dwImageLength)
  2. {
  3.     DWORD dwFlashAddr, dwExtraBytes = 0;
  4.     LPBYTE pbCache = NULL;
  5.     UCHAR nNumBlocks = 0;
  6.     //确认起始地址和长度都在Flash区域内
  7.     if (!OEMIsFlashAddr(dwImageStart) || !OEMIsFlashAddr(dwImageStart + dwImageLength - 1))
  8.     {
  9.         return(FALSE);
  10.     }
  11.     //确认起始地址是Block字节对齐的
  12.     if (dwImageStart % FLASH_BLOCK_SIZE)
  13.     {
  14.         return(FALSE);
  15.     }
  16.     //计算要写入的block数量
  17.     nNumBlocks   = (UCHAR)(dwImageLength / FLASH_BLOCK_SIZE);
  18.     dwExtraBytes = (dwImageLength % FLASH_BLOCK_SIZE);
  19.     dwFlashAddr  = dwImageStart;
  20.     pbCache      = OEMMapMemAddr (dwImageStart, dwFlashAddr);
  21.     //写Flash 
  22.     while(nNumBlocks)
  23.     { 
  24.         if (CFI_Write_Block((unsigned32*)dwFlashAddr, (unsigned32*)pbCache, FLASH_BLOCK_SIZE, NULL) != PASS)
  25.         {
  26.             EdbgOutputDebugString("ERROR: OEMWriteFlash - unable to write to block (block address=0x%x)./r/n", dwFlashAddr);
  27.             return(FALSE);
  28.         }
  29.         dwFlashAddr += FLASH_BLOCK_SIZE;
  30.         pbCache = OEMMapMemAddr (dwImageStart, dwFlashAddr);
  31.         --nNumBlocks;
  32.     }
  33.     //将额外的数据写入Flash中
  34.     if (dwExtraBytes)
  35.     {
  36.         if (CFI_Write_Block((unsigned32*)dwFlashAddr, (unsigned32*)pbCache, dwExtraBytes, NULL) != PASS)
  37.         {
  38.             EdbgOutputDebugString("ERROR: OEMWriteFlash - unable to write to block (block address=0x%x)./r/n", dwFlashAddr);
  39.             return(FALSE);
  40.         }
  41.     }
  42.     return(TRUE);
  43. }
  44.  

 

上面的5个函数用于在eboot中支持Flash操作功能。一般在开发BSP的时候,如果需要在EBOOT中实现Flash的功能,会在EBOOT中创建一个Flash.c文件,在该文件中实现上述这些函数。建议看看blcommon.c中的DownloadImage函数,可以帮助理解。

原创粉丝点击