作者:wogoyixikexie@gliet

这几天,使用立宇泰2440 开发板光盘的BSP放到手持机上,运行是没有问题了,但是却发现不了盘符。后来看串口打印信息,原来是页大小根本没有识别出来,本来是2048byte的,但是打印出来确实512byte。

  1. FMD::FMD_Init
  2. FMD::FMD_Init - pBSPArgs->nfsblk = 0xffffffff
  3. FMD::FMD_Init - READ_REGISTER_BYTE(pNFSBLK) = 0x0
  4. FMD::FMD_Init Softreset .....
  5. FMD::FMD_Init Done
  6. MID = 0xec, DID = 0xdc 4th Cycle : 0x10
  7. NUMBLOCKS : 4096(0x1000), SECTORSPERBLOCK = 256(0x100), BYTESPERSECTOR = 512(0x200)
  8. //每扇区字节数并不正确。是不是这个原因导致flash盘符发现不了呢?我猜我的flash驱动

BYTESPERSECTOR 不正确就从它入手

C:/WINCE500/PLATFORM/SMDK2440A/Src/Common/Smartmedia/fmd/fmd.cpp

  1. //  OK, instead of reading it from the chip, we use the hardcoded
  2. //  numbers here.
  3. pFlashInfo->dwNumBlocks         = wNUM_BLOCKS;
  4. pFlashInfo->wSectorsPerBlock    = PAGES_PER_BLOCK;
  5. pFlashInfo->wDataBytesPerSector = SECTOR_SIZE;
  6. pFlashInfo->dwBytesPerBlock     = (pFlashInfo->wSectorsPerBlock * pFlashInfo->wDataBytesPerSector);
  7. RETAILMSG(1, (TEXT("NUMBLOCKS : %d(0x%x), SECTORSPERBLOCK = %d(0x%x), BYTESPERSECTOR = %d(0x%x) /r/n"), pFlashInfo->dwNumBlocks, pFlashInfo->dwNumBlocks, pFlashInfo->wSectorsPerBlock, pFlashInfo->wSectorsPerBlock, pFlashInfo->wDataBytesPerSector, pFlashInfo->wDataBytesPerSector));

很明显,SECTOR_SIZE是关键所在。看看SECTOR_SIZE调用以及定义的地方

// TODO: Make sector size generic
static BYTE g_pFLSBuffer[SECTOR_SIZE];——从这里看来,他像个宏定义,是常数。

  1. #ifndef __NAND_H__
  2. #define __NAND_H__
  3. #define LARGE_BLOCK_NAND        0
  4. #define SMALL_BLOCK_NAND        1
  5. #define USE_NFCE                0
  6. #define USE_GPIO                1
  7. #define LB_BLOCK_LOOP           1
  8. #define SB_BLOCK_LOOP           8
  9. //为什么会这么定义呢?这样怎么样识别大小页?
  10. #define SECTOR_SIZE             512
  11. #define SPARE_SIZE              16
  12. #define PAGES_PER_BLOCK         256                     // Phisical 64 * logical 4
  13. #define NAND_PAGE_CNT           PAGES_PER_BLOCK     /* Each Block has 32 Pages      */
  14. #define NAND_PAGE_SIZE          SECTOR_SIZE         /* Each Page has 512 Bytes      */
  15. #define NAND_BLOCK_SIZE         (NAND_PAGE_CNT * NAND_PAGE_SIZE)
  16. #endif    // __NAND_H_.
  17. ======================nand.h======================

我查找SECTOR_SIZE 出现的地方,全部是512的,三星介绍说已经支持大页flash,真是不太负责。

继续多看几个地方

