Flash硬件原理


1.2.1. 什么是Flash

Flash全名叫做Flash Memory,從名字就能看出,是種數據存儲設備,存儲設備有很多類,Flash屬於非易失性存儲設備(Non-volatile Memory Device),與此相對應的是易失性存儲設備(Volatile Memory Device)。關於什么是非易失性/易失性,從名字中就可以看出,非易失性就是不容易丟失,數據存儲在這類設備中,即使斷電了,也不會丟失,這類設備,除了Flash,還有其他比較常見的入硬盤,ROM等,與此相對的,易失性就是斷電了,數據就丟失了,比如大家常用的內存,不論是以前的SDRAM,DDR SDRAM,還是現在的DDR2,DDR3等,都是斷電后,數據就沒了。

1.2.1.1. Flash的硬件實現機制

Flash的內部存儲是MOSFET,里面有個懸浮門(Floating Gate),是真正存儲數據的單元。

在Flash之前,紫外線可擦除(uv-erasable)的EPROM,就已經采用了Floating Gate存儲數據這一技術了。

圖 1.1. 典型的Flash內存單元的物理結構

數據在Flash內存單元中是以電荷(electrical charge) 形式存儲的。存儲電荷的多少,取決於圖中的外部門(external gate)所被施加的電壓,其控制了是向存儲單元中沖入電荷還是使其釋放電荷。而數據的表示,以所存儲的電荷的電壓是否超過一個特定的閾值Vth來表示,因此,Flash的存儲單元的默認值,不是0(其他常見的存儲設備,比如硬盤燈,默認值為0),而是1,而如果將電荷釋放掉,電壓降低到一定程度,表述數字0。

 

1.2.2. 什么是Nand Flash

Flash主要分兩種,Nand Flash和nor flash。

關於Nand Flash和Nor Flash的區別,參見[6]

不過,關於兩者區別,除了那個解釋之外,這里再多解釋解釋:

  1. Nor的成本相對高,容量相對小,比如常見的只有128KB,256KB,1MB,2MB等等,優點是讀寫數據時候,不容易出錯。所以在應用領域方面,Nor Flash比較適合應用於存儲少量的代碼。

  2. Nand flash成本相對低,說白了就是便宜,缺點是使用中數據讀寫容易出錯,所以一般都需要有對應的軟件或者硬件的數據校驗算法,統稱為ECC。但優點是,相對來說容量比較大,現在常見的Nand Flash都是1GB,2GB,更大的8GB的都有了,相對來說,價格便宜,因此適合用來存儲大量的數據。其在嵌入式系統中的作用,相當於PC上的硬盤,用於存儲大量數據。

所以,一個常見的應用組合就是,用小容量的Nor Flash存儲啟動代碼,比如uboot,用大容量的Nand Flash做整個系統和用戶數據的存儲。

而一般的嵌入式平台的啟動流程也就是,系統從裝有啟動代碼的Nor Flash啟動后,初始化對應的硬件,包括SDRAM等,然后將Nand Flash上的Linux 內核讀取到內存中,做好該做的事情后,就跳轉到SDRAM中去執行內核了,然后內核解壓(如果是壓縮內核的話,否則就直接運行了)后,開始運行,在Linux內核啟動最后,去Nand Flash上,掛載根文件,比如jffs2,yaffs2等,掛載完成,運行初始化腳本,啟動consle交互,才允許你通過console和內核交互。至此完成整個系統啟動過程。

而Nor Flash就分別存放的是Uboot,Nand Flash存放的是Linux的內核鏡像和根文件系統,以及余下的空間分成一個數據區。

1.2.2.1. Nand Flash的詳細分類

Nand Flash,按照硬件類型,可以分為

  1. Bare NAND chips

    裸片。單獨的Nand Flash芯片。

  2. SmartMediaCards

    裸片+一層薄塑料。常用於數碼相機和MP3播放器中。之所以稱smart,是由於其軟件smart,而不是硬件本身有啥smart之處。

  3. DiskOnChip

    裸片+glue logic。glue logic=硬件ECC產生器+用於靜態的nand 芯片控制的寄存器+直接訪問一小片地址窗口,那塊地址中包含了引導代碼的stub樁,其可以從Nand Flash中拷貝真正的引導代碼。

 

1.2.3. SLC和MLC的實現機制

Nand Flash按照內部存儲數據單元的電壓的不同層次,也就是單個內存單元中,是存儲1位數據,還是多位數據,可以分為SLC和MLC。

1.2.3.1. SLC(Single Level Cell)

單個存儲單元,只存儲一位數據,表示1或0。

就是上面介紹的,對於數據的表示,單個存儲單元中內部所存儲電荷的電壓,和某個特定的閾值電壓Vth,相比,如果大於此Vth值,就是表示1,反之,小於Vth,就表示0。

對於Nand Flash的數據的寫入1,就是控制External Gate去充電,使得存儲的電荷夠多,超過閾值Vth,就表示1了。而對於寫入0,就是將其放電,電荷減少到小於Vth,就表示0了。

關於為何Nand Flash不能從0變成1,我的理解是,物理上來說,是可以實現每一位的,從0變成1的,但是實際上,對於實際的物理實現,出於效率的考慮,如果對於,每一個存儲單元都能單獨控制,即,0變成1就是,對每一個存儲單元單獨去充電,所需要的硬件實現就很復雜和昂貴,同時,所進行對塊擦除的操作,也就無法實現之前所說的的,Flash的速度,即一閃而過的速度了,也就失去了Flash的眾多特性了。

1.2.3.2. MLC(Multi Level Cell)

與SLC相對應的,就是單個存儲單元,可以存儲多個位,比如2位,4位等。其實現機制,說起來比較簡單,就是通過控制內部電荷的多少,分成多個閾值,通過控制里面的電荷多少,而達到我們所需要的存儲成不同的數據。比如,假設輸入電壓是Vin=4V(實際沒有這樣的電壓,此處只是為了舉例方便),那么,可以設計出2的2次方=4個閾值, 1/4 的Vin=1V,2/4的Vin=2V,3/4的Vin=3V,Vin=4V,分別表示2位數據00,01,10,11,對於寫入數據,就是充電,通過控制內部的電荷的多少,對應表示不同的數據。

對於讀取,則是通過對應的內部的電流(與Vth成反比),然后通過一系列解碼電路完成讀取,解析出所存儲的數據。這些具體的物理實現,都是有足夠精確的設備和技術,才能實現精確的數據寫入和讀出的。

單個存儲單元可以存儲2位數據的,稱作2的2次方=4 Level Cell,而不是2 Level Cell,關於這點,之前看Nand flash的數據手冊(datasheet)的時候,差點搞暈了。

同理,對於新出的單個存儲單元可以存儲4位數據的,稱作 2的4次方=16 Level Cell。

1.2.3.3. 關於如何識別SLC還是MLC

