因爲磁盤屬於低速設備,磁盤的讀寫速度遠遠低於CPU,因此爲了解決這種速度不匹配的問題,SylixOS提供了對應塊設備的緩衝器。與此對應的,爲了提升NandFlash的讀速度,SylixOS也爲NandFlash提供了一種讀CACHE機制。爲了避免影響寫平衡軟件對壞塊的管理,該緩衝機制在NandFlash寫一個扇區時,將相關的扇區CACHE所有設爲讀不命中;當NandFlash擦除一個塊時,將塊內全部的扇區CACHE設爲讀不命中。緩存
SylixOS中關於NandFlash讀CACHE的內容主要在"libsylixos/SylixOS/fs/nandRCache"目錄下,主要實現了讀CACHE的建立、刪除操做,以及節點的申請、釋放操做。其中,讀CACHE的建立函數接口如程序清單 2-1所示。函數
程序清單 2-1讀CACHE建立函數spa
#include <SylixOS.h> LW_API ULONG API_NandRCacheCreate(PVOID pvNandRCacheMem, size_t stMemSize, ULONG ulPageSize, ULONG ulSpareSize, ULONG ulPagePerBlock, PLW_NRCACHE_CB *ppnrcache);
函數API_NandRCacheCreate原型分析:索引
此函數成功返回ERROR_NONE,失敗返回錯誤碼;接口
參數pvNandRCacheMem是緩存內存地址;內存
參數stMemSize是緩存內存大小;原型
參數ulPageSize是每一個頁面數據區大小;flash
參數ulSpareSize是每一個頁面擴展區大小;hash
參數ulPagePerBlock是每一塊頁面的個數;ast
參數ppnrcache是須要返回的建立成功的控制塊。
使用API_NandRCacheCreate函數建立CACHE成功時,最後一個入參將返回NandFlash的讀CACHE控制塊,該控制塊的詳細信息如程序清單 2-2所示。
程序清單 2-2讀CACHE管理控制塊
typedef struct { PLW_NRCACHE_NODE NRCACHE_pnrcachenBuffer; /* nand flash 全部的緩衝 */ ULONG NRCACHE_ulPagePerBlock; /* 每個塊的頁面個數 */ ULONG NRCACHE_ulnCacheNode; /* CACHE 中包含的節點個數 */ INT NRCACHE_iHashSize; /* hash 表大小 */ PLW_LIST_LINE *NRCACHE_pplineHash; /* 搜索 hash 表 */ PLW_LIST_RING NRCACHE_pringLRU; /* 有效點中最近最少使用表 */ PLW_LIST_LINE NRCACHE_plineFree; /* 空閒表頭 */ } LW_NRCACHE_CB; typedef LW_NRCACHE_CB *PLW_NRCACHE_CB; /* nand read cache 控制塊 */
NandFlash的讀CACHE建立過程主要包括開闢Hash表內存、開闢初始化控制塊內存以及初始化每一個節點內存使用狀況。和塊設備的DiskCACHE相似,NandFlash讀CACHE以NODE節點管理CACHE緩存,每個NODE節點都對應着一頁緩存,NODE節點則以LRU(Least Recently Used)的方式組成循環鏈表,方便刷新髒節點。對於已經緩存的扇區,則經過HASH表與鏈表結合的方式進行快速索引。空閒的節點單獨構成一個鏈表,方便節點的快速申請。
管理CACHE緩存的NODE節點詳細信息如程序清單 2-3所示。
程序清單 2-3 NODE節點控制塊
typedef struct { LW_LIST_LINE NRCACHEN_lineManage; /* 空閒鏈表 或 hash */ LW_LIST_RING NRCACHEN_ringLRU; /* LRU 鏈 */ ULONG NRCACHEN_ulChunkNo; /* 扇區號 */ caddr_t NRCACHEN_pcChunk; /* 數據區緩衝 */ caddr_t NRCACHEN_pcSpare; /* 擴展區緩衝 */ } LW_NRCACHE_NODE; typedef LW_NRCACHE_NODE *PLW_NRCACHE_NODE; /* 緩衝節點 */
對於NODE節點的操做主要包括申請、查找、釋放等操做,其中節點申請函數接口如程序清單 2-4所示。
程序清單 2-4 CACHE節點申請函數
#include <SylixOS.h> LW_API PLW_NRCACHE_NODE API_NandRCacheNodeAlloc(PLW_NRCACHE_CB pnrcache, ULONG ulChunkNo);
函數API_NandRCacheCreate原型分析:
此函數成功返回NODE節點,失敗返回LW_NULL;
參數pnrcache是CACHE控制塊;
參數ulChunkNo是須要緩存的扇區號。
函數API_NandRCacheCreate從空閒NODE池中獲取節點時,若不存在空閒節點,則將從LRU表中淘汰一個最久未使用的節點。
得到指定扇區節點的函數接口如程序清單 2-5所示。
程序清單 2-5 CACHE節點查找函數
#include <SylixOS.h> LW_API PLW_NRCACHE_NODE API_NandRCacheNodeGet(PLW_NRCACHE_CB pnrcache, ULONG ulChunkNo);
函數API_NandRCacheNodeGet原型分析:
此函數成功返回節點控制塊,失敗返回LW_NULL;
參數pnrcache是CACHE控制塊;
參數ulChunkNo是須要緩存的扇區號。
當API_NandRCacheNodeGet函數在CACHE中命中時,會將此節點掛入LRU表的頭部,這樣最近使用的數據始終保持在鏈表頭部。
將一個有效節點釋放的函數接口如程序清單 2-6所示。
程序清單 2-6 CACHE節點釋放函數
#include <SylixOS.h> LW_API VOID API_NandRCacheNodeFree(PLW_NRCACHE_CB pnrcache, ULONG ulChunkNo);
函數API_NandRCacheNodeFree原型分析:
此函數成功返回;
參數pnrcache是CACHE控制塊;
參數ulChunkNo是須要緩存的扇區號;
NandFlash的讀CACHE刪除操做的函數接口如程序清單 2-7所示。
程序清單 2-7讀CACHE刪除函數
#include <SylixOS.h> LW_API ULONG API_NandRCacheDelete(PLW_NRCACHE_CB pnrcache);
函數API_NandRCacheDelete原型分析:
此函數成功ERROR_NONE,失敗返回PX_ERROR;
參數pnrcache是CACHE控制塊。
無