现在我加了一些串口打印信息

  1. OEMIoControl: Unsupported Code 0x10100b4 - device 0x0101 func 45
  2. OEMIoControl: Unsupported Code 0x101008c - device 0x0101 func 35
  3. FMD::FMD_Init
  4. FMD::FMD_Init - pBSPArgs->nfsblk = 0xffffffff
  5. FMD::FMD_Init - READ_REGISTER_BYTE(pNFSBLK) = 0x0
  6. FMD::FMD_Init Softreset .....
  7. FMD::FMD_Init Done
  8. [S2440:  IN] ++_ReadXID()
  9. MID = 0xec, DID = 0xdc 4th Cycle : 0x10
  10. NUMBLOCKS : 4096(0x1000), SECTORSPERBLOCK = 64(0x40), BYTESPERSECTOR = 2048(0x800)
  11. FMD_LB_GetBlockStatus (0x0)0x0
  12. FMD::FMD_LB_ReadSector 0x0
  13. FMD::NAND_LB_ReadSectorInfo 0x0
  14. FMD::FMD_LB_ReadSector 0x0
  15. FMD::NAND_LB_ReadSectorInfo 0x0
  16. FMD_LB_GetBlockStatus (0x1)0x40
  17. FMD::FMD_LB_ReadSector 0x100
  18. FMD::NAND_LB_ReadSectorInfo 0x100
  19. FMD::FMD_LB_ReadSector 0x40
  20. FMD::NAND_LB_ReadSectorInfo 0x40
  21. //------------到了4096就出现错误
  22. [ERROR:nLength>4096]
  23. [ERROR:nLength>4096]
  24. FMD::FMD_LB_ReadSector 0x2b540
  25. FMD::NAND_LB_ReadSectorInfo 0x2b540
  26. FMD_LB_GetBlockStatus (0xad6)0x2b580
  27. FMD::FMD_LB_ReadSector 0xad600
  28. FMD::NAND_LB_ReadSectorInfo 0xad600
  29. FMD::FMD_LB_ReadSector 0x2b580
  30. FMD::NAND_LB_ReadSectorInfo 0x2b580
  31. .............................
  32. .............................
  33. .............................
  34. //一直检测到这里
  35. FMD_LB_GetBlockStatus (0xfff)0x3ffc0
  36. FMD::FMD_LB_ReadSector 0xfff00
  37. FMD::NAND_LB_ReadSectorInfo 0xfff00
  38. FMD::FMD_LB_ReadSector 0x3ffc0
  39. FMD::NAND_LB_ReadSectorInfo 0x3ffc0
  40. FMD_OEMIoControl: unrecognized IOCTL (0x71c24).
  41. OEMIoControl: Unsupported Code 0x10100d0 - device 0x0101 func 52
  42. OEMIoControl: Unsupported Code 0x10100f8 - device 0x0101 func 62

------根据上面的打印信息启动时候和FMD_LB_GetBlockStatus,FMD::FMD_LB_ReadSector ,NAND_LB_ReadSectorInfo 这几个函数相关。

现在我来看FMD_LB_GetBlockStatus这个函数(被FMD_GetBlockStatus 调用)

  1. //  FMD_GetBlockStatus
  2. //
  3. //  Returns the status of a block.  The status information is stored in the spare area of the first sector for
  4. //  the respective block.
  5. //
  6. //  A block is BAD if the bBadBlock byte on the first page is not equal to 0xff.
  7. //  根据一些参数确定是大页还是小页,但是这里没有支持我512Mflash的block大小
  8. DWORD FMD_GetBlockStatus(BLOCK_ID blockID)
  9. {
  10. DWORD dwResult = 0;
  11. int i;
  12. if ( blockID < wPRIMARY_NAND_BLOCKS )
  13. {
  14. if ( astNandSpec[dwPrimaryNandDevice].nSctsPerPg == 4 )
  15. {//小心LB_BLOCK_LOOP这个宏定义:#define LB_BLOCK_LOOP   1
  16. for ( i = 0; i < LB_BLOCK_LOOP; i++ )
  17. {
  18. dwResult |= FMD_LB_GetBlockStatus(blockID*(LB_BLOCK_LOOP) + i, USE_NFCE);
  19. }
  20. }
  21. else
  22. {
  23. for ( i = 0; i < SB_BLOCK_LOOP; i++ )
  24. {
  25. dwResult |= FMD_SB_GetBlockStatus(blockID*(SB_BLOCK_LOOP) + i, USE_NFCE);
  26. }
  27. }
  28. }
  29. else
  30. {
  31. if ( astNandSpec[dwSecondaryNandDevice].nSctsPerPg == 4 )
  32. {
  33. for ( i = 0; i < LB_BLOCK_LOOP; i++ )
  34. {
  35. dwResult |= FMD_LB_GetBlockStatus((blockID-wPRIMARY_NAND_BLOCKS)*(LB_BLOCK_LOOP) + i, USE_GPIO);
  36. }
  37. }
  38. else
  39. {
  40. for ( i = 0; i < SB_BLOCK_LOOP; i++ )
  41. {
  42. dwResult |= FMD_SB_GetBlockStatus((blockID-wPRIMARY_NAND_BLOCKS)*(SB_BLOCK_LOOP) + i, USE_GPIO);
  43. }
  44. }
  45. }
  46. return dwResult;
  47. }