Nand Flash設計中,有個命令叫做Read ID,讀取ID,意思是讀取芯片的ID,就像大家的身份證一樣,這里讀取的ID中,是讀取好幾個字節,一般最少是4個,新的芯片,支持5個甚至更多,從這些字節中,可以解析出很多相關的信息,比如此Nand Flash內部是幾個芯片(chip)所組成的,每個chip包含了幾片(Plane),每一片中的頁大小,塊大小,等等。在這些信息中,其中有一個,就是識別此flash是SLC還是MLC。下面這個就是最常見的Nand Flash的datasheet中所規定的,第3個字節,3rd byte,所表示的信息,其中就有SLC/MLC的識別信息:

表 1.1. Nand Flash第3個ID的含義

1.2.4. Nand Flash數據存儲單元的整體架構

簡單說就是,常見的Nand Flash,內部只有一個chip,每個chip只有一個plane。

而有些復雜的,容量更大的Nand Flash,內部有多個chip,每個chip有多個plane。這類的Nand Flash,往往也有更加高級的功能,比如下面要介紹的Multi Plane Program和Interleave Page Program等。

概念上,由大到小來說,就是:

Nand Flash ⇒ Chip ⇒ Plane ⇒ Block ⇒ Page ⇒ oob

用圖表來表示,更加易懂:

圖 1.2. Nand Flash的結構圖

 

 

比如,型號為K9K8G08U0A這塊Nand Flash(有時候也被稱為此塊chip芯片),其內部有兩個K9F4G08U0A的chip,chip#1和chip#2,每個K9F4G08U0A的chip包含了2個Plane,每個Plane是2Gbbit,所以K9F4G08U0A的大小是2Gb×2 = 4Gb = 512MB,因此,K9K8G08U0A內部有2個K9F4G08U0A,或者說4個Plane,總大小是×256MB=1GB。

用公式表示如下:

公式 1.1. K9K8G08U0A的物理結構所組成的總容量

K9K8G08U0A(這塊Nand Flash)

= 2 × K9F4G08U0A(K9F4G08U0A是chip,1 K9F4G08U0A = 2 Plane)

= 2 × 2個Plane

= 4 Plane(1 Plane = 2048 Block)

= 4 × 2048個Block(1 Block = 64 Page)

= 4 × 2048 × 64Page(1 Page = 2KB)

= 4 × 2048 × 64Page × 2KB

= 4 × 2048 × 128KB(1 Block = 128KB)

= 4 × 256MB(1 Plane = 2Gb = 256MB)

= 2 × 512MB(1 K9F4G08U0A = 4Gb = 512MB)

= 1GB(1 K9K8G08U0A = 1GB)

 

而型號是K9WAG08U1A的Nand Flash,內部包含了2個K9K8G08U0A,所以,總容量是K9K8G08U0A的兩倍=1GB×2=2GB,類似地K9NBG08U5A,內部包含了4個K9K8G08U0A,總大小就是4×1GB=4GB。

 

下面詳細介紹一下,Nand Flash的一個chip內部的硬件邏輯組織結構。

1.2.5. Nand Flash的物理存儲單元的陣列組織結構

Nand Flash的內部組織結構,此處還是用圖來解釋,比較容易理解:

圖 1.3. Nand Flash物理存儲單元的陣列組織結構

上圖是K9K8G08U0A的datasheet中的描述。

簡單解釋就是:

1.2.5.1. Block塊

一個Nand Flash(的chip,芯片)由很多個塊(Block)組成,塊的大小一般是128KB,256KB,512KB,此處是128KB。其他的小於128KB的,比如64KB,一般都是下面將要介紹到的small block的Nand Flash。

塊Block,是Nand Flash的擦除操作的基本/最小單位。

1.2.5.2. Page頁

每個塊里面又包含了很多頁(page)。每個頁的大小,對於現在常見的Nand Flash多數是2KB,最新的Nand Flash的是4KB、8KB等,這類的頁大小大於2KB的Nand Flash,被稱作big block的Nand Flash,對應的發讀寫命令地址,一共5個周期(cycle),而老的Nand Flash,頁大小是256B,512B,這類的Nand Flash被稱作small block,地址周期只有4個。

頁Page,是讀寫操作的基本單位。

不過,也有例外的是,有些Nand Flash支持subpage(1/2頁或1/4頁)子頁的讀寫操作,不過一般很少見。

1.2.5.3. oob / Redundant Area / Spare Area

每一個頁,對應還有一塊區域,叫做空閑區域(spare area)/冗余區域(redundant area),而Linux系統中,一般叫做OOB(Out Of Band),這個區域,是最初基於Nand Flash的硬件特性:數據在讀寫時候相對容易錯誤,所以為了保證數據的正確性,必須要有對應的檢測和糾錯機制,此機制被叫做EDC(Error Detection Code)/ECC(Error Code Correction, 或者 Error Checking and Correcting),所以設計了多余的區域,用於放置數據的校驗值。

Oob的讀寫操作,一般是隨着頁的操作一起完成的,即讀寫頁的時候,對應地就讀寫了oob。

關於oob具體用途,總結起來有:

  1. 標記是否是壞快
  2. 存儲ECC數據
  3. 存儲一些和文件系統相關的數據。如jffs2就會用到這些空間存儲一些特定信息,而yaffs2文件系統,會在oob中,存放很多和自己文件系統相關的信息。

 

 

1.2.6. Flash名稱的由來

Flash的擦除操作是以block塊為單位的,與此相對應的是其他很多存儲設備,是以bit位為最小讀取/寫入的單位,Flash是一次性地擦除整個塊:在發送一個擦除命令后,一次性地將一個block,常見的塊的大小是128KB/256KB。。,全部擦除為1,也就是里面的內容全部都是0xFF了,由於是一下子就擦除了,相對來說,擦除用的時間很短,可以用一閃而過來形容,所以,叫做Flash Memory。所以一般將Flash翻譯為 (快速)閃存。

1.2.7. Flash相對於普通設備的特殊性

根據上面提到過的,Flash最小操作單位,相對於普通存儲設備,就顯得有些特殊。

因為一般存儲設備,比如硬盤或內存,讀取和寫入都是以位(bit)為單位,讀取一個bit的值,將某個值寫入對應的地址的位,都是可以按位操作的。

但是Flash由於物理特性,使得內部存儲的數據,只能從1變成0,這點,這點可以從前面的內部實現機制了解到,對於最初始值,都是1,所以是0xFFFFFFFF,而數據的寫入,即是將對應的變成0,而將數據的擦出掉,就是統一地,以block為單位,全部一起充電,所有位,都變成初始的1,而不是像普通存儲設備那樣,每一個位去擦除為0。而數據的寫入,就是電荷放電的過程,代表的數據也從1變為了0。

所以,總結一下Flash的特殊性如下:

表 1.2. Flash和普通設備相比所具有的特殊性

1.2.8. Nand Flash的位反轉特性

Nand Flash的位反轉,也叫做位翻轉,對應的英文表達有:Bit Flip=Bit Flipping=Bit-Flip=Bit twiddling。

Nand Flash由於本身硬件的內在特性,會導致(極其)偶爾的出現位反轉的現象。

所謂的位反轉,bit flip,指的是原先Nand Flash中的某個位,變化了,即要么從1變成0了,要么從0變成1了。

