WinCE中nandflash驱动开发介绍

本文深入探讨了基于WinCE6.0 R2的FAL+FMD架构下,如何开发NAND闪存驱动。详细介绍了初始化、卸载、读写扇区、擦除块、获取块状态、设置块状态、获取闪存信息、电源管理及自定义IO控制等关键函数的实现方法。
摘要由CSDN通过智能技术生成

先来谈一下flash,flash是一种非易失存储器,一般flash存储设备分为Nandflash和Norflash。这两种flash各有优 缺点。在读写速度上,norflash的读速度快一些,nandflash的写速度会快一些。Nandflash的容量一般都比Norflash大很多, 而且相比价格比较便宜。但是Norflash支持XIP,而nandflash不支持,而且Nandflash可能有坏块。相关的比较,网上很多文章都有 介绍,这里就说这么多了。

这里介绍nandflash驱动,在WinCE中,有专门针对flash存储设备驱动的支持,一般传统采用FAL+FMD的架构。在WinCE最新 的版本中,也就是Windows CE6.0 R2中,还支持MDD+PDD的架构。在FAL+FMD架构中,FAL层由微软来实现,我们需要实现FMD层的相关接口函数。在MDD+PDD的架构 中,MDD替换了原来架构中的FAL,而PDD相当于原来的FMD,只要实现PDD层就可以了。如果你的系统已经升级到WinCE6.0 R2,那么你应该可以在/WINCE600/Public/COMMON/OAK/DRIVERS目录下面找到这两种架构驱动的源代码。 由于MDD+PDD的架构在WinCE6.0 R2中才有支持,本人也没有实现过。所以这里只介绍基于FAL+FMD架构下,nandflash驱动的开发,这也是目前大家都采用的开发flash驱动 的架构。

如上面所说,我们需要实现FMD层的相关接口,下面来介绍一下各个接口函数:
1. PVOID FMD_Init(LPCTSTR lpActiveReg, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut): 这个是Flash设备的初始化函数。在WinCE启动的时候,要加载Flash驱动时,首先调用这个函数对flash设备进行初始化。如果你的系统中有 nandflash的controller,那么你需要在这里对你的nandflash controller进行初始化。如果没有的话,你需要针对你的硬件设计进行相关的片选,时序等进行配置。返回一个handle表示成功,这个 handle将被FMD_Deinit(..)函数用到,如果返回NULL表示失败。


2. BOOL FMD_Deinit(PVOID hFMD): 这个函数在nandflash驱动卸载的时候被调用,参数就是FMD_Init函数返回的Handle.一般在这个函数里面,你可以释放一些用到的资源, 然后关闭nandflash controller。


3. BOOL FMD_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors): 这个函数用于读nandflash的一个扇区。对于nandflash来说,分大page和小page,大page是2048个bytes一页,小 page是512个bytes一页。所以大page每个扇区有2048 bytes,小page每个扇区有512 bytes。
startSectorAddr: nandflash物理扇区的起始地址,对于nandflash来说,就是nandflash中从哪个page开始。
pSectorBuff: 扇区数据buffer,从nandflash中读出的每一个扇区的数据都存放在这个buffer中。
pSectorInfoBuff:扇区信息 buffer,一般每个扇区的信息会被保存在nandflash的带外数据中,针对小page,带外数据有16 bytes,大page有64 bytes。从nandflash的带外数据将该扇区的相关信息读出来,存放在这个buffer中。
dwNumSectors:读取多少个扇区, 对于nandflash来说相当于读取多少个page。


4. BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors): 该函数用于写nandflash的一个扇区。参数和上面的FMD_ReadSector的参数意思一样,就不多说了。


5. BOOL FMD_EraseBlock(BLOCK_ID blockID): 该函数用于擦出nandflash的一个block,参数为要擦除nandflash的block地址,也就是第几个block。


6. DWORD FMD_GetBlockStatus(BLOCK_ID blockID): 该函数获得nandflash中某一个block的状态。参数为nandflash的block地址。由于nandflash中可能有坏块,所以针对 nandflash,这个函数首先会检查当前块是否是坏块,这个一般通过读取当前block的第0个page和第1个page的带外数据。对于小page nandflash一般是读取第5个byte,对于大page nandflash一般读取第0个byte,如果不为0xff表示该块是坏块。当然,至于具体该读哪个byte,最好还是看一下所用nandflash的 datasheet,确认一下,不同的厂家可能有所不同。如果发现该块是坏块,应该返回BLOCK_STATUS_BAD。如果不是坏块,需要读取这个块 的起始扇区的扇区信息。如果读该扇区信息出错,应该返回BLOCK_STATUS_UNKNOWN,否则,判断独到的信息,返回相应结果。


7. BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus): 该函数设置nandflash某个block的状态,第一个参数是nandflash的block地址,第二个是要设置的状态。在这个函数中,首先检查 dwStatus是不是BLOCK_STATUS_BAD,如果是就对nandflash作坏块标记,然后返回FALSE。如果不是,就将 dwStatus写到该block的第0个page的扇区info中。这个函数和上面的函数正好是相反的。


8. BOOL FMD_GetInfo(PFlashInfo pFlashInfo): 该函数用于返回flash的信息。其中pFlashInfo是一个包含flash信息的结构。
pFlashInfo->flashType:flash 的类型,对于nandflash来说,应该是NAND。
pFlashInfo->wDataBytesPerSector:一个扇区多少个 bytes,对于大page是2048,对于小page是512。
pFlashInfo->dwNumBlocks:flash中总共有多 少个block,查一下所用的nandflash的datasheet就知道了。
pFlashInfo->wSectorsPerBlock: 每个block中包含多少个扇区。
pFlashInfo->dwBytesPerBlock:每个block中包含多少个bytes。


9. VOID FMD_PowerDown()和VOID FMD_PowerUp(): 这两个函数用于电源管理。FMD_PowerDown()用于关闭flash设备电源,FMD_PowerUp()用于恢复flash设备电源。根据你所 用处理器和相关硬件环境,去实现这两个函数。不实现也不会影响nandflash的使用。


10. BOOL FMD_OEMIoControl(..): 就像很多的IOControl函数一样,根据不同的case,实现相应的功能。针对nandflash来说,这里面的case不一定都需要实现。事实上, 如果什么都没有实现,也不影响nandflash的使用。在WinCE的文档中,定义了一些需要实现的case,你可以实现,也可以不去实现。


对于nandflash来说,实现上述函数就可以了。在nandflash出厂的时候,厂家已经对nandflash中的坏块进行了标记。 所以第一次对nandflash操作的时候,不要随便擦除nandflash,因为这样可能会把坏块标记擦掉,这样你就判断不出哪个块是坏块了。


关于ECC校验,目前很多处理带有nandflash controller,而且nandflash controller带有硬件ECC功能。如果没有硬件ECC,也可以使用软件ECC,软ECC的代码可以在/WINCE600/PUBLIC /COMMON/OAK/DRIVERS/BLOCK/MSFLASHFMD/ECC下找到。一般来说,ECC校验会对512个BYTE产生3个字节的校 验码,也就是说对小PAGE来说,每个PAGE有3个字节的ecc校验码;对于大PAGE来说,有12个字节。这些校验码应该在写扇区数据的时候,被写在 扇区的带外数据里面。当读扇区数据时,会先把数据读出来,然后根据这些数据计算ecc,再和读出来的ecc进行比较,如果一致,则表示正确。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhongnanjun_3/archive/2009/03/09/3973312.aspx

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值