分类: Windows平台
2013-06-27 10:13:37
一般flash存储设备分为Nandflash和Norflash。这两种flash各有优缺点。在读写速度上,norflash的读速度快一些,nandflash的写速度会快一些。Nandflash的容量一般都比Norflash大很多,而且相比价格比较便宜。但是Norflash支持XIP,而nandflash不支持,而且Nandflash可能有坏块。在FAL+FMD架构中,FAL层由微软来实现,我们需要实现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的一个扇区。
tartSectorAddr: nandflash物理扇区的起始地址。
pSectorBuff:扇区数据buffer,从nandflash中读出的每一个扇区的数据都存放在这个buffer中。
pSectorInfoBuff:扇区信息buffer,一般每个扇区的信息会被保存在nandflash的带外数据中,针对小page,带外数据有16bytes, 大page有64 bytes。从nandflash的带外数据将该扇区的相关信息读出来,存放在这个buffer中。
dwNumSectors:读取多少个扇区。
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地址。
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的使用。
对于nandflash来说,实现上述函数就可以了。在nandflash出厂的时候,厂家已经对nandflash中的坏块进行了标记。所以第一次对nandflash操作的时候,不要随便擦除nandflash,因为这样可能会把坏块标记擦掉,这样你就判断不出哪个块是坏块了。关于ECC校验,目前很多处理带有nandflash controller,而且nandflash controller带有硬件ECC功能。如果没有硬件ECC,也可以使用软件ECC,一般来说,ECC校验会对512个BYTE产生3个字节的校验码,也就是说对小PAGE(单扇区)来说,每个PAGE有3个字节的ecc校验码;对于大PAGE(4扇区)来说,有12个字节。这些校验码应该在写扇区数据的时候,被写在扇区的带外数据里面。当读扇区数据时,会先把数据读出来,然后根据这些数据计算ecc,再和读出来的ecc进行比较,如果一致,则表示正确。
来自:http://blog.csdn.net/zhandoushi1982/article/details/4577390