日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于WINCE6.0的nandflash驱动(基于K9F1G08U0B)

發布時間:2025/4/16 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于WINCE6.0的nandflash驱动(基于K9F1G08U0B) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

*******************************LoongEmbedded********************************

作者:LoongEmbedded

時間:2010.11.26

類別:WINCE驅動開發

********************************LoongEmbedded********************************

?

?

1.?????? nandflash驅動架構概述

1

?

Windows CE下的FLASH驅動分為兩層,分別為FMD層和FAL(flash abstraction layer)FMDFlash Media Driver)屬于底層,直接操作Flash硬件,比如讀、寫和擦除等,不同的Flash硬件則FMD_XXX接口實現函數各不相同,上層則是FAL (Flash Abstraction Layer)層,該層是由微軟實現并提供的,是一個與硬件無關的層,可用于FAL層實現扇區的動態分配和壞塊管理等。FAL層向應用層(如API)提供DSK接口。例如CreateFile中調用的設備即是調用該FAL層提供的接口。FMD層暴露FMD_XXXFAL層調用。 PB中的闡述如下:

The flash media driver (FMD) is a device driver that performs the actual input and output of data to a flash memory device. An FMD contains all of the device-specific code necessary for read, write, and erase commands to the flash memory device. You can link the FMD with the flash abstraction layer (FAL) to create a block driver that a file system such as FAT can use. You can also link the FMD with a boot loader so that the boot loader can flash a run-time image.

?

2.FALFMD對應的實現代碼部分

首先我們知道是由FAL+FMDàsmflash.dll的,下面看看FALFMD分別對應哪些代碼:

?

2.1 FAL

FAL: /WINCE600/PRIVATE/WINCEOS/DRIVERS/MSFLASH,這個文件夾下的代碼編譯出fal.lib

也就是說FAL層是以fal.lib供鏈接的,fal.lib的導出文件內容如下:

LIBRARY???? MSFLASH

?

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.2 FMD

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.libsmflash_lib.lib這個兩個庫,而fal.lib就是FAL層提供的鏈接庫,smflash_lib.libFMD層提供的鏈接庫。

?

?

3. FAL層和FMD層的交互

?

3.1 FAL層獲取FMD層的函數接口

在系統啟動過程中,oal.exe 載了kernel.dll, kernel.dll加載device.dll, device.dll加載devmgr.dll, 這個就是負責加載, 卸載, 管理流驅動的. 備管理器找到HKLM/Drivers/BuiltInBusEnum.dll加載, 這是一個總線枚舉驅動, 依照ORDER值指示的加載順序,它來完成后續的加載工作, 也是使用ActiveDevice來加載.設備管理器加載smflash驅動的時候,調用DSK_Init函數,這個函數在falmain.cpp下面定義,下面是其中一部分

2

下面來看GetFMDInterface函數是如何或去FMD提供的接口函數的

3

到此FAL層已經獲得FMD層提供的函數接口,結構體FMDInterfacepublic/common/oak/inc/fmd.h中定義,如下:

4

?

3.2 FMD層提供的函數接口

?

3.2.1 PVOID FMD_Init(LPCTSTR lpActiveReg, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut)

?

FMD_InitFlash設備的初始化函數。在WinCE啟動的時候,要加載Flash驅動時,首先調用這個函數對flash設備進行初始化。如果你的系統中有nandflashcontroller,那么你需要在這里對你的nandflash controller進行初始化。如果沒有的話,你需要針對你的硬件設計進行相關的片選,時序等進行配置。返回一個handle表示成功,這個handle將被FMD_Deinit(..)函數用到,如果返回NULL表示失敗。下面來看看FMD_Init的函數體:

5

nand flash控制器參數TACLSTWRPH0TWRPH1的確定,可以參考我另一篇博文:

http://blog.csdn.net/LoongEmbedded/archive/2010/10/14/5939912.aspx,下面先來了解讀取K9F1G08U0BID,讀取K9F1G08U0B芯片ID操作首先需要寫入讀ID命令(0x90),然后再寫入0x00地址,就可以讀取到一共五個周期的芯片ID,第一個周期為廠商ID,第二個周期為設備ID,第三個周期至第五個周期包括了一些具體的該芯片信息,K9F1G08U0B關于讀取ID的操作如下圖:

?

6

那么函數ReadFlashID是如何實現的呢,見下圖:

7

接下來繼續看FMD_Init函數的后半部分:

8

?

3.2.2 BOOL FMD_Deinit(PVOID hFMD)

這個函數在nandflash驅動卸載的時候被調用,參數就是FMD_Init函數返回的Handle.一般在這個函數里面,你可以釋放一些用到的資源,然后關閉nandflash controller,但是這里的FMD_Denit函數只是簡單返回TRUE,所以就不做介紹了。

?

3.2.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

?

因為本驅動的nandflash是大頁面的,FMD_ReadSector函數 調用FMD_LB_ReadSector函數來實現,在看read操作的代碼之前先看K9F1G08U0B讀操作的時序要求:

9

下面來看FMD_LB_ReadSector函數的實現:

?

10

接著看此函數的實現部分:

11

接下來就開始讀取頁數據了,先來看看K9F1G08U0B對隨即讀取頁數據的時序圖

12

下面看看其實現的代碼

13

下圖是S3C2443 nandflash控制器中關于NFMECCD0NFMECCD1寄存器的描述

14

?