根据上面的情况,再来看看FMD_LB_GetBlockStatus这个函数原型

  1. //  FMD_LB_GetBlockStatus
  2. //
  3. //  Returns the status of a block.  The status information is stored in the spare area of the first sector for
  4. //  the respective block.
  5. //
  6. //  A block is BAD if the bBadBlock byte on the first page is not equal to 0xff.
  7. //
  8. DWORD FMD_LB_GetBlockStatus(BLOCK_ID blockID, int mode)
  9. {
  10. SECTOR_ADDR sectorAddr = blockID << LB_NAND_LOG_2_PAGES_PER_BLOCK;
  11. SectorInfo SI;
  12. DWORD dwResult = 0;
  13. //这个函数启动的时候会被调用很多次,串口信息打开影响速度
  14. //RETAILMSG(1, (TEXT("FMD_LB_GetBlockStatus (0x%x)0x%x /r/n"), blockID, sectorAddr));
  15. BOOL bLastMode = SetKMode(TRUE);
  16. if(!FMD_LB_ReadSector(sectorAddr<<2, NULL, &SI, 1, mode))
  17. {
  18. return BLOCK_STATUS_UNKNOWN;
  19. }
  20. if(!(SI.bOEMReserved & OEM_BLOCK_READONLY))
  21. {
  22. dwResult |= BLOCK_STATUS_READONLY;
  23. }
  24. if( blockID < pBSPArgs->nfsblk )
  25. {
  26. dwResult |= BLOCK_STATUS_READONLY;
  27. }
  28. if(SI.bBadBlock != 0xFF)
  29. {
  30. dwResult |= BLOCK_STATUS_BAD;
  31. }
  32. SetKMode(bLastMode);
  33. return dwResult;
  34. }