1.2.8.1. Nand Flash位反轉的原因

Nand Flash的位反轉現象,主要是由以下一些原因/效應所導致:

  1. 漂移效應(Drifting Effects)

    漂移效應指的是,Nand Flash中cell的電壓值,慢慢地變了,變的和原始值不一樣了。

  2. 編程干擾所產生的錯誤(Program-Disturb Errors)

    此現象有時候也叫做,過度編程效應(over-program effect)。

    對於某個頁面的編程操作,即寫操作,引起非相關的其他的頁面的某個位跳變了。

  3. 讀操作干擾產生的錯誤(Read-Disturb Errors)

    此效應是,對一個頁進行數據讀取操作,卻使得對應的某個位的數據,產生了永久性的變化,即Nand Flash上的該位的值變了。

1.2.8.2. Nand Flash位反轉的影響

位反轉,說白了,就是讀取數據的時候,數據出錯了。

因此,如果你讀取的數據正好是屬於某個重要的文件中的數據,比如系統的配置文件等,那么此時錯了一位,都會導致系統出現異常,問題相對會很嚴重。

而如果此數據屬於音視頻流中的數據,那么此時即使錯了一位,對整個音視頻的播放產生的影響也很小,所以問題也不大。

1.2.8.3. Nand Flash位反轉的類型和解決辦法

對應的位反轉的類型,有兩種:

  1. 一種是nand flash物理上的數據存儲的單元上的數據,是正確的,只是在讀取此數據出來的數據中的某位,發生變化,出現了位反轉,即讀取出來的數據中,某位錯了,本來是0變成1,或者本來是1變成0了。此處可以成為軟件上位反轉。此數據位的錯誤,當然可以通過一定的校驗算法檢測並糾正。
  2. 另外一種,就是nand flash中的物理存儲單元中,對應的某個位,物理上發生了變化,原來是1的,變成了0,或原來是0的,變成了1,發生了物理上的位的數據變化。此處可以成為硬件上的位反轉。此錯誤,由於是物理上發生的,雖然讀取出來的數據的錯誤,可以通過軟件或硬件去檢測並糾正過來,但是物理上真正發生的位的變化,則沒辦法改變了。不過個人理解,好像也是可以通過擦除Erase整個數據塊Block的方式去擦除此錯誤,不過在之后的Nand Flash的使用過程中,估計此位還是很可能繼續發生同樣的硬件的位反轉的錯誤。

以上兩種類型的位反轉,其實對於從Nand Flash讀取出來的數據來說,解決其中的錯誤的位的方法,都是一樣的,即通過一定的校驗算法,常稱為ECC,去檢測出來,或檢測並糾正錯誤。

如果只是單獨檢測錯誤,那么如果發現數據有誤,那么再重新讀取一次即可。

實際中更多的做法是,ECC校驗發現有錯誤,會有對應的算法去找出哪位錯誤並且糾正過來。

其中對錯誤的檢測和糾正,具體的實現方式,有軟件算法,也有硬件實現,即硬件Nand Flash的控制器controller本身包含對應的硬件模塊以實現數據的校驗和糾錯的。

 

1.2.9. Nand Flash引腳(Pin)的說明

圖 1.4. Nand Flash引腳功能說明

上圖是常見的Nand Flash所擁有的引腳(Pin)所對應的功能,簡單翻譯如下:

表 1.3. Nand Flash引腳功能的中文說明

 

1.2.9.1. 為何需要ALE和CLE

硬件上,有了電源的Vcc和接地的Vss等引腳,很好理解,但是為何還要有ALE和CLE這樣的引腳,為何設計這么多的命令,把整個系統搞這么復雜,關於這點,最后終於想明白了:

設計命令鎖存使能(Command Latch Enable, CLE) 和 地址鎖存使能(Address Latch Enable,ALE),那是因為,Nand Flash就8個I/O,而且是復用的,也就是,可以傳數據,也可以傳地址,也可以傳命令,為了區分你當前傳入的到底是啥,所以,先要用發一個CLE(或ALE)命令,告訴Nand Flash的控制器一聲,我下面要傳的是命令(或地址),這樣,里面才能根據傳入的內容,進行對應的動作。否則,Nand Flash內部,怎么知道你傳入的是數據,還是地址,還是命令,也就無法實現正確的操作了。

1.2.9.2. Nand Flash只有8個I/O引腳的好處

在Nand Flash的硬件設計中,你會發現很多個引腳。關於硬件上為何設計這樣的引腳,而不是直接像其他存儲設備,比如普通的RAM,直接是一對數據線引出來,多么方便和好理解啊。

關於這樣設計的好處:

1.2.9.2.1. 減少外圍連線

相對於並口(Parellel)的Nor Flash的48或52個引腳來說,的確是大大減小了引腳數目,這樣封裝后的芯片體積,就小很多。現在芯片在向體積更小,功能更強,功耗更低發展,減小芯片體積,就是很大的優勢。同時,減少芯片接口,也意味着使用此芯片的相關的外圍電路會更簡化,避免了繁瑣的硬件連線。

1.2.9.2.2. 提高系統的可擴展性

因為沒有像其他設備一樣用物理大小對應的完全數目的addr引腳,在芯片內部換了芯片的大小等的改動,對於用全部的地址addr的引腳,那么就會引起這些引腳數目的增加,比如容量擴大一倍,地址空間/尋址空間擴大一倍,所以,地址線數目/addr引腳數目,就要多加一個,而對於統一用8個I/O的引腳的Nand Flash,由於對外提供的都是統一的8個引腳,內部的芯片大小的變化或者其他的變化,對於外部使用者(比如編寫Nand Flash驅動的人)來說,不需要關心,只是保證新的芯片,還是遵循同樣的接口,同樣的時序,同樣的命令,就可以了。這樣就提高了系統的擴展性。

說白了,對於舊的Nand Flash所實現的驅動,這些軟件工作,在換新的硬件的Nand Flash的情況下,仍然可以工作,或者是通過極少的修改,就同樣可以工作,使得軟硬件兼容性大大提高。

 

1.2.10. Nand Flash的一些典型(typical)的特性

  1. 頁擦除時間是200us,有些慢的有800us
  2. 塊擦除時間是1.5ms
  3. 頁數據讀取到數據寄存器的時間一般是20us
  4. 串行訪問(Serial access)讀取一個數據的時間是25ns,而一些舊的Nand Flash是30ns,甚至是50ns
  5. 輸入輸出端口是地址和數據以及命令一起multiplex復用的
  6. Nand Flash的編程/擦除的壽命:即,最多允許的擦除的次數

    以前老的Nand Flash,編程/擦除時間比較短,比如K9G8G08U0M,才5K次,而后來的多數也只有10K=1萬次,而現在很多新的Nand Flash,技術提高了,比如,Micron的MT29F1GxxABB,Numonyx的 NAND04G-B2D/NAND08G-BxC,都可以達到100K,也就是10萬次的編程/擦除,達到和接近於之前常見的Nor Flash,幾乎是同樣的使用壽命了。

  7. 封裝形式

    48引腳的TSOP1封裝 或 52引腳的ULGA封裝