3.2.4 BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff,DWORD dwNumSectors)

?

該函數用于寫nandflash的一頁。參數和上面的FMD_ReadSector的參數意思一樣,就不多說了。FMD_WriteSector 函數會調用FMD_LB_WriteSector函數來寫數據,下面先來看K9F1G08U0B頁編程的時序圖:

15

接下來來看這個函數的實現部分:

16

接著看此函數體

17

繼續,結合我的博文http://blog.csdn.net/LoongEmbedded/archive/2010/11/17/6015302.aspx可以更好去理解

18

繼續

19

下圖是K9F1G08U0B中關于編程和讀狀態操作的時序圖

20

?

?

3.2.5 BOOL FMD_EraseBlock(BLOCK_ID blockID)

該函數用于擦除nandflash中一個block,參數為要擦除nandflashblock地址,也就是第幾個block。這個函數的詳細描述見我的另一篇博文:

http://blog.csdn.net/LoongEmbedded/archive/2010/11/17/6015302.aspx

?

3.2.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,否則,判斷獨到的信息,返回相應結果。

?

這個函數的詳細描述見我的另一篇博文:

http://blog.csdn.net/LoongEmbedded/archive/2010/11/17/6015302.aspx

?

3.2.7 BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)

該函數設置nandflash某個block的狀態,第一個參數是nandflashblock地址,第二個是要設置的狀態。在這個函數中,首先檢查dwStatus是不是BLOCK_STATUS_BAD,如果是就對nandflash作壞塊標記,如果不是,就將dwStatus寫到該block的第0page的扇區info中。這個函數和上面的函數正好是相反的。對于大頁面的nandflashFMD_SetBlockStatus函數調用FMD_LB_SetBlockStatus函數來實現,下面來看函數體

21

下面就來看看LB_MarkBlockBad函數是如何把一塊標識為壞塊的。

22

?

?

?

?

3.2.8 BOOL FMD_GetInfo(PFlashInfo pFlashInfo)

該函數用于返回flash的信息。其中pFlashInfo是一個包含flash信息的結構。在public/common/oak/inc/fmd.h下有定義:

typedef enum? _FLASH_TYPE { NAND, NOR } FLASH_TYPE;

?

typedef struct _FlashInfo

{

??? FLASH_TYPE? flashType;

??? DWORD?????? dwNumBlocks;

??? DWORD?????? dwBytesPerBlock;

??? WORD??????? wSectorsPerBlock;

??? WORD??????? wDataBytesPerSector;

?

}FlashInfo, *PFlashInfo;

其中

flashTypeflash的類型,對于nandflash來說,應該是NAND

dwNumBlocksflash中總共有多少個block,查一下所用的nandflashdatasheet就知道了,在此為1024.

dwBytesPerBlock:每個block中包含多少個bytes,在此為2112 bytes

wSectorsPerBlock:每個block中包含多少個扇區,也就是多少頁,在此為64頁。

wDataBytesPerSector:一個扇區多少個bytes,對于大page2048,對于小page512

?

下面是此函數體

23

因為此函數和FMD_Init函數體內容差不多,可參考上面對FMD_Init函數的描述。

?

?

3.2.9 VOID FMD_PowerDown(VOID)VOID FMD_PowerUp(VOID)

這兩個函數用于電源管理。FMD_PowerDown()用于關閉flash設備電源,FMD_PowerUp()用于恢復flash設備電源。根據你所用處理器和相關硬件環境,去實現這兩個函數。不實現也不會影響nandflash的使用。FMD_PowerDown函數的函數體為空,所以就沒有什么介紹的了,下面看FMD_PowerUp的函數體

24

此函數和FMD_Init函數中初始化nandflash控制器的代碼是一樣的,可以共用,具體需要根據CPUnandflash控制器和具體的nandflash來設置。

?

3.2.10 BOOL? FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize,

?????????????????????? PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)

?

就像很多的IOControl函數一樣,根據不同的case,實現相應的功能。針對nandflash來說,這里面的case不一定都需要實現。事實上,如果什么都沒有實現,也不影響nandflash的使用。在WinCE的文檔中,定義了一些需要實現的case,你可以實現,也可以不去實現,下面是其函數體

25

FAL層的DSK_Init 函數會通過調用FMD_OEMIoControl函數來獲得FALFMD層的接口函數,這些接口函數是FMD層提供的,為什么說FMD_OEMIoControl函數可以不是對IOCTL_FMD_GET_INTERFACE這個case的支持呢?因為DSK_Init函數在發現在調用FMD_OEMIoControl函數的時候如發現不支持IOCTL_FMD_GET_INTERFACE這個case,那么DSK_Init函數會自己用FMD層的接口函數來為其全局結構體變量FMD賦值,見圖3

?

參考的鏈接:

?

Windows CE下的FMD接口實現文件與FAL.LIB的鏈接

http://www.cnblogs.com/xilentz/archive/2010/05/31/1747839.html

?

WinCE NAND flash – FAL

http://blog.csdn.net/renpine/archive/2009/09/20/4572347.aspx

?

WinCEnandflash驅動開發介紹

http://blog.csdn.net/zhongnanjun_3/archive/2009/03/09/3973312.aspx

?

s3c2440nandflash的操作

http://www.360doc.com/content/10/1117/08/4128402_70026701.shtml

?

總結

以上是生活随笔為你收集整理的基于WINCE6.0的nandflash驱动(基于K9F1G08U0B)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。