?flash模擬eeprom存儲日志的原理
掃描二維碼
隨時隨地手機看文章
flash模擬eeprom存儲日志的原理
-
文章目的
-
采用flash模擬eeprom的優(yōu)點
-
方案設計
-
注意事項
文章目的
做mcu開發(fā)時,涉及到數(shù)據(jù)存儲時,往往都會考慮使用flash、eeprom,或者鐵電存儲器。從數(shù)據(jù)儲存的角度上來說,安全性最高的肯定是FRAM,接著才會考慮使用EEPROM,對于一般的數(shù)據(jù)儲存,flash就足夠了??紤]到一般的MCU都不會攜帶EEPROM,最簡單的方案可以利用flash模擬出eeprom,并且實現(xiàn)基本的日志文件系統(tǒng)操作,下面來描述一下基本的原理。
采用flash模擬eeprom的優(yōu)點
一般做mcu開發(fā)時,都會存儲數(shù)據(jù),如果有文件系統(tǒng),可以寫到文件中,但是一般不用文件系統(tǒng)時,則直接操作flash的讀寫。根據(jù)flash的操作特點,一方面是flash是只能從1變?yōu)?,不能從0寫到1。只有當擦除一個頁的時候,才能將該頁上的數(shù)據(jù)從0變?yōu)?。以一個頁為4K大小來計算,如果每次存幾十個字節(jié),并且多次重復操作,那么每次都需要擦除一個頁之后再寫數(shù)據(jù)。
假如用戶數(shù)據(jù)是一連串的狀態(tài)信息,每次都只會改變其中的一個狀態(tài),或者一個字節(jié),那么每次操作都會將flash上所有的用戶數(shù)據(jù)讀到內存中,然后將內存中的數(shù)據(jù)的變化的狀態(tài)位改變,然后再擦除page,接著再將內存中的數(shù)據(jù)寫到flash的page上。
由于flash的讀寫壽命有限,在10w次左右,并且擦除page消耗的時間很長。所以上述方案存在缺陷,那么如何才能讓flash像eeprom一樣讀寫,而且操作也不用每次擦除flash呢?
方案設計
為了非常容易的將flash當作eeprom來使用,需要確保兩個條件
1.讀寫的數(shù)據(jù)量至少小于1/2的flash的一個page數(shù)據(jù)量的大小
2.準備至少兩個pages
然后就可以開始設計數(shù)據(jù)的搬運了。
每個page的數(shù)據(jù)結構可以按照上圖所示進行設計。
首先每個pages的頭部都會有一個標志,用于描述當前的pages的狀態(tài),其狀態(tài)有未初始化、有效、無效。具體場景是,當未初始化時,由于flash的電氣特性,其flags為0xff,此時需要初始化該page,往其標志位寫有效即可。然后依次向下存放數(shù)據(jù),此時由于知道每次寫的數(shù)據(jù)量的大小,只需要確定其偏移量即可。
而這樣也會帶來一個問題,就是如何確保每次斷電后再上電也能知道當前寫數(shù)據(jù)的偏移?
要想解決這個問題,可以在每次上電的時候,遍歷該page0,通過讀取特定的用戶數(shù)據(jù)的標志位來確保得到當前數(shù)據(jù)的偏移量,然后就可以記錄在內存中,接著執(zhí)行了。
當數(shù)據(jù)在一個page0中存滿后,此時需要將數(shù)據(jù)轉移到page1了。這個過程比較可以好好分解一下:
因為是日志型的數(shù)據(jù)類型,一定會存在數(shù)據(jù)被刪除或者更新的情況,所以page0中會有兩個同為index=0的用戶數(shù)據(jù)。而且是最新的在后面。
一旦程序在pages上進行數(shù)據(jù)的寫操作時,檢查到剩余的pages空間不足則會將page0的狀態(tài)設置成無效,接著開始將page1的flags設置為有效狀態(tài),同時開始將pages0中的數(shù)據(jù)轉移到page1,注意在轉移的時候,需要檢查page0中的index,用最新的數(shù)據(jù)取代舊的數(shù)據(jù)。最后擦除page0即可。
依次按照上面的順序進行數(shù)據(jù)的搬運即可實現(xiàn)日志型數(shù)據(jù)操作的存儲。
注意事項
該方案的使用,在很多情況下都可以很好的操作,但是一旦用戶數(shù)據(jù)量很大,接近1/2的page數(shù)據(jù)量時,頻繁的擦寫flash的問題也會存在。
隨著page個數(shù)的增加,也可以減少擦除的次數(shù),帶來的問題是程序設計的更加復雜。
實際使用的過程中每個pages的flag標志不一定只有有效和無效的狀態(tài),比如在轉移過程中,突然斷電了,為了保證數(shù)據(jù)的不丟失,一定要考慮到每個page異常情況下的狀態(tài),并能夠恢復數(shù)據(jù)。達到掉電安全狀態(tài)。
有了這些后臺管理機制,再寫日志時,上層便可以直接使用讀寫函數(shù)進行操作,而不用管底層到底是flash還是eeprom。