WinCE中nandflash驅(qū)動開發(fā)介紹 收藏
先來談一下flash,flash是一種非易失存儲器,,一般flash存儲設(shè)備分為Nandflash和Norflash,。這兩種flash各有優(yōu)缺點。在讀寫速度上,,norflash的讀速度快一些,,nandflash的寫速度會快一些。Nandflash的容量一般都比Norflash大很多,,而且相比價格比較便宜,。但是Norflash支持XIP,而nandflash不支持,,而且Nandflash可能有壞塊,。相關(guān)的比較,網(wǎng)上很多文章都有介紹,,這里就說這么多了,。 這里介紹nandflash驅(qū)動,在WinCE中,,有專門針對flash存儲設(shè)備驅(qū)動的支持,,一般傳統(tǒng)采用FAL+FMD的架構(gòu)。在WinCE最新的版本中,,也就是Windows CE6.0 R2中,,還支持MDD+PDD的架構(gòu)。在FAL+FMD架構(gòu)中,,F(xiàn)AL層由微軟來實現(xiàn),,我們需要實現(xiàn)FMD層的相關(guān)接口函數(shù)。在MDD+PDD的架構(gòu)中,,MDD替換了原來架構(gòu)中的FAL,,而PDD相當(dāng)于原來的FMD,,只要實現(xiàn)PDD層就可以了。如果你的系統(tǒng)已經(jīng)升級到WinCE6.0 R2,,那么你應(yīng)該可以在\WINCE600\Public\COMMON\OAK\DRIVERS目錄下面找到這兩種架構(gòu)驅(qū)動的源代碼,。 由于MDD+PDD的架構(gòu)在WinCE6.0 R2中才有支持,本人也沒有實現(xiàn)過,。所以這里只介紹基于FAL+FMD架構(gòu)下,,nandflash驅(qū)動的開發(fā),這也是目前大家都采用的開發(fā)flash驅(qū)動的架構(gòu),。
如上面所說,,我們需要實現(xiàn)FMD層的相關(guān)接口,下面來介紹一下各個接口函數(shù):
1. PVOID FMD_Init(LPCTSTR lpActiveReg, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut): 這個是Flash設(shè)備的初始化函數(shù),。在WinCE啟動的時候,,要加載Flash驅(qū)動時,首先調(diào)用這個函數(shù)對flash設(shè)備進(jìn)行初始化,。如果你的系統(tǒng)中有nandflash的controller,,那么你需要在這里對你的nandflash controller進(jìn)行初始化。如果沒有的話,,你需要針對你的硬件設(shè)計進(jìn)行相關(guān)的片選,,時序等進(jìn)行配置。返回一個handle表示成功,,這個handle將被FMD_Deinit(..)函數(shù)用到,,如果返回NULL表示失敗。 2. BOOL FMD_Deinit(PVOID hFMD): 這個函數(shù)在nandflash驅(qū)動卸載的時候被調(diào)用,,參數(shù)就是FMD_Init函數(shù)返回的Handle.一般在這個函數(shù)里面,,你可以釋放一些用到的資源,然后關(guān)閉nandflash controller,。 3. BOOL FMD_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors): 這個函數(shù)用于讀nandflash的一個扇區(qū),。對于nandflash來說,分大page和小page,,大page是2048個bytes一頁,,小page是512個bytes一頁。所以大page每個扇區(qū)有2048 bytes,,小page每個扇區(qū)有512 bytes,。 startSectorAddr: nandflash物理扇區(qū)的起始地址,,對于nandflash來說,,就是nandflash中從哪個page開始。 pSectorBuff:扇區(qū)數(shù)據(jù)buffer,,從nandflash中讀出的每一個扇區(qū)的數(shù)據(jù)都存放在這個buffer中,。 pSectorInfoBuff:扇區(qū)信息buffer,一般每個扇區(qū)的信息會被保存在nandflash的帶外數(shù)據(jù)中,針對小page,,帶外數(shù)據(jù)有16 bytes,,大page有64 bytes。從nandflash的帶外數(shù)據(jù)將該扇區(qū)的相關(guān)信息讀出來,,存放在這個buffer中,。 dwNumSectors:讀取多少個扇區(qū),對于nandflash來說相當(dāng)于讀取多少個page,。 4. BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors): 該函數(shù)用于寫nandflash的一個扇區(qū),。參數(shù)和上面的FMD_ReadSector的參數(shù)意思一樣,就不多說了,。 5. BOOL FMD_EraseBlock(BLOCK_ID blockID): 該函數(shù)用于擦出nandflash的一個block,,參數(shù)為要擦除nandflash的block地址,也就是第幾個block,。 6. DWORD FMD_GetBlockStatus(BLOCK_ID blockID): 該函數(shù)獲得nandflash中某一個block的狀態(tài),。參數(shù)為nandflash的block地址。由于nandflash中可能有壞塊,,所以針對nandflash,,這個函數(shù)首先會檢查當(dāng)前塊是否是壞塊,這個一般通過讀取當(dāng)前block的第0個page和第1個page的帶外數(shù)據(jù),。對于小page nandflash一般是讀取第5個byte,,對于大page nandflash一般讀取第0個byte,如果不為0xff表示該塊是壞塊,。當(dāng)然,,至于具體該讀哪個byte,最好還是看一下所用nandflash的datasheet,,確認(rèn)一下,,不同的廠家可能有所不同。如果發(fā)現(xiàn)該塊是壞塊,,應(yīng)該返回BLOCK_STATUS_BAD,。如果不是壞塊,需要讀取這個塊的起始扇區(qū)的扇區(qū)信息,。如果讀該扇區(qū)信息出錯,,應(yīng)該返回BLOCK_STATUS_UNKNOWN,否則,,判斷獨(dú)到的信息,,返回相應(yīng)結(jié)果。 7. BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus): 該函數(shù)設(shè)置nandflash某個block的狀態(tài),,第一個參數(shù)是nandflash的block地址,,第二個是要設(shè)置的狀態(tài),。在這個函數(shù)中,首先檢查dwStatus是不是BLOCK_STATUS_BAD,,如果是就對nandflash作壞塊標(biāo)記,,然后返回FALSE。如果不是,,就將dwStatus寫到該block的第0個page的扇區(qū)info中,。這個函數(shù)和上面的函數(shù)正好是相反的。 8. BOOL FMD_GetInfo(PFlashInfo pFlashInfo): 該函數(shù)用于返回flash的信息,。其中pFlashInfo是一個包含flash信息的結(jié)構(gòu),。 pFlashInfo->flashType:flash的類型,對于nandflash來說,,應(yīng)該是NAND,。 pFlashInfo->wDataBytesPerSector:一個扇區(qū)多少個bytes,對于大page是2048,,對于小page是512,。 pFlashInfo->dwNumBlocks:flash中總共有多少個block,查一下所用的nandflash的datasheet就知道了,。 pFlashInfo->wSectorsPerBlock:每個block中包含多少個扇區(qū),。 pFlashInfo->dwBytesPerBlock:每個block中包含多少個bytes。 9. VOID FMD_PowerDown()和VOID FMD_PowerUp(): 這兩個函數(shù)用于電源管理,。FMD_PowerDown()用于關(guān)閉flash設(shè)備電源,,F(xiàn)MD_PowerUp()用于恢復(fù)flash設(shè)備電源。根據(jù)你所用處理器和相關(guān)硬件環(huán)境,,去實現(xiàn)這兩個函數(shù),。不實現(xiàn)也不會影響nandflash的使用。 10. BOOL FMD_OEMIoControl(..): 就像很多的IOControl函數(shù)一樣,,根據(jù)不同的case,,實現(xiàn)相應(yīng)的功能。針對nandflash來說,,這里面的case不一定都需要實現(xiàn),。事實上,如果什么都沒有實現(xiàn),,也不影響nandflash的使用,。在WinCE的文檔中,定義了一些需要實現(xiàn)的case,,你可以實現(xiàn),,也可以不去實現(xiàn)。 對于nandflash來說,,實現(xiàn)上述函數(shù)就可以了,。在nandflash出廠的時候,,廠家已經(jīng)對nandflash中的壞塊進(jìn)行了標(biāo)記,。所以第一次對nandflash操作的時候,,不要隨便擦除nandflash,因為這樣可能會把壞塊標(biāo)記擦掉,,這樣你就判斷不出哪個塊是壞塊了,。 關(guān)于ECC校驗,目前很多處理帶有nandflash controller,,而且nandflash controller帶有硬件ECC功能,。如果沒有硬件ECC,也可以使用軟件ECC,,軟ECC的代碼可以在\WINCE600\PUBLIC\COMMON\OAK\DRIVERS\BLOCK\MSFLASHFMD\ECC下找到,。一般來說,ECC校驗會對512個BYTE產(chǎn)生3個字節(jié)的校驗碼,,也就是說對小PAGE來說,,每個PAGE有3個字節(jié)的ecc校驗碼;對于大PAGE來說,,有12個字節(jié),。這些校驗碼應(yīng)該在寫扇區(qū)數(shù)據(jù)的時候,被寫在扇區(qū)的帶外數(shù)據(jù)里面,。當(dāng)讀扇區(qū)數(shù)據(jù)時,,會先把數(shù)據(jù)讀出來,然后根據(jù)這些數(shù)據(jù)計算ecc,,再和讀出來的ecc進(jìn)行比較,,如果一致,則表示正確,。 本文來自CSDN博客,,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/zhongnanjun_3/archive/2009/03/09/3973312.aspx
|
|