很明显上面这个函数是根据BLOCKID读这个BLOCK的Spare区的一些信息,从上面的串口信息可以看出,这个函数要把所有的block读完,但是控制这所有block的循环在哪里呢?我现在找不到,真是太奇怪了。因为:#define LB_BLOCK_LOOP   1 所以FMD_GetBlockStatus这个函数在哪里调用了是关键。请看下面他被调用的地方

  1. static BOOL DefineLayout()
  2. {
  3. PFlashRegion pRegion = NULL;
  4. DWORD dwBlock = 0;
  5. if (!FMD_GetInfo (&g_flashInfo)) {
  6. return FALSE;
  7. }
  8. // Find the MBR to determine if there is a flash layout sector
  9. g_dwNumRegions = 0;
  10. // Find the first usuable block要找的地方就是这里了。哈哈!
  11.     while (dwBlock < g_flashInfo.dwNumBlocks) {
  12.         if (!(FMD_GetBlockStatus(dwBlock) & (BLOCK_STATUS_BAD | BLOCK_STATUS_RESERVED))) {
  13.             break;
  14.         }
  15.         dwBlock++;
  16.     }
  17. RETAILMSG(1, (TEXT("DefineLayout: dwBlock = 0x%x /r/n"), dwBlock));
  18. DWORD dwSector = dwBlock * g_flashInfo.wSectorsPerBlock;
  19. if (!FMD_ReadSector (dwSector, g_pFLSBuffer, NULL, 1)) {
  20. return FALSE;
  21. }
  22. // compare the signatures
  23. if (IS_VALID_BOOTSEC(g_pFLSBuffer))
  24. {
  25. if (!FMD_ReadSector (dwSector+1, g_pFLSBuffer, NULL, 1)) {
  26. return FALSE;
  27. }
  28. if (IS_VALID_FLS(g_pFLSBuffer))
  29. {
  30. PFlashLayoutSector pFLS = (PFlashLayoutSector)(g_pFLSBuffer);
  31. // Cache the flash layout sector information
  32. g_dwNumRegions = pFLS->cbRegionEntries / sizeof(FlashRegion);
  33. //          RETAILMSG(1, (TEXT("DefineLayout: g_dwNumRegions = 0x%x /r/n"), g_dwNumRegions));
  34. // FlashRegion table starts after the ReservedEntry table.
  35. if (g_dwNumRegions)
  36. {
  37. pRegion = (PFlashRegion)((LPBYTE)pFLS + sizeof(FlashLayoutSector) + pFLS->cbReservedEntries);
  38. }
  39. }
  40. }
  41. if (!g_dwNumRegions)
  42. {
  43. g_dwNumRegions = 1;
  44. }
  45. if (g_dwNumRegions > MAX_REGIONS)
  46. return FALSE;
  47. if (pRegion)
  48. {
  49. memcpy (g_pRegionTable, pRegion, g_dwNumRegions * sizeof(FlashRegion));
  50. }
  51. else
  52. {
  53. g_pRegionTable[0].dwStartPhysBlock = 0;
  54. g_pRegionTable[0].dwNumPhysBlocks = g_flashInfo.dwNumBlocks;
  55. g_pRegionTable[0].dwNumLogicalBlocks = FIELD_NOT_IN_USE;
  56. g_pRegionTable[0].dwBytesPerBlock = g_flashInfo.dwBytesPerBlock;
  57. g_pRegionTable[0].regionType = FILESYS;
  58. g_pRegionTable[0].dwSectorsPerBlock = g_flashInfo.wSectorsPerBlock;
  59. g_pRegionTable[0].dwCompactBlocks = DEFAULT_COMPACTION_BLOCKS;
  60. }
  61. //——这个地方非常关键,一些MBR和文件系统相关的东西都在这里了
  62. RETAILMSG(1, (TEXT("DefineLayout: g_pRegionTable[0].dwNumPhysBlocks = 0x%x /r/n"), g_pRegionTable[0].dwNumPhysBlocks));
  63. return TRUE;
  64. }

不过并没有这么顺利

#if defined (MAGNETO)
static BOOL DefineLayout();
#endif

--------------#if defined (MAGNETO) 这个并没有定义,所以上面的函数并没有被编译。从串口打印信息也可以看的出来。不过FMD_GetBlockStatus在哪里被调用多次呢?真是很晕了。难道是文件系统做的事情?

wogoyixikexie@gliet 说:
我对比了启动正常和不正常的加载饿文件系统DLL,发现有两个DLL没有被加载
wogoyixikexie@gliet 说:
diskcache.dll和fatfsd.dll没有被加载

=======================无计可施,幸好有朋友帮忙===================

gsymichael      2008年11月20日 09点10分23秒 说:
我看到你的帖子了,这个是比较奇怪的一个问题。
因为在存储管理部分对于一个块设备来说,在这里就是你的NandFlash,会创建一个对应的Stroe对象。
之后会通过注册表中Profile中的给定去相应的地方读取驱动的Dll,也就是你的smflash.dll。在这个dll中存储
管理会通过一个IoCtl去获得DISK_INFO的结构,那么这部分由于你是用FAL+FMD的结构这部分在FMD.cpp中没有体现
我之前也搞不清这个是怎么回事,后来网上有人说设置好GetInfo就OK,我猜想这个IoCtl是在FAL里面实现的,然后FAL调用
GetInfo去获得DISK的内容。
现在有个方法,就是你按照我博客的内容把Private下的CoreOS中的Storage移植到你的BSP中,这样你就可以在其中加入Debug
信息调试了。那个存储管理的代码分析我的博客上也有。
还有在你的QQ群里有个三星的技术支持,他也是用FAL+FMD结构的,你也可以问问他。

