1. 程式人生 > >nor flash之擦除和寫入

nor flash之擦除和寫入

最近研究了下nor flash的掉電問題,對nor的掉電有了更多的認識。總結分享如下

擦除從0變1,寫入從1變0

nor flash的物理特性是,寫入之前需要先進行擦除。擦除後資料為全0xFF,此時寫入操作,實際上是將資料從1改成0。
一般先擦後寫,但實際上擦除後每個位置是可以寫入多次的,只要每次寫入都是讓某些bit從1變0即可。
例如在擦除後資料為0xFF,此時寫入0x0F,可讀出0x0F,再寫入0x01,可讀出0x01,再寫入0x00,可讀出0x00。
而對於0x00,就無法再改寫成任何值了,因為此時每個bit都是0,想要改寫就必須先擦除,讓其恢復到0xFF,再進行寫入改成目標值。

多次寫入的例子

在uboot中就有一個利用nor這個特性的例子。當使用了冗餘env功能時,flash上會維護兩份env,我們記為envA和envB吧。

既然有兩份env,那就需要一種方式來區分哪份env的資料更新。對此uboot支援幾種策略,其中一種可適用於nor的策略FLAG_BOOLEAN,uboot會在env的頭部結構中,使用了一個位元組flags來表示其是否有效。
假設當前A有效,B無效,則A的flags為0x1,B的flags為0x0. 讀取時可以據此判斷哪份env為新的。
寫入時,uboot會先在ram的buffer中構造好flags為1的新env資料,再對envB進行擦除和寫入。寫入後flash上兩份env的flags就都是0x1了。接著uboot直接對A的flags的位置寫入0x0,即將原本的0x1不經擦除,直接改寫為0,這樣就快速地達到將A標記為無效的目的了。

寫入過程掉電

對於nor來說,一次寫入可以連續寫256 bytes,那如果在中途發生了掉電,再次上電後讀出來的資料會是什麼樣的呢?
這個問題我們很容易得到兩種猜測:
假設nor中存在一片buffer,集齊256 bytes後再一次性刷到顆粒中,那麼中途掉電大概率就是完全沒有寫入,因為資料還在buffer中。也有小概率是正在刷buffer到顆粒中掉電了,那麼這個時候寫入的資料應該是亂序的。
假設nor中沒有維護buffer,每個bytes的波形接收到之後就寫入固化下來,那麼中途掉電大概率就是部分寫入,而且是順序的,即前面的資料寫入了,後面的資料仍然為0xFF。

實測實際情況為假設二所述。
當寫入一筆資料時,nor就是按順序寫入的,掉電後的資料特徵為前面部分資料是正確資料,後面部分資料是0xFF。前後的交界點並未對齊到256 bytes。

擦除過程中掉電

從nor flash原廠瞭解到,erase操作其實在flash內部分成三個步驟:
1)pre-program all "00";
2)erase;
3)post-program all "FF"

那麼在擦除過程中掉電,可能出現的資料特徵就比較多了。

第一步驟:pre-program all "00";
當收到擦除命令時,首先flash會對這4k寫入全0資料,這個是按先後順序序列寫入的,就理解為一個正常的寫入全0資料。
如果在這個過程中掉電,那麼觀察到的資料會是,前半部分的資料為0x00,後半部分的資料為原始的資料。情況跟上面描述的寫入過程掉電一樣。

第二步驟:erase
全部寫入0之後,就進行擦除,擦除是會將所有的0都變成0xFF,這個是4k的資料並行進行的,在這個過程中掉電,可以看到所有的資料都介於0-0xFF之間,亂七八糟的資料,沒有任何規律。

第三步驟:post-program all "FF"
這一步其實我沒太理解,但從掉電後的資料特徵看,有一種狀態可能跟這一步沒完成有關。
即4k的資料,處於不穩定的0xFF狀態。不穩定的意思是,某次上電讀出來為全0xFF,重新上電再讀,可能就是夾雜著一些0xFD, 0xBF之類的資料。

總結

以上我們觀察了寫入和擦除中途掉電的資料特徵。
從寫入過程掉電的特徵看,寫入過程掉電可能導致nor僅將部分資料寫入的,導致頭部資料存在但整體資料是不完整的,因此不能簡單依賴頭部結構的MAGIC值來判定資料是否有效,重要資料需要做完整性校驗。
從擦除過程掉電的特徵看,擦除過程掉電可能導致flash上存在雜亂資料,或者不穩定的全0xFF資料,因此對於全0xFF的資料,寫入之前還是要先做一次擦除讓nor達到穩定狀態。

本文連結:https://www.cnblogs.com/zqb-all/p/12207924.h