1.2.11. Nand Flash控制器與Nand Flash芯片

關於Nand Flash的控制器Controller和Nand Flash芯片chip之間的關系,覺得有必要解釋一下:

首先,我們要知道的是,我們寫驅動,是寫Nand Flash 控制器的驅動,而不是Nand Flash 芯片的驅動,因為獨立的Nand Flash芯片,一般來說,是很少直接拿來用的,多數都是硬件上有對應的硬件的Nand Flash的控制器,去操作和控制Nand Flash,包括提供時鍾信號,提供硬件ECC校驗等等功能,我們所寫的驅動軟件,是去操作Nand Flash的控制器

然后由控制器去操作Nand Flash芯片,實現我們所要的功能。

1.2.12. Nand Flash中的特殊硬件結構

由於Nand Flash相對其他常見設備來說,比較特殊,所以,特殊的設備,就有特殊的設計,就對應某些特殊的硬件特性,就有必要解釋解釋:

頁寄存器(Page Register)

由於Nand Flash讀取和編程操作來說,一般最小單位是頁,所以Nand Flash在硬件設計時候,就考慮到這一特性,對於每一片(Plane),都有一個對應的區域專門用於存放,將要寫入到物理存儲單元中去的或者剛從存儲單元中讀取出來的,一頁的數據,這個數據緩存區,本質上就是一個緩存buffer,但是只是此處datasheet里面把其叫做頁寄存器page register而已,實際將其理解為頁緩存,更貼切原意。

 

而正是因為有些人不了解此內部結構,才容易產生之前遇到的某人的誤解,以為內存里面的數據,通過Nand Flash的FIFO,寫入到Nand Flash里面去,就以為立刻實現了實際數據寫入到物理存儲單元中了,而實際上只是寫到了這個頁緩存中,只有當你再發送了對應的編程第二階段的確認命令,即0x10,之后,實際的編程動作才開始,才開始把頁緩存中的數據,一點點寫到物理存儲單元中去。

 

所以,簡單總結一下就是,對於數據的流向,實際是經過了如下步驟:

 

圖 1.5. Nand Flash讀寫時的數據流向

 

1.2.13. Nand Flash中的壞塊(Bad Block)

Nand Flash中,一個塊中含有1個或多個位是壞的,就稱為其為壞塊Bad Block。

壞塊的穩定性是無法保證的,也就是說,不能保證你寫入的數據是對的,或者寫入對了,讀出來也不一定對的。與此對應的正常的塊,肯定是寫入讀出都是正常的。

1.2.13.1. 壞塊的分類

壞塊有兩種:

  1. 出廠時就有存在的壞塊

    一種是出廠的時候,也就是,你買到的新的,還沒用過的Nand Flash,就可以包含了壞塊。此類出廠時就有的壞塊,被稱作factory (masked) bad block或initial bad/invalid block,在出廠之前,就會做對應的標記,標為壞塊。

  2. 使用過程中產生的壞塊

    第二類叫做在使用過程中產生的,由於使用過程時間長了,在擦塊除的時候,出錯了,說明此塊壞了,也要在程序運行過程中,發現,並且標記成壞塊的。具體標記的位置,和上面一樣。這類塊叫做worn-out bad block。即用壞了的塊。

1.2.13.2. 壞塊的標記

具體標記的地方是,對於現在常見的頁大小為2K的Nand Flash,是塊中第一個頁的oob起始位置(關於什么是頁和oob,下面會有詳細解釋)的第1個字節(舊的小頁面,pagesize是512B甚至256B的Nand Flash,壞塊標記是第6個字節),如果不是0xFF,就說明是壞塊。相對應的是,所有正常的塊,好的塊,里面所有數據都是0xFF的。

不過,對於現在新出的有些Nand Flash,很多標記方式,有些變化,有的變成該壞塊的第一個頁或者第二個頁,也有的是,倒數最后一個或倒數第二個頁,用於標記壞塊的。

具體的信息,請參考對應的Nand Flash的數據手冊,其中會有說明。

對於壞塊的標記,本質上,也只是對應的flash上的某些字節的數據是非0xFF而已,所以,只要是數據,就是可以讀取和寫入的。也就意味着,可以寫入其他值,也就把這個壞塊標記信息破壞了。對於出廠時的壞塊,一般是不建議將標記好的信息擦除掉的。

uboot中有個命令是

nand scrub

就可以將塊中所有的內容都擦除了,包括壞塊標記,不論是出廠時的,還是后來使用過程中出現而新標記的。一般來說,不建議用這個。

不過,在實際的驅動編程開發過程中,為了方便起見,我倒是經常用,其實也沒啥大礙,呵呵。不過呢,其實最好的做法是,用

nand erase

只擦除好的塊,對於已經標記壞塊的塊,不要輕易擦除掉,否則就很難區分哪些是出廠時就壞的,哪些是后來使用過程中用壞的了。

1.2.13.3. 壞塊的管理

對於壞塊的管理,在Linux系統中,叫做壞塊管理(BBM,Bad Block Management),對應的會有一個表去記錄好塊,壞塊的信息,以及壞塊是出廠就有的,還是后來使用產生的,這個表叫做壞塊表(BBT,Bad Block Table)。在Linux 內核MTD架構下的Nand Flash驅動,和Uboot中Nand Flash驅動中,在加載完驅動之后,如果你沒有加入參數主動要求跳過壞塊掃描的話,那么都會去主動掃描壞塊,建立必要的BBT的,以備后面壞塊管理所使用。

1.2.13.4. 壞塊的比例

而關於好塊和壞塊,Nand Flash在出廠的時候,會做出保證:

  1. 關於好的,可以使用的塊的數目達到一定的數目,比如三星的K9G8G08U0M,整個flash一共有4096個塊,出廠的時候,保證好的塊至少大於3996個,也就是意思是,你新買到這個型號的Nand Flash,最壞的可能, 有3096-3996=100個壞塊。不過,事實上,現在出廠時的壞塊,比較少,絕大多數,都是使用時間長了,在使用過程中出現的。
  2. 保證第一個塊是好的,並且一般相對來說比較耐用。做此保證的主要原因是,很多Nand Flash壞塊管理方法中,就是將第一個塊,用來存儲上面提到的BBT,否則,都是出錯幾率一樣的塊,那么也就不太好管理了,連放BBT的地方,都不好找了,^_^。

一般來說,不同型號的Nand Flash的數據手冊中,也會提到,自己的這個Nand Flash,最多允許多少個壞塊。就比如上面提到的,三星的K9G8G08U0M,最多有100個壞塊。

 

1.2.14. Nand Flash中頁的訪問順序

在一個塊內,對每一個頁進行編程的話,必須是順序的,而不能是隨機的。比如,一個塊中有128個頁,那么你只能先對page0編程,再對page1編程,。。。。,而不能隨機的,比如先對page3,再page1,page2,page0,page4,。。。

