none
wince 5.0下nandflash驱动代码 RRS feed

  • 问题

  • wince 5.0下nandflash驱动是FAL+FMD架构的,我找不到FAL部分的代码,希望高手(最好是何老师能光临此贴)来指点迷津。 EMAIL REMOVED,小弟在这里感激涕零啊
    2009年10月15日 2:31

答案

  • 这部分代码在CE5.0中没有开放,如果你要编写驱动,不需要关心FAL,只需要实现FMD就可以了。以下是我搜索的资料,希望对你有用:

    这里介绍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设备进行初始化。如果你的系统中有nandflashcontroller,那么你需要在这里对你的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,大page2048bytes一页,小page512bytes一页。所以大page每个扇区有2048 bytes,小page每个扇区有512 bytes

    startSectorAddr nandflash物理扇区的起始地址,对于nandflash来说,就是nandflash中从哪个page开始。

    pSectorBuff:扇区数据buffer,从nandflash中读出的每一个扇区的数据都存放在这个buffer中。

    pSectorInfoBuff:扇区信息buffer,一般每个扇区的信息会被保存在nandflash的带外数据中,针对小page,带外数据有16 bytes,大page64 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,参数为要擦除nandflashblock地址,也就是第几个block

     

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

     

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

     

    8. BOOL FMD_GetInfo(PFlashInfo pFlashInfo) 该函数用于返回flash的信息。其中pFlashInfo是一个包含flash信息的结构。

     

        pFlashInfo->flashTypeflash的类型,对于nandflash来说,应该是NAND

     

        pFlashInfo->wDataBytesPerSector:一个扇区多少个bytes,对于大page2048,对于小page512

     

        pFlashInfo->dwNumBlocksflash中总共有多少个block,查一下所用的nandflashdatasheet就知道了。

     

         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校验会对512BYTE产生3个字节的校验码,也就是说对小PAGE来说,每个PAGE3个字节的ecc校验码;对于大PAGE来说,有12个字节。这些校验码应该在写扇区数据的时候,被写在扇区的带外数据里面。当读扇区数据时,会先把数据读出来,然后根据这些数据计算ecc,再和读出来的ecc进行比较,如果一致,则表示正确。

    2009年10月16日 3:36

全部回复

  • Email removed什么意思啊?
    2009年10月16日 3:10
  • Email removed什么意思啊?
    2009年10月16日 3:10
  • 这部分代码在CE5.0中没有开放,如果你要编写驱动,不需要关心FAL,只需要实现FMD就可以了。以下是我搜索的资料,希望对你有用:

    这里介绍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设备进行初始化。如果你的系统中有nandflashcontroller,那么你需要在这里对你的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,大page2048bytes一页,小page512bytes一页。所以大page每个扇区有2048 bytes,小page每个扇区有512 bytes

    startSectorAddr nandflash物理扇区的起始地址,对于nandflash来说,就是nandflash中从哪个page开始。

    pSectorBuff:扇区数据buffer,从nandflash中读出的每一个扇区的数据都存放在这个buffer中。

    pSectorInfoBuff:扇区信息buffer,一般每个扇区的信息会被保存在nandflash的带外数据中,针对小page,带外数据有16 bytes,大page64 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,参数为要擦除nandflashblock地址,也就是第几个block

     

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

     

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

     

    8. BOOL FMD_GetInfo(PFlashInfo pFlashInfo) 该函数用于返回flash的信息。其中pFlashInfo是一个包含flash信息的结构。

     

        pFlashInfo->flashTypeflash的类型,对于nandflash来说,应该是NAND

     

        pFlashInfo->wDataBytesPerSector:一个扇区多少个bytes,对于大page2048,对于小page512

     

        pFlashInfo->dwNumBlocksflash中总共有多少个block,查一下所用的nandflashdatasheet就知道了。

     

         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校验会对512BYTE产生3个字节的校验码,也就是说对小PAGE来说,每个PAGE3个字节的ecc校验码;对于大PAGE来说,有12个字节。这些校验码应该在写扇区数据的时候,被写在扇区的带外数据里面。当读扇区数据时,会先把数据读出来,然后根据这些数据计算ecc,再和读出来的ecc进行比较,如果一致,则表示正确。

    2009年10月16日 3:36