WINCE60下的nandflash驱动Word格式文档下载.docx
- 文档编号:19490301
- 上传时间:2023-01-06
- 格式:DOCX
- 页数:19
- 大小:733.67KB
WINCE60下的nandflash驱动Word格式文档下载.docx
《WINCE60下的nandflash驱动Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《WINCE60下的nandflash驱动Word格式文档下载.docx(19页珍藏版)》请在冰豆网上搜索。
首先我们知道是由FAL+FMDà
smflash.dll的,下面看看FAL和FMD分别对应哪些代码:
2.1FAL层
FAL:
\WINCE600\PRIVATE\WINCEOS\DRIVERS\MSFLASH,这个文件夹下的代码编译出fal.lib
也就是说FAL层是以fal.lib供链接的,fal.lib的导出文件内容如下:
LIBRARYMSFLASH
EXPORTS
DSK_Init
DSK_Deinit
DSK_Open
DSK_Close
DSK_Read
DSK_Write
DSK_Seek
DSK_IOControl
DSK_PowerDown
DSK_PowerUp
从上面的导出函数可知FAL层向应用层(如API)提供DSK接口
2.2FMD层
smflash_lib.lib:
\WINCE600\PLATFORM\DMA2443\Src\Common\Smartmedia\fmd,这个文件下的代码生成smflash_lib.lib,而\WINCE600\PLATFORM\DMA2443\Src\Common\Smartmedia\Dll
文件夹将生成smflash.dll,下面是其sources的内容:
TARGETNAME=smflash
TARGETTYPE=DYNLINK
RELEASETYPE=PLATFORM
WINCEOEM=1
DEFFILE=smflash.def
TARGETLIBS=$(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib\
SOURCELIBS=$(_COMMONOAKROOT)\lib\$(_CPUINDPATH)\fal.lib\
$(_TARGETPLATROOT)\lib\$(_CPUINDPATH)\smflash_lib.lib
可以知道smflash.dll需要链接fal.lib和smflash_lib.lib这个两个库,而fal.lib就是FAL层提供的链接库,smflash_lib.lib是FMD层提供的链接库。
3.FAL层和FMD层的交互
3.1FAL层获取FMD层的函数接口
在系统启动过程中,oal.exe加载了kernel.dll,kernel.dll加载device.dll,device.dll加载devmgr.dll,这个就是负责加载,卸载,管理流驱动的.设备管理器找到HKLM\Drivers\BuiltIn下BusEnum.dll加载,这是一个总线枚举驱动,依照ORDER值指示的加载顺序,它来完成后续的加载工作,也是使用ActiveDevice来加载.设备管理器加载smflash驱动的时候,调用DSK_Init函数,这个函数在falmain.cpp下面定义,下面是其中一部分
图2
下面来看GetFMDInterface函数是如何或去FMD提供的接口函数的
图3
到此FAL层已经获得FMD层提供的函数接口,结构体FMDInterface在public\common\oak\inc\fmd.h中定义,如下:
图4
3.2FMD层提供的函数接口
3.2.1PVOIDFMD_Init(LPCTSTRlpActiveReg,PPCI_REG_INFOpRegIn,PPCI_REG_INFOpRegOut)
FMD_Init是Flash设备的初始化函数。
在WinCE启动的时候,要加载Flash驱动时,首先调用这个函数对flash设备进行初始化。
如果你的系统中有nandflash的controller,那么你需要在这里对你的nandflashcontroller进行初始化。
如果没有的话,你需要针对你的硬件设计进行相关的片选,时序等进行配置。
返回一个handle表示成功,这个handle将被FMD_Deinit(..)函数用到,如果返回NULL表示失败。
下面来看看FMD_Init的函数体:
图5
nandflash控制器参数TACLS、TWRPH0和TWRPH1的确定,可以参考我另一篇博文:
图6
那么函数ReadFlashID是如何实现的呢,见下图:
图7
接下来继续看FMD_Init函数的后半部分:
图8
3.2.2BOOLFMD_Deinit(PVOIDhFMD)
这个函数在nandflash驱动卸载的时候被调用,参数就是FMD_Init函数返回的Handle.一般在这个函数里面,你可以释放一些用到的资源,然后关闭nandflashcontroller,但是这里的FMD_Denit函数只是简单返回TRUE,所以就不做介绍了。
3.2.3BOOLFMD_ReadSector(SECTOR_ADDRstartSectorAddr,LPBYTEpSectorBuff,PSectorInfopSectorInfoBuff,DWORDdwNumSectors)
这个函数用于读nandflash的一个扇区。
对于nandflash来说,分大page和小page,大page是2048个bytes一页,小page是512个bytes一页。
所以大page每个扇区有2048bytes,小page每个扇区有512bytes。
startSectorAddr:
nandflash物理扇区的起始地址,对于nandflash来说,就是nandflash中从哪个page开始。
pSectorBuff:
扇区数据buffer,从nandflash中读出的每一个扇区的数据都存放在这个buffer中。
pSectorInfoBuff:
扇区信息buffer,一般每个扇区的信息会被保存在nandflash的带外数据中,针对小page,带外数据有16bytes,大page有64bytes。
从nandflash的带外数据将该扇区的相关信息读出来,存放在这个buffer中。
dwNumSectors:
读取多少个扇区,对于nandflash来说相当于读取多少个page。
因为本驱动的nandflash是大页面的,FMD_ReadSector函数调用FMD_LB_ReadSector函数来实现,在看read操作的代码之前先看K9F1G08U0B读操作的时序要求:
图9
下面来看FMD_LB_ReadSector函数的实现:
图10
接着看此函数的实现部分:
图11
接下来就开始读取页数据了,先来看看K9F1G08U0B对随即读取页数据的时序图
图12
下面看看其实现的代码
图13
下图是S3C2443nandflash控制器中关于NFMECCD0和NFMECCD1寄存器的描述
图14
3.2.4BOOLFMD_WriteSector(SECTOR_ADDRstartSectorAddr,LPBYTEpSectorBuff,PSectorInfopSectorInfoBuff,DWORDdwNumSectors)
该函数用于写nandflash的一页。
参数和上面的FMD_ReadSector的参数意思一样,就不多说了。
FMD_WriteSector函数会调用FMD_LB_WriteSector函数来写数据,下面先来看K9F1G08U0B页编程的时序图:
图15
接下来来看这个函数的实现部分:
图16
接着看此函数体
图17
继续,结合我的博文
图18
继续
图19
下图是K9F1G08U0B中关于编程和读状态操作的时序图
图20
3.2.5BOOLFMD_EraseBlock(BLOCK_IDblockID)
该函数用于擦除nandflash中一个block,参数为要擦除nandflash的block地址,也就是第几个block。
这个函数的详细描述见我的另一篇博文:
3.2.6DWORDFMD_GetBlockStatus(BLOCK_IDblockID)
该函数获得nandflash中某一个block的状态。
参数为nandflash的block地址。
由于nandflash中可能有坏块,所以针对nandflash,这个函数首先会检查当前块是否是坏块,这个一般通过读取当前block的第0个page和第1个page的带外数据。
对于小pagenandflash一般是读取第5个byte,对于大pagenandflash一般读取第0个byte,如果不为0xff表示该块是坏块。
当然,至于具体该读哪个byte,最好还是看一下所用nandflash的datasheet,确认一下,不同的厂家可能有所不同。
如果发现该块是坏块,应该返回BLOCK_STATUS_BAD。
如果不是坏块,需要读取这个块的起始扇区的扇区信息。
如果读该扇区信息出错,应该返回BLOCK_STATUS_UNKNOWN,否则,判断独到的信息,返回相应结果。
3.2.7BOOLFMD_SetBlockStatus(BLOCK_IDblockID,DWORDdwStatus)
该函数设置nandflash某个block的状态,第一个参数是nandflash的block地址,第二个是要设置的状态。
在这个函数中,首先检查dwStatus是不是BLOCK_STATUS_BAD,如果是就对nandflash作坏块标记,如果不是,就将dwStatus写到该block的第0个page的扇区info中。
这个函数和上面的函数正好是相反的。
对于大页面的nandflash,FMD_SetBlockStatus函数调用FMD_LB_SetBlockStatus函数来实现,下面来看函数体
图21
下面就来看看LB_MarkBlockBad函数是如何把一块标识为坏块的。
图22
3.2.8BOOLFMD_GetInfo(PFlashInfopFlashInfo)
该函数用于返回flash的信息。
其中pFlashInfo是一个包含flash信息的结构。
在public\common\oak\inc\fmd.h下有定义:
typedefenum_FLASH_TYPE{NAND,NOR}FLASH_TYPE;
typedefstruct_FlashInfo
{
FLASH_TYPEflashType;
DWORDdwNumBlocks;
DWORDdwBytesPerBlock;
WORDwSectorsPerBlock;
WORDwDataBytesPerSector;
}FlashInfo,*PFlashInfo;
其中
flashType:
flash的类型,对于nandflash来说,应该是NAND。
dwNumBlocks:
flash中总共有多少个block,查一下所用的nandflash的datasheet就知道了,在此为1024.
dwBytesPerBlock:
每个block中包含多少个bytes,在此为2112bytes。
wSectorsPerBlock:
每个block中包含多少个扇区,也就是多少页,在此为64页。
wDataBytesPerSector:
一个扇区多少个bytes,对于大page是2048,对于小page是512。
下面是此函数体
图23
因为此函数和FMD_Init函数体内容差不多,可参考上面对FMD_Init函数的描述。
3.2.9VOIDFMD_PowerDown(VOID)和VOIDFMD_PowerUp(VOID)
这两个函数用于电源管理。
FMD_PowerDown()用于关闭flash设备电源,FMD_PowerUp()用于恢复flash设备电源。
根据你所用处理器和相关硬件环境,去实现这两个函数。
不实现也不会影响nandflash的使用。
FMD_PowerDown函数的函数体为空,所以就没有什么介绍的了,下面看FMD_PowerUp的函数体
图24
此函数和FMD_Init函数中初始化nandflash控制器的代码是一样的,可以共用,具体需要根据CPU的nandflash控制器和具体的nandflash来设置。
3.2.10BOOLFMD_OEMIoControl(DWORDdwIoControlCode,PBYTEpInBuf,DWORDnInBufSize,
PBYTEpOutBuf,DWORDnOutBufSize,PDWORDpBytesReturned)
就像很多的IOControl函数一样,根据不同的case,实现相应的功能。
针对nandflash来说,这里面的case不一定都需要实现。
事实上,如果什么都没有实现,也不影响nandflash的使用。
在WinCE的文档中,定义了一些需要实现的case,你可以实现,也可以不去实现,下面是其函数体
图25
FAL层的DSK_Init函数会通过调用FMD_OEMIoControl函数来获得FAL和FMD层的接口函数,这些接口函数是FMD层提供的,为什么说FMD_OEMIoControl函数可以不是对IOCTL_FMD_GET_INTERFACE这个case的支持呢?
因为DSK_Init函数在发现在调用FMD_OEMIoControl函数的时候如发现不支持IOCTL_FMD_GET_INTERFACE这个case,那么DSK_Init函数会自己用FMD层的接口函数来为其全局结构体变量FMD赋值,见图3。
参考的链接:
WindowsCE下的FMD接口实现文件与FAL.LIB的链接
WinCENANDflash–FAL
WinCE中nandflash驱动开发介绍
s3c2440对nandflash的操作
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- WINCE60 nandflash 驱动