關於此處對於只能順序給頁編程的說法,只是翻譯自datasheet,但是實際情況卻發現是,程序中沒有按照此邏輯處理,可以任意對某Block內的Page去做Program的動作,而不必是順序的。但是datasheet為何如此解釋,原因未知,有待知情者給解釋一下。

1.2.15. 常見的Nand Flash的操作

要實現對Nand Flash的操作,比如讀取一頁的數據,寫入一頁的數據等,都要發送對應的命令,而且要符合硬件的規定,如圖:

圖 1.6. Nand Flash K9K8G08U0A的命令集合

 

從上圖可以看到,如果要實現讀一個頁的數據,就要發送Read的命令,而且是分兩個周期(Cycle),即分兩次發送對應的命令,第一次是0x00h,第二次是0x30h,而兩次命令中間,需要發送對應的你所要讀取的頁的地址,關於此部分詳細內容,留待后表。

對應地,其他常見的一些操作,比如寫一個頁的數據(Page Program),就是先發送0x80h,然后發生要寫入的地址,再發送0x10h。

 

關於一些常見的操作,比如讀一個頁的Read操作和寫一個頁的Page Program,下面開始更深入的介紹。

1.2.15.1. 頁編程(Page Program)注意事項

Nand flash的寫操作叫做編程Program,編程,一般情況下,是以頁為單位的。

有的Nand Flash,比如K9K8G08U0A,支持部分頁編程(Partial Page Program),但是有一些限制:在同一個頁內的,連續的部分頁的編程,不能超過4次。

一般情況下,都是以頁為單位進行編程操作的,很少使用到部分頁編程。

關於這個部分頁編程,本來是一個頁的寫操作,卻用兩個命令或更多的命令去實現,看起來是操作多余,效率不高,但是實際上,有其特殊考慮:

至少對於塊擦除來說,開始的命令0x60是擦除設置命令(erase setup comman),然后傳入要擦除的塊地址,然后再傳入擦除確認命令(erase confirm command)0xD0,以開始擦除的操作。

這種完成單個操作要分兩步發送命令的設計,即先開始設置,再最后確認的命令方式,是為了避免由於外部由於無意的/未預料而產生的噪音,比如,由於某種噪音,而產生了0x60命令,此時,即使被Nand Flash誤認為是擦除操作,但是沒有之后的確認操作0xD0,Nand Flash就不會去擦除數據,這樣使得數據更安全,不會由於噪音而誤操作。

1.2.15.2. 讀(Read)操作過程詳解

下面以最簡單的read操作為例,解釋如何理解時序圖,以及將時序圖中的要求,轉化為代碼。

解釋時序圖之前,讓我們先要搞清楚,我們要做的事情:

從Nand Flash的某個頁Page里面,讀取我們要的數據。

要實現此功能,會涉及到幾部分的知識,即使我們不太懂Nand Flash的細節,但是通過前面的基本知識的介紹,那么以我們的常識,至少很容易想到的就是,需要用到哪些命令,怎么發這些命令,怎么計算所需要的地址,怎么讀取我們要的數據等等。

下面就一步步的解釋,需要做什么,以及如何去做:

1.2.15.2.1. 需要使用何種命令

首先,是要了解,對於讀取數據,要用什么命令:

根據前面關於Nand Flash的命令集合介紹,我們知道,要讀取數據,要用到Read命令,該命令需要2個周期,第一個周期發0x00,第二個周期發0x30。

1.2.15.2.2. 發送命令前的准備工作以及時序圖各個信號的具體含義

知道了用何命令后,再去了解如何發送這些命令。

 

圖 1.7. Nand Flash數據讀取操作的時序圖

我們來一起看看,我在圖6中的特意標注的①邊上的黃色豎線。

黃色豎線所處的時刻,是在發送讀操作的第一個周期的命令0x00之前的那一刻。

讓我們看看,在那一刻,其所穿過好幾行都對應什么值,以及進一步理解,為何要那個值。

  1. 黃色豎線穿過的第一行,是CLE。還記得前面介紹命令所存使能(CLE)那個引腳吧?CLE,將CLE置1,就說明你將要通過I/O復用端口發送進入Nand Flash的,是命令,而不是地址或者其他類型的數據。只有這樣將CLE置1,使其有效,才能去通知了內部硬件邏輯,你接下來將收到的是命令,內部硬件邏輯,才會將受到的命令,放到命令寄存器中,才能實現后面正確的操作,否則,不去將CLE置1使其有效,硬件會無所適從,不知道你傳入的到底是數據還是命令了。
  2. 而第二行,是CE#,那一刻的值是0。這個道理很簡單,你既然要向Nand Flash發命令,那么先要選中它,所以,要保證CE#為低電平,使其有效,也就是片選有效。
  3. 第三行是WE#,意思是寫使能。因為接下來是往Nand Flash里面寫命令,所以,要使得WE#有效,所以設為低電平。
  4. 第四行,是ALE是低電平,而ALE是高電平有效,此時意思就是使其無效。而對應地,前面介紹的,使CLE有效,因為將要數據的是命令(此時是發送圖示所示的讀命令第二周期的0x30),而不是地址。如果在其他某些場合,比如接下來的要輸入地址的時候,就要使其有效,而使CLE無效了。
  5. 第五行,RE#,此時是高電平,無效。可以看到,知道后面低6階段,才變成低電平,才有效,因為那時候,要發生讀取命令,去讀取數據。
  6. 第六行,就是我們重點要介紹的,復用的輸入輸出I/O端口了,此刻,還沒有輸入數據,接下來,在不同的階段,會輸入或輸出不同的數據/地址。
  7. 第七行,R/B#,高電平,表示R(Ready)/就緒,因為到了后面的第5階段,硬件內部,在第四階段,接受了外界的讀取命令后,把該頁的數據一點點送到頁寄存器中,這段時間,屬於系統在忙着干活,屬於忙的階段,所以,R/B#才變成低,表示Busy忙的狀態的。

介紹了時刻①的各個信號的值,以及為何是這個值之后,相信,后面的各個時刻,對應的不同信號的各個值,大家就會自己慢慢分析了,也就容易理解具體的操作順序和原理了。

1.2.15.2.3. 如何計算出我們要傳入的行地址和列地址

在介紹具體讀取數據的詳細流程之前,還要做一件事,那就是,先要搞懂我們要訪問的地址,以及這些地址,如何分解后,一點點傳入進去,使得硬件能識別才行。

此處還是以K9K8G08U0A為例,此Nand Flash,一共有8192個塊,每個塊內有64頁,每個頁是2K+64 Bytes。

假設,我們要訪問其中的第7000個塊中的第64頁中的1208字節處的地址,此時,我們就要先把具體的地址算出來:

物理地址

=塊大小×塊號 + 頁大小×頁號 + 頁內地址

=128K×7000 + 2K×64 + 1208

=0x36B204B8

接下來,我們就看看,怎么才能把這個實際的物理地址,轉化為Nand Flash所要求的格式。

在解釋地址組成之前,先要來看看其datasheet中關於地址周期的介紹:

圖 1.8. Nand Flash的地址周期組成

 