2440 wince 5.0 BSP之flash驱动分析相关推荐

  1. UT2416 wince 6.0 调试LCD35 触摸驱动参考

    UT2416 wince6.0 调试LCD35 触摸屏驱动参考 硬件平台:UT2416BV02  [友坚恒天ARM开发平台] 软件平台:wince6.0           [友坚恒天wince6.0 ...

  2. 24.Linux-Nand Flash驱动(分析MTD层并制作NAND驱动)

    1.本节使用的nand flash型号为K9F2G08U0M,它的命令如下: 1.1我们以上图的read id(读ID)为例,它的时序图如下: 首先需要使能CE片选 1)使能CLE 2)发送0X90命 ...

  3. linux nand 驱动,Linux NAND FLASH驱动分析(一)

    最近一直在忙着工作上的事情,好久都没有更新博客了,发现最近思想是比较混乱的.学任何东西都坚持不下去,既然选择驱动开发这条路就要坚持下去. 之前分析了Linux块设备驱动,是以内存块来模拟的虚拟块设备. ...

  4. [Android6.0][RK3399] PWM Backlight 驱动分析

    DTS 分析 backlight: backlight {status = "disabled";compatible = "pwm-backlight";pw ...

  5. wince5.0 2440 BSP之摄像头驱动分析

    现在看驱动就看那几个接口函数即可,现在先看初始化函数. DWORD CIS_Init(DWORD dwContext) { DWORD dwErr = ERROR_SUCCESS, bytes; RE ...

  6. wince7 屏幕控制_技术干货:WinCE 7.0下的触摸屏驱动

    在嵌入式系统中较为常用的是四线电阻式触摸屏,通过检测x轴和y轴的电压,来确定触点的位置.一般触摸屏系统结构为:触摸屏->触摸屏控制器->处理器. wince7下触摸屏的驱动分为PDD层(位 ...

  7. uboot下的nand flash驱动分析

    Nand flash芯片工作原理: ------------------------------------     Nand flash芯片型号为Samsung K9F2G08U0A,数据存储容量为 ...

  8. USB总线-Linux内核USB3.0设备控制器之UDC驱动分析(六)

    1.概述 UDC驱动的接口都定义在drivers/usb/gadget/udc/core.c文件中.USB Function驱动通过调用这些接口匹配及访问USB设备控制器,而底层USB控制器驱动要实现 ...

  9. 《Linux驱动:Nor flash驱动看这一篇就够了》

    文章目录 一,前言 二,硬件电路 2.1 脚位功能 2.2 地址移位 三,Nand Flash和Nor Flash的区别 四,Nor flash CFI规范和JEDEC规范 4.1 JEDEC规范 4 ...

最新文章

  1. 提单丢失了,怎么办?
  2. 正则表达式 BRE 与 ERE的区别
  3. Codeforces 1291 Round #616 (Div. 2) C. Mind Control(超级详细)
  4. 基础004_V7-DSP Slice
  5. Java-基本运算符
  6. 雨松MOMO《Unity 3D游戏开发》源码公布
  7. java类构造函数调用顺序_Java中的构造函数调用顺序
  8. kong自定义插件(修改官方插件)
  9. 「Linux」- 安装网易云音乐(Neteast Cloud Music) @20210330
  10. Mysql 查询根节点下所有叶子节点
  11. minic 动作句型处理
  12. react-hooks/exhaustive-deps警告
  13. python取数组最后一个元素_python数组最后一个元素
  14. 微信小程序服务端调用--小程序码 wxacode.getUnlimited 接口调用,实现微信扫码直接跳转小程序页面
  15. 里约热内卢圣徒java_里约热内卢:圣徒之城
  16. 百度云虚拟主机详细使用流程
  17. 如何控制苹果Mac电池健康管理功能?
  18. window下php自动脚本,Windows下使用VBS实现定时执行访问URL脚本(刷流量)
  19. 教你如何轻松做百度文库推广引流?
  20. 连载26:软件体系设计新方向:数学抽象、设计模式、系统架构与方案设计(简化版)(袁晓河著)

热门文章

  1. XSSF实现Excel下拉和HSSF实现Excel下拉
  2. 2019新版前端与移动开发学习路线图(视频+工具+书籍+资源)
  3. 毕业论文知网查重之应对办法
  4. 轻松搞定 Spring Cloud 2.x 微服务全家桶
  5. 云速美建站手机端使用百度app打开手机端网站闪退的问题
  6. 快速创建ROS2 packages
  7. 现代轻奢风格装修讲解
  8. esaywechat 微信公众号jsapi支付
  9. 重卡自动驾驶进入“正规战”
  10. Chrome如何使用