加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

WinCE Eboot中的OEM Flash函数

发布时间:2020-12-15 18:10:06 所属栏目:百科 来源:网络整理
导读:作者: dengxin123 转自:http://www.voidcn.com/article/p-aexlnrjc-gp.html 在EBOOT中提供了操作Flash的功能,可以将下载的WinCE image烧到Flash当中,这需要实现一些Flash相关的OEM函数。 ? 这些OEM函数会在BLCOMMON模块中被调用,也就是在blcommon.c文件

作者:dengxin123

转自:http://www.voidcn.com/article/p-aexlnrjc-gp.html


在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区域中,dwAddr是image文件的地址,如果在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为被写入image在Flash中的起始地址,dwImageLength为image的大小,给个微软的例子:

  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,?dwExtraBytes,?dwFlashAddr);
  37. ????????????return(FALSE);
  38. ????????}
  39. ????}

  40. ????return(TRUE);
  41. }

  42. ?

?

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读