結合圖 1.7 “Nand Flash數據讀取操作的時序圖”中的2,3階段,我們可以看出,此Nand Flash地址周期共有5個,2個列(Column)周期,3個行(Row)周期。

  1. 對應地,列地址A0~A10,就是頁內地址,地址范圍是從0到2047。

    細心的讀者可能注意到了,為何此處多出來個A11呢?

    這樣從A0到A11,一共就是12位,可以表示的范圍就是0~212,即0~4096了。

    實際上,由於我們訪問頁內地址,可能會訪問到oob的位置,即2048-2111這64個字節的范圍內,所以,此處實際上只用到了2048~2111,用於表示頁內的oob區域,其大小是64字節。

  2. 對應地,A12~A30,稱作頁號,頁的號碼,可以定位到具體是哪一個頁。

    A18~A30,表示對應的塊號,即屬於哪個塊。

簡單解釋完了地址組成,那么就很容易分析上面例子中的地址了。

注意,下面這樣的方法,是錯誤的:

0x36B204B8 = 11 0110 1011 0010 0000 0100 1011 1000,分別分配到5個地址周期就是:

 

而至於上述計算方法為何是錯誤的,那是因為上面計算過程中,把第11位的值,本來是屬於頁號的位A11,給算成頁內地址里面的值了。

應該是這樣計算,才是對的:

0x36B204B8 = 11 0110 1011 0010 0000 0100 1011 1000

 

那有人會問了,上面表11中,不是明明寫的A0到A30,其中包括A11,不是正好對應着此處地址中的bit0到bit30嗎?

其實,我開始也是犯了同樣的錯誤,誤以為我們要傳入的地址的每一位,就是對應着表11中的A0到A30呢,實際上,表11中的A11,是比較特殊的,只有當我們訪問頁內地址處於oob的位置,即屬於2048~2111的時候,A11才會其效果,才會用A0-A11用來表示對應的某個屬於2048~2111的某個值,屬於oob的某個位置。

而我們此處的頁內地址為2108,還沒有超過2047呢,所以A11肯定是0。

 

這么解釋,顯得很繞,很難看懂。

換種方式來解釋,就容易聽懂了:

說白了,我們就是要訪問第7000個塊中的第64頁中的1208字節處,對應着

頁內地址

=1208

=0x4B8

 

頁號

=塊數×頁數/塊 + 塊內的頁號

= 7000×(128K/2K) + 64

= 7000×64 + 64

= 448064

=0x6D640

 

也就是,我們要訪問0x6D640頁內的0x4B8地址,這樣很好理解吧,^_^。

然后對應的:

頁內地址=0x4B8

分成兩個對應的列地址,就變成

0x4B8 :列地址1=0xB8,列地址2=0x04

 

頁號=0x6D640,分成三個行號就是:

0x6D640:行號1=0x40,行號2=0xD6,行號3=0x06

再回頭看看上面的計算方法,

最開始計算出來的:

列地址1=0xB8

列地址2=0x04

行號1=0x20

行號2=0x6B

行號3=0x03

是錯誤的。

 

而第二次計算正確的:

列地址1=0xB8

列地址2=0x04

行號1=0x40

行號2=0xD6

行號3=0x06

才是對的,也和我們此處自己手動計算,是一致的。

第一次之所以計算錯,就是錯誤的把行地址的最低一位A11,放到列地址中的最高位了。

至此,才算把如何手動計算行地址和列地址,解釋明白和正確了。

對應的,Linux的源碼\drivers\mtd\nand\nand_base.c中,也是這樣處理的:

static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
                int column, int page_addr)
{
......
        /* Serially input address */
        if (column != -1) {
......
            chip->cmd_ctrl(mtd, column1, ctrl); /* 發送Col Addr 1 */
            ctrl &= ~NAND_CTRL_CHANGE;
            chip->cmd_ctrl(mtd, column >> 8, ctrl); /* 發送Col Addr 2 */
        }
        if (page_addr != -1) {
            chip->cmd_ctrl(mtd, page_addr2, ctrl); /* 發送Row Addr 1 */
            chip->cmd_ctrl(mtd, page_addr >> 8, /* 發送Row Addr 2 */
                       NAND_NCE | NAND_ALE); 
            /* One more address cycle for devices > 128MiB */
            if (chip->chipsize > (128 << 20))
                chip->cmd_ctrl(mtd, page_addr >> 16, /* 發送Row Addr 3 */
                           NAND_NCE | NAND_ALE); 
        }
}

因此,我們要訪問第7000個塊中的第64頁中的1208字節處的話,所要傳入的地址就是分5個周期:

分別傳入兩個列地址的:

列地址1=0xB8

列地址2=0x04

然后再傳3個行地址的:

行號1=0x40

行號2=0xD6

行號3=0x06

這樣硬件才能識別。

而接下來的內容,也就是介紹硬件是如何處理這些輸入的。

 

1.2.15.2.4. 讀操作過程的解釋

准備工作終於完了,下面就可以開始解釋說明,對於讀操作的,上面圖中標出來的,1-6個階段,具體是什么含義。

操作准備階段:此處是讀(Read)操作,所以,先發一個圖5中讀命令的第一個階段的0x00,表示,讓硬件先准備一下,接下來的操作是讀。

發送兩個周期的列地址。也就是頁內地址,表示,我要從一個頁的什么位置開始讀取數據。

接下來再傳入三個行地址。對應的也就是頁號。

然后再發一個讀操作的第二個周期的命令0x30。接下來,就是硬件內部自己的事情了。

Nand Flash內部硬件邏輯,負責去按照你的要求,根據傳入的地址,找到哪個塊中的哪個頁,然后把整個這一頁的數據,都一點點搬運到頁緩存中去。而在此期間,你所能做的事,也就只需要去讀取狀態寄存器,看看對應的位的值,也就是R/B#那一位,是1還是0,0的話,就表示,系統是busy,仍在”忙“(着讀取數據),如果是1,就說系統活干完了,忙清了,已經把整個頁的數據都搬運到頁緩存里去了,你可以接下來讀取你要的數據了。

對於這里。估計有人會問了,這一個頁一共2048+64字節,如果我傳入的頁內地址,就像上面給的1208一類的值,只是想讀取1028到2011這部分數據,而不是頁開始的0地址整個頁的數據,那么內部硬件卻讀取整個頁的數據出來,豈不是很浪費嗎?答案是,的確很浪費,效率看起來不高,但是實際就是這么做的,而且本身讀取整個頁的數據,相對時間並不長,而且讀出來之后,內部數據指針會定位到你剛才所制定的1208的那個位置。

接下來,就是你“竊取“系統忙了半天之后的勞動成果的時候了,呵呵。通過先去Nand Flash的控制器中的數據寄存器中寫入你要讀取多少個字節(byte)/字(word),然后就可以去Nand Flash的控制器的FIFO中,一點點讀取你要的數據了。

至此,整個Nand Flash的讀操作就完成了。

對於其他操作,可以根據我上面的分析,一點點自己去看datasheet,根據里面的時序圖去分析具體的操作過程,然后對照代碼,會更加清楚具體是如何實現的。

 

