【ARM-WINCE 】 WinCE中nandflash驅動開發介紹
先來談一下flash,flash是一種非易失儲存器,一般flash儲存裝置分為Nandflash和Norflash。這兩種flash各有優缺點。在讀寫速度上,norflash的讀速度快一些,nandflash的寫速度會快一些。Nandflash的容量一般都比Norflash大很多,而且相比價格比較便宜。但是Norflash支援XIP,而nandflash不支援,而且Nandflash可能有壞塊。相關的比較,網上很多文章都有介紹,這裡就說這麼多了。
這裡介紹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裝置進行初始化。如果你的系統中有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的一個扇區。對於nandflash來說,分大page和小page,大page是2048個bytes一頁,小page是512個bytes一頁。所以大page每個扇區有2048 bytes,小page每個扇區有512 bytes。
startSectorAddr: nandflash物理扇區的起始地址,對於nandflash來說,就是nandflash中從哪個page開始。
pSectorBuff:扇區資料buffer,從nandflash中讀出的每一個扇區的資料都存放在這個buffer中。
pSectorInfoBuff:扇區資訊buffer,一般每個扇區的資訊會被儲存在nandflash的帶外資料中,針對小page,帶外資料有16 bytes,大page有64 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,引數為要擦除nandflash的block地址,也就是第幾個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的使用。在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校驗會對512個BYTE產生3個位元組的校驗碼,也就是說對小PAGE來說,每個PAGE有3個位元組的ecc校驗碼;對於大PAGE來說,有12個位元組。這些校驗碼應該在寫扇區資料的時候,被寫在扇區的帶外資料裡面。當讀扇區資料時,會先把資料讀出來,然後根據這些資料計算ecc,再和讀出來的ecc進行比較,如果一致,則表示正確。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-374493/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 如何編寫linux下nandflash驅動-4LinuxNaN
- Linux驅動開發筆記(四):裝置驅動介紹、熟悉雜項裝置驅動和ubuntu開發雜項裝置DemoLinux筆記Ubuntu
- Linux USB ECM Gadget 驅動介紹Linux
- 【動手開發作業系統】- 介紹作業系統
- docker overlay儲存驅動介紹(傳送門)Docker
- 敏捷開發:Scrum 中的 Product Backlog 介紹敏捷Scrum
- 驅動開發:配置Visual Studio驅動開發環境開發環境
- 一種基於事件驅動思想的 SAP 系統整合二次開發方法介紹事件
- 移動前端開發和Web前端開發的不同點介紹前端Web
- EntityFramework之領域驅動設計實踐介紹Framework
- 簡單介紹python中的mock介面開發PythonMock
- 電腦印表機驅動在哪個位置?window電腦印表機驅動位置介紹
- 中移鏈合約常用開發介紹 (一)開發基本流程
- 驅動開發:探索DRIVER_OBJECT驅動物件Object物件
- 領域驅動設計及其優點介紹 - DEV社群dev
- LED數顯驅動晶片VK1650資料介紹晶片
- 社群驅動增長 | Dev.Together 分論壇介紹dev
- iOS開發- reloadData方法介紹iOS
- 陀螺世界商城開發(介紹)
- ModStartCMS模組開發介紹
- 驅動開發入門
- Web專案開發介紹及實戰專案介紹Web
- 鏈動2+1系統開發詳細介紹
- 跳脫字元在前端開發中的詳細介紹字元前端
- Android開發 - 掌握ConstraintLayout(二)介紹AndroidAI
- Kotlin on Android 開發環境介紹KotlinAndroid開發環境
- Web開發小工具介紹Web
- Apple開發者賬號介紹APP
- SOLIDWORKS二次開發介紹Solid
- 【Spring註解驅動開發】聊聊Spring註解驅動開發那些事兒!Spring
- 鏈動2+1模式開發費用詳情介紹模式
- window驅動開發總結
- 驅動開發書籍大全
- 驅動程式開發步驟
- VS Code外掛開發介紹(二)
- iOS混合開發庫(GICXMLLayout)一、介紹iOSXML
- 介紹一個軟體開發工具
- Flutter混合開發二-FlutterBoost使用介紹Flutter
- Harmony 應用開發常用元件介紹元件