1、NandFlash的接口
1.1、Nand的型號與命名
? ? ? ? (1)、Nand的型號命名都有含義,就拿K9F2G08來示例分析一下:K9F表示是三星公司的NandFlash系列。2G表示Nand的大小是2Gbit (256MB)。08表示Nand是8位的 (8位就是數據線有8根)。
? ? ? ? (2)、Nand命名中可以看出:廠家、系列型號、容量大小、數據位數。
1.2、Nand的數據位
????????(1)、Nand有8位數據位的,有16位數據位的。做電路時/寫軟件時應該根據自己實際采購的Nnad的位數來設計電路/寫軟件。
????????(2)、說明Nand是并行接口的 (8/16位)。
????????(3)、Nand的數據線上傳遞的不一定全部是有效數據,也可能有命令、地址等。
1.3、Nand的功能框圖
????????(1)、Nand的結構可以看成是一個矩陣式存儲器,其中被分成一個一個的小塊,每一小塊可以存儲一個bit位,然后彼此以一定單位組合成整個Nand。
????????(2)、Nand中可以被單次訪問的最小單元(就是說對Nand進行一次讀寫至少要讀寫這么多,或者是這么多的整數倍) 叫做Page (頁),在K9F2G08芯片中,Page的大小是2KB+64B。也就是說我們要讀寫K9F2G08,每次至少要讀寫2KB或者n*2KB,即使我們只是想要其中的一個字節。這就是我們說的典型的塊設備 (現在有些塊設備為了方便,提供了一種random read模式,可以只讀取1個字節)。
????????(3)、頁往上還有個Block(塊)的概念,1個塊等于若個頁(如在K9F2G08中1個塊等于64頁)。
????????(4)、塊往上就是整個Nand芯片了,叫做Device。一個Device是若干個Block,譬如K9F2G08一個Device有2028個block。所以整個Device大小為:2048x64x2K =256MB。
????????(5)、塊設備分page、block有什么意義?首先要明白,塊設備不能完全按字節訪問而必須塊訪問是物理上的限制,而不是人為設置的障礙。其次,Page和Block各有各的意義,譬如Nand中:Page是讀寫Nand的最小單位;Block是擦除Nand的最小單位。 (這些規則都是Nand的物理原理和限制要求的,不是誰想要這樣的,所以對于我們做軟件的來說,只能去想辦法適應硬件,不是想著超越硬件)。
????????(6)、Nand芯片中主要包含2部分:Nand存儲顆粒+Nand接口電路。存儲顆粒就是純粹的Nand原理的存儲單元類似于倉庫;Nand接口電路是用來管理存儲顆粒,并且給外界提供一個統一的Nand接口規格的訪問接口的。
????????(7)、Nand中有多個存儲單元,每個單元都有自己的地址(地址是精確到字節的)。所以Nand是地址編排精確到字節,但是實際讀寫卻只能精確到頁(所以Nand的很多操作都要求給的地址是頁對齊的,譬如2K、4K、512K等這樣的地址,不能給3000B這樣的地址)。Nand讀寫時地址傳遞是通過IO線發送的,因為地址有30位而IO只有8位,所以需要多個cycle才能發送完畢。一般的Nand都是4cycle或者5cycle發送地址(從這里把Nand分為了4cycle Nand和5cycle Nand)。
????????總結:Nand芯片內部有存儲空間,并且有電路來管理這些存儲空間,向外部提供統一的Nand接口的訪問規則,然后外部的SoC可以使用Nand接口時序來讀寫這個Nand存儲芯片。Nand接口是一種公用接口,是一種標準,理論上來說外部SoC可以直接模擬Nand接口來讀寫Nand芯片,但是實際上因為nand接口對時序要求非常嚴格,而且時序很復雜,所以一般的SoC都是通過專用的硬件的Nand控制器(這些控制器一般是作為SoC的內部外設來存在的)來操控Nand芯片的。
2、NandFlash的結構
2.1、Nand的單元組織:block與page (大頁Nand與小頁Nand)
????????(1)、Nand的頁和以前講過的塊設備(尤其是硬盤)的扇區是類似的。扇區最早在磁盤中是512字節,后來也有些高級硬盤扇區不是512字節而是1024字節/2048字節/4096字節等。Nand也是一樣,不同的Nand的頁的大小是不同的,也有512字節/1024字節/2048字節/4096字節等。
????????(2)、一個block等于多少page也是不定的,不同的Nand也不同。一個Nand芯片有多少block也是不定的,不同的Nand芯片也不同。
????????總結:Nand的組織架構挺亂的,接口時序也不同,造成結果就是不同廠家的Nand芯片,或者是同一個廠家的不同系列型號存儲容量的nand接口也不一樣。所以nand有一個很大的問題就是一旦升級容量或者換芯片系列則硬件要重新做、軟件要重新移植。
2.2、帶內數據和帶外數據 (ECC與壞塊標記)
????????(1)、Nand的每個頁由2部分組成,這2部分各自都有一定的存儲空間。譬如K9F2G08中為2K+64字節。其中的2K字節屬于帶內數據,是我們真正的存儲空間,將來存儲在Nand中的有效數據就是存在這2K范圍內的(我們平時計算nand的容量時也是只考慮這2KB);64字節的帶外數據不能用來存儲有效數據,是作為別的附加用途的 (譬如用來存儲ECC數據、用來存儲壞塊標志等····)。
????????(2)、什么是ECC:(error correction code,錯誤校驗碼)。因為nand存儲本身出錯(位反轉)概率高 (Nand較Nor最大的缺點就是穩定性),所以當我們將有效信息存儲到Nand中時都會同時按照一定算法計算一個ECC信息(譬如CRC16等校驗算法),將ECC信息同時存儲到Nand這個頁的帶外數據區。然后等將來讀取數據時,對數據用同樣的算法再計算一次ECC,并且和從帶外數據區讀出的ECC進行校驗。如果校驗通過則證明Nand的有效數據可信,如果校驗不通過則證明這個數據已經被損壞(只能丟棄或者嘗試修復)。
????????(3)、壞塊標志:Nand芯片用一段時間后,可能某些塊會壞掉(這些塊無法擦除了,或者無法讀寫了),nand的壞塊非常類似于硬盤的壞道。壞塊是不可避免的,而且隨著Nand的使用壞塊會越來越多。當壞塊還不算太多時這個Nand都是可以用的,除非壞塊太多了不劃算使用了才會換新的。所以我們為了管理Nand發明了一種壞塊標志機制。Nand的每個頁的64字節的帶外數據中,我們(一般是文件系統)定義一個固定位置(譬如定位第24字節)來標記這個塊是好的還是壞的。文件系統在發現這個塊已經壞了沒法用了時會將這個塊標記為壞塊,以后訪問nand時直接跳過這個塊即可。
2.3、Nand的地址時序
? ? ? ? (1)、nand的地址有多位,分4/5周期通過IO引腳發送給Nand芯片來對Nand進行尋址。尋址的最小單位是字節,但是讀寫的最小單位是頁。
????????(2)、nand的地址在寫代碼時要按照Nand要求的時序和順序去依次寫入。
2.4、Nand的命令碼
????????(1)、外部SoC要想通過Nand控制器來訪問Nand (實質就是通過Nand接口),就必須按照Nand接口給nand發送命令、地址、數據等信息來讀寫Nand。
????????(2)、Nand芯片內部的管理電路本身可以接收外部發送的命令,然后根據這些命令來讀寫Nand內容與外部SoC交互。所以我們對nand進行的所有操作(擦除、讀、寫···)都要有命令、地址、數據的參與才能完成,而且必須按照Nand芯片規定的流程來做。
3、NandFlash的常見操作及流程分析
3.1、壞塊檢查
????????(1)、Flash使用之前要先統一擦除(擦除的單位是塊)。Flash類設備擦除后里面全是1,所以擦干凈之后讀出來的值是0xff。
????????(2)、檢查壞塊的思路就是:先塊擦除,然后將整塊讀出來,依次檢測各自節是否為0xff,如果是則表明不是壞塊,如果不是則表明是壞塊。
3.2、頁寫(program)操作
????????(1)、寫之前確保這個頁是被擦除于凈的。如果不是擦除于凈的(而是臟的、用過的)頁,寫進去的值就是錯的,不是你想要的結果。
????????(2)、寫操作(write)在flash的操作中就叫編程(proaram)。
????????(3)、SoC寫Flash時通過命令線、IO線依次發送寫命令、寫頁地址、寫數據等進入NandFlash。
????????(4)、寫的過程:SoC通過Nand控制器和Nand芯片完成順序對接,然后按照時序要求將一頁數據發給Nand芯片內部的接口電路。接口電路先接收數據到自己的緩沖區,然后再集中寫入Nand芯片的存儲區域中。Nand接口電路將一頁數據從緩沖區中寫入Nand存儲系統中需要一定的時間,這段時間Nand芯片不能再響應SoC發過來的其他命令,所以SoC要等待Nand接口電路忙完。等待方法是SoC不斷讀取狀態寄存器(這個狀態資存器有2種情況:一種是SoC的Nand控制器自帶的,另一種是SoC通過發命令得到命令響應得到的),然后通過檢查這個狀態寄存器的狀態位就能知道Nand接口電路剛才寫的那一頁數據寫完了沒、寫好了沒。直到SoC收到正確的狀態寄存器響應才能認為剛才要寫的那一頁數據已經ok。 (如果SoC收到的狀態一直不對,可以考慮重寫或者認為這一頁所在的塊已經是壞塊,或者整個Nand芯片已經掛掉了)。
????????(5)、正常情況下到了第四步就已經完了。但是因為Nand的讀寫有不靠譜情況,因此我們為了安全會去做ECC校驗。ECC校驗有硬件式校驗和軟件式校驗2種。軟件式校驗可以采用的策略有很多,其中之一 (Nand芯片手冊上推薦的方式是):將剛才寫入的1頁數據讀出來,和寫入的內容進行逐一對比。如果讀出的和寫入的完全一樣,說明剛才的寫入過程正確完成了;如果讀出來的和寫入的不完全一樣那就說明剛才的寫入有問題。
????????(6)、硬件式ECC:SoC的Nand控制器可以提供硬件式ECC(這個也是比較普遍的情況)。硬件式ECC就是在Nand的控制器中有個硬件模塊專門做ECC操作。當我們操作Nand芯片時,只要按照SoC的要求按時打開ECC生成開關,則當我們寫入nand芯片時SoC的Nand控制器的ECC模塊會自動生成ECC數據放在相應的寄存器中,然后我們只需要將這生成的ECC數據寫入Nand芯片的帶外數據區即可;在將來讀取這塊Nand芯片時,同樣要打開硬件ECC開關,然后開始讀,在讀的過程當中硬件ECC會自動計算讀進來的一頁數據的ECC值并將之放到相應的寄存器中。然后我們再讀取帶外數據區中原來寫入時存入的ECC值,和我們剛才讀的時候得到的ECC值進行校驗。校驗通過則說明讀寫正確,校驗不通過則說明不正確(放棄數據或者嘗試修復)。
3.3、擦除 (erase)操作
????????(1)、擦除時必須給塊對齊的地址。如果給了不對齊的地址,結果是不可知的(有些Nand芯片沒關系,它內部會自動將其對齊,而有些Nand會返回地址錯誤)。
????????(2)、讀寫時給的地址也是一樣,要求是頁對齊地址。如果給了不對齊的,也是有可能對有可能錯。
3.4、頁讀(read)操作
????????
4、S5PV210的NandFlash控制器
4.1、SoC的Nand控制器的作用
????????(1)、Nand芯片本身通過Nand接口電路來存取數據Nand接口電路和SoC之間通過Nand接口時序來通信。Nand接口時序相對復雜,如果要SoC完全用軟件來實現Nand接口時序有一些不好(主要是:第一很難保證時序能滿足、容易不穩定;第二代碼很難寫)。解決方案是:在SoC內部集成一個Nand控制器(實質就是塊硬件電路,這個硬件電路完全滿足Nand接口時序的操作,然后將接口時序的操作寄存器化)。
????????(2)、SoC和Nand芯片之間通信,在SoC沒有Nand控制器時需要SoC自己來處理接口時序,編程很麻煩,需要程序員看Nand芯片的接口時序圖,嚴格按照接口時序圖中編程(尤其要注意各個時間參數);在SoC有Nand控制器時SoC只需要編程操控Nand控制器的寄存器即可,Nand控制器內部硬件會根據寄存器值來生成合適的Nand接口時序和Nand芯片通信。所以在有Nand控制器時編程要簡單很多,我們讀寫Nand芯片時再也不用關注Nand接口時序了,只要關注SoC的Nand控制器的寄存器即可。
????????(3)、擴展來講,現在的技術趨勢就是:幾乎所有的外設在SoC內部都有對應的控制器來與其通信,那么SoC內部集成的各種控制器(也就是各種內部外設) 越多,則SoC硬件能完成的功能越多,將來用這個SoC來完成相應任務時軟件編程越簡單。譬如說圖形處理和圖像處理領域,2D圖像編碼(jpeg編碼)、視頻編碼(h.264編碼),現在大部分的application級別的SoC都有集成的內部編碼器(像S5PV210就有、更復雜的譬如4418、6818就更不用說了,只會更多更先進),我們可以利用這些硬件編碼器來進行快速編解碼,這樣軟件工作量和難度降低了很多 (這就是所謂的硬件加速)。
4.2、結構框圖分析
????????(1)、結構框圖中關鍵點:SFR(我們后續編程的關鍵,編程時就是通過讀寫SFR來產生Nand接口時序以讀寫Nand芯片的) + Nand interface (硬件接口,將來和Nand芯片的相應引腳進行連接) + ECC生成器
4.3、S5PV210的Nand控制器的主要寄存器
????????NFCONF、NFCONT、NFCMMD、NFADDR、NFDATA、NFMECCD0&NFMECCD1、NFSECCD、NFSTAT
5、Nand操作代碼解析
5.1、擦除函數
????????
5.2、頁讀取函數
5.3、頁寫入函數
總結:
????????(1)、像NandFlash這類芯片,通過專用的接口時序和SoC內部的控制器相連(這種連接方式是非常普遍的,像LCD、DDR等都是類似的連接)。這種接法和設計對我們編程來說,關鍵在于兩點:SoC的控制器的寄存器理解和Nand芯片本身的文檔、流程圖等信息。
????????(2)、對于我們來說,學習NandFlash,要注意的是:第一,要結合SoC的數據手冊、Nand芯片的數據手冊、示例代碼三者來理解。第二,初學時不要嘗試完全不參考自己寫出Nand操作的代碼,初學時應該是先理解實例代碼,知道這些代碼是怎么寫出來的,必要時對照文檔來理解代碼。代碼理解之后去做實踐,實踐成功后以后再考慮自己不參考代碼只參考文檔來寫出nand操作的代碼。
6、iNand介紹
6.1、iNand/eMMC/SDCard/MMCCard的關聯
????????(1)、最早出現的是MMC卡,卡片式結構,按照MMC協議設計。(相較于NandFlash芯片來說,MMC卡有2個優勢:第一是卡片化,便于拆裝;第二是統一了協議接口,兼容性好。)
????????(2)、后來出現SD卡,兼容MMC協議。SD卡較MMC有一些改進,譬如寫保護、速率、容量等。
????????(3)、SD卡遵守SD協議,有多個版本。多個版本之間向前兼容。
????????(4)、iNand/eMMC在SD卡的基礎上發展起來,較SD卡的區別就是將SD卡芯片化了 (解決卡的接觸不良問題,便于設備迷你化)。
????????(5)iNand和eMMC的關聯:eMMC是協議,iNand是Sandisk公司符合eMMC協議的一種芯片系列名稱。
6.2、iNand/eMMC的結構框圖及其與NandFlash的區別
????????(1)、iNand內部也是由存儲系統和接口電路構成(和Nand結構特性類似,不同之處在于接口電路功能不同)。
????????(2)、iNand的接口電路挺復雜,功能很健全。譬如:第一,提供eMMC接口協議,和SoC的eMMC接口控制器通信對接。第二,提供塊的ECC校驗相關的邏輯,也就是說iNand本身自己完成存儲系統的ECC功能,SoC使用iNand時自己不用寫代碼來進行ECC相關操作,大大簡化了SoC的編程難度。(NandFlash分2種:SLC和MLC,SLC更穩定,但是容量小價格高;MLC容易出錯,但是容量大價格低)。第三,iNand芯片內部使用MLC Nand顆粒,所以性價比很高。第四,iNand接口電路還提供了cache機制,所以iNand的操作速度很快。
6.3、iNand/eMMC的物理接口和SD卡物理接口的對比
????????(1)、S5PV210芯片本身支持4通道的SD/MMC,在X210中實際是在SD/MMCO通道接了iNand芯片,而SD/MMC2接了SD卡(SD/MMC3也接了SD卡)。
????????(2)、對比iNand和SD卡接線,發現:這兩個接線幾乎是一樣的,唯一的區別就是SD卡IO線有4根,而iNand的IO線有8根。
????????(3)、這個告訴我們,我們在實際操作iNand芯片時和操作SD卡時幾乎是一樣的(物理接線幾乎一樣,軟件操作協議幾乎一樣)。
6.4、結論:iNand/eMMC其實就是芯片化的SD/MMC卡,軟件操作和SD卡相同
????????分析iNand芯片的操作代碼時,其實就是以前的SD卡的操作代碼。一些細節的區別就是為了區分各種不同版本的SD卡、iNand的細節差異。
7、SD卡/iNand操作
7.1、硬件接口:DATA、CLK、CMD
????????(1)、iNand的IO線有8根,支持1、4、8線并行傳輸模式;SD卡IO線有4根,支持1、4線并行傳輸模式。
????????(2)、CMD線用來傳輸命令、CLK線用來傳輸時鐘信號。
????????(3)、接口有CLK線,工作時主機SoC通過CLK線傳輸時鐘信號給SD卡/iNand芯片,說明:SD/iNand是同步的SD/iNand的工作速率是由主機給它的CLK頻率決定的。
7.2、命令響應的操作模式
????????(1)、SD協議事先定義了很多標準命令(CMD0、CMD1···),每個命令都有它的作用和使用條件和對應的響應。SD卡工作的時候就是一個一個的命令周期組合起來的,在一個命令周期中,主機先發送CMD給SD卡,然后SD卡解析這個命令并且執行這個命令,然后SD卡根據結果回發給主機SoC一個響應。 (有些命令是不需要響應的,這時SD卡不會給主機回發響應,主機也不用等待響應)。標準的命令+響應的周期中,主機發完一個命令后應該等待SD卡的響應而不是接著發下一條命令。
7.3、SD/iNand的體系結構圖
????????(1)、SD卡內部有一個接口控制器,這個控制器類似于一個單片機,這個單片機的程序功能就是通過CMD線接收外部主機SoC發給SD卡的命令碼,然后執行這個命令并且回發響應給主機SoC。這個單片機處理命令及回發響應遵循的就是SD協議。這個單片機同時可以控制SD卡內部的存儲單元,可以讀寫存儲單元。
7.4、SD/iNand的寄存器(重點是RCA寄存器)
????????(1)、注意這里說的是SD卡內部的寄存器,而不是主機SoC的SD控制器的寄存器。(很多外置芯片內部都是有寄存器的,這些寄存器可以按照一定的規則訪問,訪問這些寄存器可以得知芯片的一些信息)。
????????(2)、RCA (relative address,相對地址寄存器)。我們在訪問SD卡時,實際上SD卡內部每個存儲單元的地址沒有絕對地址,都是使用相對地址。相對地址由SD卡自己決定的,存放在RCA寄存器中。
7.5、SoC的SD/MMC/iNand控制器簡介
????????(1)、不同的SoC可能在SD/MMC/iNand等支持方面有差異,但是如果支持都是通過內部提供SD控制器來支持的。
????????(2)、S5PV210的SD卡控制器在section8.7部分。
8、SD/iNand代碼實戰分析1
8.1、命令碼CMD和ACMD
????????(1)、SD卡工作在命令+響應的模式下。
????????(2)、SD協議的命令分2種:CMD和ACMDx。CMD是單命令命令,就是單獨發一個CMD即可表示一個意思。ACMD是一種擴展,就是發2個CMD加起來表示一個意思。可以認為ACMDx = CMDy+CMDz (y一般是55)。
8.2、卡類型識別SD or MMC?
????????(1)、MMC協議、SD協議、eMMC協議本身是一脈相承的,所以造成了一定的兼容性,所以當我們SoC控制器工作時連接到SoC上的可能是一個MMC卡、也可能是SD卡、也可能是iNand芯片。主機SoC需要去識別這個卡到底是什么版本的卡
????????(2)、SoC如何區分卡種類?因為不同版本的卡內部協議不同的,所以對卡識別命令的響應也是不同的。SoC通過發送一些命令、聽取響應就可以根據不同的響應判定卡的版本。
8.3、卡狀態
????????(1)、SD卡內部的接口控制器類似于一個單片機,這個單片機其實是一個狀態機。所以SD卡任何時候都屬于某一種狀態(空閑狀態、準備好狀態、讀寫狀態、出錯狀態···都是事先定義好的),在這種狀態下能夠接收的命令是一定的,接收到命令之后執行一定的操作然后根據操作結果會跳轉為其他狀態。如果主機發過來的命令和當前狀態不符狀態機就不響應,如果收到命令和當前狀態相符就會執行相應操作,執行完之后根據結果跳轉為其他狀態。
8.4、卡回復類型
????????(1)、一般來說,SD卡的命令都屬于:命令+響應的模式。也有極少數的SD卡命令是不需要回復的。
????????(2)、卡回復有R1、R7、R1B等8種類型,每種卡回復類型都有自己的解析規則。然后卡在特定狀態下響應特定命令時有可能回復哪種響應都是SD協議事先規定好的,詳細細節要查閱協議文檔。
9、SD/iNand代碼實戰分析2
9.1、linux內核風格的寄存器定義
????????(1)、定義一個基地址,然后定義要訪問的寄存器和基地址之間的偏移量,在最終訪問寄存器時地址就等干基地址+偏移量。
????????(2)、給大家提供的代碼中宏定義是不完整的,很多宏定義只能從字面意思來理解對應,無法通過語法完全獲得。這樣寫代碼的好處是可以見名知意,就算代碼不全都能讀。
9.2、SD/iNand相關的GPIO初始化
????????(1)、GPG0相關的GPIO初始化,參考LED部分的設置技術。
????????(2)、時鐘設置參考裸機第六部分時鐘那一章,設置時使用到了位操作技巧,參考C高級第二部分。
????????(3)、要求能夠在兩三分鐘之內完全看懂這些代碼涉及到的知識,要能夠在數據手冊、原理圖中找到相對應的點,要能夠瞬間明白代碼中涉及到的C語言語法技巧,這樣才叫融會貫通,才能夠從代碼中學到東西。
9.3、SD/iNand相關的時鐘系統設置
????????
9.4、SD/iNand的時鐘設置
????????(1)、SD卡本身工作需要時鐘,但是自己又沒有時鐘發生單元,依靠主機SoC的控制器通過SD接口中的CLK線傳一個時鐘過來給SD卡內部使用。所以主機SD卡控制器先初始化好自己的時鐘,然后將自己的時鐘傳給SD卡。
????????(2)、因為此時剛開始和SD卡通信,主機不清楚SD卡屬于哪個版本(高版本和低版本的SD卡的讀寫速率不同,高版本的可以工作在低版本的速率下,低版本的SD卡不能工作在高版本速率下),所以先給SD卡發400KHz的低速率時鐘,SD卡拿到這個時鐘后就能工作了。然后在后面和SD卡進行進一步通信時去識別SD卡的版本號,識別后再根據SD卡的版本進一步給它更合適的時鐘。
10、SD/iNand代碼實戰分析3
10.1、命令發送函數解析
????????