1.2.16. Nand Flash的一些高級特性

1.2.16.1. Nand Flash的Unique ID

1.2.16.1.1. 什么是Unique ID唯一性標識

Unique ID,翻譯為中文就是,獨一無二的ID,唯一性標識。

很明顯,這個Unique ID是為了用來識別某些東西的,每一個東西都擁有一個獨一無二的標識信息。

在Nand Flash里面的Unique ID,主要是某個ID信息,保證每個Nand Flash都是獨一無二的。主要用於其它的使用Nand Flash的用戶,根據此unique id去做加密等應用,實現某些安全方面的應用。

簡而言之,就是用Nand Flash的Unique ID來實現安全相關的應用,比如加密,版權保護等等。

1.2.16.1.2. 不同Nand Flash廠商的對Unique ID的不同的實現方法

此處,繼續解釋之前,還要再次贅述一下:

目前Nand Flash的廠家有samsung,Toshiba,Intel, Hynix,Micron,Numonyx,Phison ,SanDisk,Sony,Spansion等。

由於前面所說的Nand Flash的規范之爭,即Toshiba & Samsung和Intel + 其它廠商(Hynix,Micron,Numonyx,Phison ,SanDisk,Sony,Spansion等)之爭,導致對於Unique ID這么個小的功能點(feature),不同的方面,弄出了不同的實現(做法)。

下面就來解釋一下各個廠家關於Unique ID的實現方法,以及如何讀取對應的Unique ID:

1.2.16.1.2.1. Toshiba東芝的Nand的Unique ID

網上找到一個datasheet:

Toshiba TH58NS512DC

http://datasheet.elcodis.com/pdf/11/23/112371/th58ns512dc-to51y.pdf

中有提到:

P1:The TH58NS512DC is a SmartMediaTM with ID and each device has 128 bit unique ID number embedded in the device. This unique ID number is applicable to image files, music files, electronic books, and so on where copyright protection is required.”即每個Toshiba的TH58NS512DC中,都有一個128 bit=16 byte的Unique ID,可用於圖片,音樂,電子書等應用中的版權保護。

P24:

圖 1.9. Toshiba的Unique ID

  

1.2.16.1.2.2. 讀取Toshiba的Nand的Unique ID

從上面可以看出,Toshiba的Nand中,關於Unique ID,是需要先通過普通的0x90,即Read ID的命令,去讀取Nand的ID,找到第三個字節(3rd byte),然后判斷其是否是0xA5,如果是0xA5,然后才能確定此Nand里面是有Unique ID的,然后才有去讀取Unique ID這一說。

而關於如何獨缺Unique ID,則需要和自己去聯系Toshiba,和其簽訂NDA協議后,才可得知讀取Nand的Unique ID的方法。

 

1.2.16.1.3. Samsung三星的Nand的Unique ID

網上找到的某款三星的Nand的datasheet:

Samsung K9F5608U0B

http://hitmen.c02.at/files/docs/psp/ds_k9f5608u0b_rev13.pdf

6. Unique ID for Copyright Protection is available

- The device includes one block sized OTP (One Time Programmable), which can be used to increase system security or to provide identification capabilities. Detailed information can be obtained by contact with Samsung

即,Samsung的Nand的Unique ID,也和Toshiba的用途類似,也主要是用於版權保護,但是其實現卻不同。

Samsung的Unique ID的實現,是專門在Nand 里面配備了一個OTP的Block,而此Nand芯片的Block大小是16KB。

而關於如何操作此OTP,即如何寫入數據和讀取數據,此處未說明。

欲知詳情,請聯系三星。

不過個人理解,應該和普通的block的操作類似,即普通的block,包含很多page,每個page的操作,有對應的page read,用對應的page read命令來讀取此特殊的OTP的block里面的數據。

而此OTP的block里面的數據是什么,完全取決於自己最開始往里面寫入了什么數據。說白了就是,你根據自己需求,在你的產品出廠的時候,寫入對應的數據,比如該款產品的SN序列號等數據,然后自己在用page read讀取出相應數據后,自己解析,得到自己要的信息,用於自己的用途,比如版權保護等。

1.2.16.1.3.1. 讀取Samsung的Nand的Unique ID

如前所述:

關於如何操作此OTP的block,即如何寫入數據和讀取數據,此處未說明。

即想要知道如何讀取Samsung的Nand的Unique ID,請自己去問三星。

 

1.2.16.1.4. 遵循ONFI規范的廠商的Nand的Unique ID

主要指的是Intel英特爾,Hynix海力士,Micron美光,Numonyx恆億,Spansion飛索等公司。

對應的Nand 的Unique ID的相關定義,ONFI的規范中都有,現簡要摘錄如下:

ONFI 2.2

http://onfi.org/wp-content/uploads/2009/02/ONFI%202_2%20Gold.pdf

ONFI規范中,在5.7.1. Parameter Page Data Structure Definition”中,如圖:

圖 1.10. ONFI的參數頁數據結構定義

 

定義了一個page的數據,用於存儲對應的Nand的各種參數,其中,有一個第8個字節的bit5==1的時候,表示支持“Read Unique ID”的命令,即說明此Nand芯片支持此命令,如果byte8的bit5==0,那么說明不支持,也就沒法去讀Unique ID了。

1.2.16.1.4.1. 讀取遵循ONFI的廠商的Nand的Unique ID

如果經過上述判斷,此符合ONFI的Nand Flash支持Read Unique ID命令,次此時就可以通過該命令來讀取對應的Nand Flash的Unique ID了。

此Read Unique ID的詳細解釋為:

 5.8. Read Unique ID Definition

The Read Unique ID function is used to retrieve the 16 byte unique ID (UID) for the device. The unique ID when combined with the device manufacturer shall be unique.

The UID data may be stored within the Flash array. To allow the host to determine if the UID is without bit errors, the UID is returned with its complement, as shown in Table 47. If the XOR of the UID and its bit-wise complement is all ones, then the UID is valid.

即用Read Unique ID命令來讀取128bit=16字節的Unique ID,但是呢,為了用於防止寫入的Unique ID有誤,因此在16字節后面又添了個對應的補碼,即每位取反的結果,這樣前16字節的Unique ID和后16字節的Unique ID的補碼,構成了32字節,算作一組,如下圖所示:

圖 1.11. ONFI中Unique ID的結構

To accommodate robust retrieval of the UID in the case of bit errors, sixteen copies of the UID and the corresponding complement shall be stored by the target. For example, reading bytes 32-63 returns to the host another copy of the UID and its complement. Read Status Enhanced shall not be used during execution of the Read Unique ID command

 

Figure 57 defines the Read Unique ID behavior. The host may use any timing mode supported by the target in order to retrieve the UID data.


而為了進一步防止出錯,將上面32字節算一組,重復了16次,將這16個32字節的數據,存在Nand Flash里面,然后用Read Unique ID命令去讀取出來,取得其中某個32字節即可,然后判斷前16字節和后16字節取反,如果結果所有位都是1,那么結果即為16個0xFF,那么說明Unique ID是正確的。否則說明有誤。

