WinCE Eboot中的OEM Flash函数

作者: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,给个微软的例子:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

  1. #defineFLASH_START0
  2. #defineFLASH_LENGTH0x02000000
  3. BOOLOEMIsFlashAddr(DWORDdwAddr)
  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. BOOLOEMStartEraseFlash(DWORDdwStartAddr,DWORDdwLength)
  2. {
  3. ULONGi=0;
  4. ULONGnNumBlocks=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("Erasingflashblocks:startblock=%dendblock=%d\r\n",gnStartBlock,gnEndBlock);
  27. return(TRUE);
  28. }

3. void OEMContinueEraseFlash (void)

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

  1. voidOEMContinueEraseFlash(void)
  2. {
  3. UCHARnEraseCount=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-flasheraseerror(blocknumber%d).\r\n",gnBlockCount);
  13. return;
  14. }
  15. ++gnBlockCount;
  16. --nEraseCount;
  17. }
  18. return;
  19. }

4. BOOL OEMFinishEraseFlash (void)

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

  1. BOOLOEMFinishEraseFlash(void)
  2. {
  3. EdbgOutputDebugString("INFO:Finishingflasherase...\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. BOOLOEMWriteFlash(DWORDdwImageStart,DWORDdwImageLength)
  2. {
  3. DWORDdwFlashAddr,dwExtraBytes=0;
  4. LPBYTEpbCache=NULL;
  5. UCHARnNumBlocks=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-unabletowritetoblock(blockaddress=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-unabletowritetoblock(blockaddress=0x%x).\r\n",dwFlashAddr);
  39. return(FALSE);
  40. }
  41. }
  42. return(TRUE);
  43. }

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

你可能感兴趣的:(C++,c,Flash,Office,WinCE)