Read Unique ID的命令的詳細格式如下圖所示:

圖 1.12. ONFI中Read Unique ID命令的時序圖

即先發送0xED命令,再發送0x00地址,然后等待Nand Flash的busy狀態結束,就可以讀取出來的那16組的32個字節了,然后用上面辦法去判斷,找到前16字節和后16字節異或得到結果全部16字節都為0xFF,即說明得到了正確的Unique ID。至此,符合ONFI規范的Unique ID,就讀取出來了。

1.2.16.2. 片選無關(CE don’t-care)技術

很多Nand flash支持一個叫做CE don’t-care的技術,字面意思就是,不關心是否片選。

對此也許有人會問了,如果不片選,那還能對其操作嗎?答案就是,這個技術,主要用在當時是不需要選中芯片,但是芯片內部卻仍可以繼續操作的這些情況:在某些應用,比如錄音,音頻播放等應用中,外部使用的微秒(us)級的時鍾周期,此處假設是比較少的2us,在進行讀取一頁或者對頁編程時,是對Nand Flash操作,這樣的串行(Serial Access)訪問的周期都是20/30/50ns,都是納秒(ns)級的,此處假設是50ns,當你已經發了對應的讀或寫的命令之后,接下來只是需要Nand Flash內部去自己操作,將數據讀取除了或寫入進去到內部的數據寄存器中而已,此處,如果可以把片選取消,CE#是低電平有效,取消片選就是拉高電平,這樣會在下一個外部命令發送過來之前,即微秒量級的時間里面,即2us-50ns≈2us,這段時間的取消片選,可以降低很少的系統功耗,但是多次的操作,就可以在很大程度上降低整體的功耗了。

總的來說就是:由於某些外部應用所需要的訪問Nand Flash的頻率比較低,而Nand Flash內部操作速度比較快,所以在針對Nand Flash的讀或寫操作的大部分時間里面,都是在等待外部命令的輸入,同時卻選中芯片,產生了多余的功耗,此“不關心片選”技術,就是在Nand Flash的內部的相對快速的操作(讀或寫)完成之后,就取消片選,以節省系統功耗。待下次外部命令/數據/地址輸入來的時候,再選中芯片,即可正常繼續操作了。這樣,整體上,就可以大大降低系統功耗了。

1.2.16.3. 帶EDC的拷回操作以及Sector的定義(Copy-Back Operation with EDC & Sector Definition for EDC)

Copy-Back功能,簡單的說就是,將一個頁的數據,拷貝到另一個頁。

如果沒有Copy-Back功能,那么正常的做法就是,先要將那個頁的數據拷貝出來放到內存的數據buffer中,讀出來之后,再用寫命令將這頁的數據,寫到新的頁里面。

而Copy-Back功能的好處在於,不需要用到外部的存儲空間,不需要讀出來放到外部的buffer里面,而是可以直接讀取數據到內部的頁寄存器(page register)然后寫到新的頁里面去。

而且,為了保證數據的正確,要硬件支持EDC(Error Detection Code)的,否則,在數據的拷貝過程中,可能會出現錯誤,並且拷貝次數多了,可能會累積更多錯誤。

而對於錯誤檢測來說,硬件一般支持的是512字節數據,對應有16字節用來存放校驗產生的ECC數值,而這512字節一般叫做一個扇區。對於2K+64字節大小的頁來說,按照512字節分,分別叫做A,B,C,D區,而后面的64字節的oob區域,按照16字節一個區,分別叫做E,F,G,H區,對應存放A,B,C,D數據區的ECC的值。

Copy-Back編程的主要作用在於,去掉了數據串行讀取出來,再串行寫入進去的時間,所以,而這部分操作,是比較耗時的,所以此技術可以提高編程效率,提高系統整體性能。

1.2.16.4. 多片同時編程(Simultaneously Program Multi Plane)

對於有些新出的Nand Flash,支持同時對多個片進行編程,比如上面提到的三星的K9K8G08U0A,內部包含4片(Plane),分別叫做Plane0,Plane1,Plane2,Plane3。.由於硬件上,對於每一個Plane,都有對應的大小是2048+64=2112字節的頁寄存器(Page Register),使得同時支持多個Plane編程成為可能。 K9K8G08U0A支持同時對2個Plane進行編程。

不過要注意的是,只能對Plane0和Plane1或者Plane2和Plane3,同時編程,而不支持Plane0和Plane2同時編程。

1.2.16.5. 交錯頁編程(Interleave Page Program)

多片同時編程,是針對一個chip里面的多個Plane來說的,

而此處的交錯頁編程,是指對多個chip而言的。

可以先對一個chip,假設叫chip1,里面的一頁進行編程,然后此時,chip1內部就開始將數據一點點寫到頁里面,就出於忙的狀態了,而此時可以利用這個時間,對出於就緒狀態的chip2,也進行頁編程,發送對應的命令后,chip2內部也就開始慢慢的寫數據到存儲單元里面去了,也出於忙的狀態了。此時,再去檢查chip1,如果編程完成了,就可以開始下一頁的編程了,然后發完命令后,就讓其內部慢慢的編程吧,再去檢查chip2,如果也是編程完了,也就可以進行接下來的其他頁的編程了。如此,交互操作chip1和chip2,就可以有效地利用時間,使得整體編程效率提高近2倍,大大提高Nand Flash的編程/擦寫速度了。

1.2.16.6. 隨機輸出頁內數據(Random Data Output In a Page)

在介紹此特性之前,先要說說,與Random Data Output In a Page相對應的是,普通的,正常的,sequential data output in a page。

正常情況下,我們讀取數據,都是先發讀命令,然后等待數據從存儲單元到內部的頁數據寄存器中后,我們通過不斷地將RE#(Read Enale,低電平有效)置低,然后從我們開始傳入的列的起始地址,一點點讀出我們要的數據,直到頁的末尾,當然有可能還沒到頁地址的末尾,就不再讀了。所謂的順序(sequential)讀取也就是,根據你之前發送的列地址的起始地址開始,每讀一個字節的數據出來,內部的數據指針就加1,移到下個字節的地址,然后你再讀下一個字節數據,就可以讀出來你要的數據了,直到讀取全部的數據出來為止。

而此處的隨機(random)讀取,就是在你正常的順序讀取的過程中,先發一個隨機讀取的開始命令0x05命令,再傳入你要將內部那個數據指針定位到具體什么地址,也就是2個cycle的列地址,然后再發隨機讀取結束命令0xE0,然后,內部那個數據地址指針,就會移動到你所制定的位置了,你接下來再讀取的數據,就是從那個制定地址開始的數據了。

而Nand Flash數據手冊里面也說了,這樣的隨機讀取,你可以多次操作,沒限制的。

請注意,上面你所傳入的地址,都是列地址,也就是頁內地址,也就是說,對於頁大小為2K的Nand Flash來說,所傳入的地址,應該是小於2048+64=2112的。

不過,實際在Nand Flash的使用中,好像這種用法很少的。絕大多數,都是順序讀取數據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM