很久沒(méi)接觸過(guò) nandflash 驅(qū)動(dòng)了,最近工作又摸了一下,那就順便整理點(diǎn)筆記總結(jié)一下吧。nandflash 在我看來(lái)算是比較落后的存儲(chǔ)設(shè)備了,所以文章里沒(méi)有太多細(xì)節(jié)的東西,更多的是一些開(kāi)發(fā)思路和經(jīng)驗(yàn),希望能幫助到有需要的人。
一、了解 nandflash 當(dāng)前發(fā)展?fàn)顩r
什么是 nandflash?
nandflash 由許多保存位( bit )的單元( cell )組成,這些位通過(guò)電荷開(kāi)啟或關(guān)閉。這些開(kāi)/關(guān)單元的組織方式表示存儲(chǔ)在nandflash 上的數(shù)據(jù)。這些單元中的位數(shù)也決定了 nandflash 的命名,例如 Single Level Cell ( SLC ) nandflash 在每個(gè)單元中都包含一個(gè)位。MLC nandflash將每個(gè)單元的位數(shù)增加了一倍,而 TLC nandflash 則增加了三倍,這為更高容量的 nandflash 開(kāi)辟了道路。
SLC 的優(yōu)點(diǎn)是速度最快,最耐用,但缺點(diǎn)是價(jià)格昂貴,并且無(wú)法提供更高的存儲(chǔ)容量。SLC 是企業(yè)使用的首選。與 SLC 相比,MLC 和 TLC 閃存的生產(chǎn)成本更低,存儲(chǔ)容量更高,但要權(quán)衡相對(duì)較短的使用壽命和較慢的讀/寫(xiě)速度。MLC 和 TLC 是日常消費(fèi)計(jì)算機(jī)等個(gè)人用品的首選。
為什么在嵌入式設(shè)備上 emmc 取代了 nandflash?
由于NAND Flash芯片的不同廠牌包括三星、KingMax、東芝(Toshiba)或海力士(Hynix)、美光(Micron)等,都需要根據(jù)每家公司的產(chǎn)品和技術(shù)特性來(lái)重新設(shè)計(jì),過(guò)去并沒(méi)有哪個(gè)技術(shù)能夠通用所有廠牌的NAND Flash芯片。
而每次NAND Flash制程技術(shù)改朝換代,包括70納米演進(jìn)至50納米,再演進(jìn)至40納米或30納米制程技術(shù)。
手機(jī)客戶也都要重新設(shè)計(jì)(重新設(shè)計(jì)什么?因?yàn)槟阋ㄓ?,就需要通訊的電壓,時(shí)序,甚至接口命令,這些都隨著不同廠商,不同制程技術(shù)而不同,你作為手機(jī)制造商或者soc廠商,想要把每種新的 nandflash 集成到你的產(chǎn)品中,就要根據(jù)這些新的特性來(lái)花時(shí)間設(shè)計(jì)。soc這邊會(huì)有一個(gè)nandflash controller,你要根據(jù)采用的nandflash特性來(lái)配置nand flash controller,以達(dá)到成功通訊的目的)。
但半導(dǎo)體產(chǎn)品每1年制程技術(shù)都會(huì)推陳出新,存儲(chǔ)器問(wèn)題也拖累手機(jī)新機(jī)種推出的速度,因此像eMMC這種把所有存儲(chǔ)器和管理nandflash的控制芯片都包在1顆MCP上的概念,逐漸風(fēng)行起來(lái)。即:
NAND Flash 是一種存儲(chǔ)介質(zhì),要在上面讀寫(xiě)數(shù)據(jù),外部要加主控和電路設(shè)計(jì);
eMMC是NAND Flash+主控IC ,對(duì)外的接口協(xié)議與SD、TF卡類(lèi)似;
emmc 內(nèi)部根本的存儲(chǔ)介質(zhì)還是 nandflash,而不是一種全新的 storage。但是他定義并規(guī)范了統(tǒng)一接口比如:emmc 4.3, 4.4, 4.5(類(lèi)似于usb 2.0, 3.0 這樣的), 把和 nand flash 的通訊封裝在emmc內(nèi)部,而提供給外部的接口就是 emmc 接口。
同理, 外部,比如soc就需要有個(gè) sdmmc controller, 并且宣布支持 emmc 4.3/4.4.。。,那么,你需要做的就是,根據(jù)選用的emmc的版本號(hào),來(lái)給 sdmmc controller 來(lái)選擇一個(gè)通訊的接口版本號(hào)4.4。
二、如何驅(qū)動(dòng)一款NAND Flash?
參考:
(一) 基礎(chǔ)硬件知識(shí)
nandflash 是一個(gè)存儲(chǔ)芯片,那么它應(yīng)該能提供“讀地址A的數(shù)據(jù),把數(shù)據(jù)B寫(xiě)到地址A“的功能。
以Mini2440為例簡(jiǎn)單說(shuō)明一下:
問(wèn)1:原理圖上 NAND FLASH 和 S3C2440 之間只有數(shù)據(jù)線,如何傳輸?shù)刂纺兀?/p>
答1.在DATA0~DATA7上既傳輸數(shù)據(jù),又傳輸?shù)刂?,?dāng)ALE為高電平時(shí)傳輸?shù)氖堑刂贰?/p>
問(wèn)2:從NAND FLASH芯片手冊(cè)可知,要讀寫(xiě)NAND FLASH需要先發(fā)出命令,如何傳入命令?
在DATA0~DATA7上既傳輸數(shù)據(jù),又傳輸?shù)刂罚矀鬏斆睿?/p>
當(dāng)ALE為高電平時(shí)傳輸?shù)氖堑刂罚?/p>
當(dāng)CLE為高電平時(shí)傳輸?shù)氖敲睿?/p>
當(dāng)ALE和CLE都為低電平時(shí)傳輸?shù)氖菙?shù)據(jù);
問(wèn)3:數(shù)據(jù)線LDATAn既接到NAND FLASH,也接到NOR FLASH,還接到SDRAM、DM9000等等,cpu如何準(zhǔn)確的將某個(gè)地址發(fā)到正確的芯片上而不干擾其他芯片呢?
這些芯片,要訪問(wèn)之必須”選中“(即片選信號(hào)為低),沒(méi)有選中的芯片不會(huì)工作,相當(dāng)于沒(méi)接一樣。
問(wèn)4:假設(shè)燒寫(xiě)NAND FLASH,把命令、地址、數(shù)據(jù)發(fā)給它之后,NAND FLASH肯定不可能瞬間完成燒寫(xiě)的,怎么判斷燒寫(xiě)完成?
通過(guò)狀態(tài)引腳RnB來(lái)判斷:它為高電平表示就緒,它為低電平表示正忙。
問(wèn)5:怎么操作NAND FLASH呢?
答5. 根據(jù)NAND FLASH的芯片手冊(cè),一般的過(guò)程是:
(1) 發(fā)出命令
(2) 發(fā)出地址
(3) 寫(xiě)數(shù)據(jù)/讀數(shù)據(jù)
(4) 等待
(二) CPU nandflash 控制器章節(jié)導(dǎo)讀
SLC nandflash一般是1bit ecc,對(duì)應(yīng)的編解碼的過(guò)程需閱讀上述內(nèi)容。
MLC nandflash 一般是8/12/16 bit ecc,對(duì)應(yīng)的編解碼的過(guò)程需閱讀上述內(nèi)容。
(三) nandflash 芯片手冊(cè)導(dǎo)讀
特性列表,一般位于芯片手冊(cè)首頁(yè),可以幫助我們快速了解芯片特性,基本可以認(rèn)為是最重要的信息。
不同芯片廠商的nandflash芯片引腳定義基本是一致的,但是可能會(huì)有1~2引腳是有差異,需要核對(duì)。
上圖可用于確定nandflash的存儲(chǔ)布局;
上圖可用于核對(duì)芯片的型號(hào)和詳細(xì)的硬件特性;
(四) nandflash 調(diào)試思路:
1. 通讀 CPU 芯片手冊(cè) nandflash 控制器章節(jié):
- 了解該 CPU nandflash 控制器支持哪些特性,一般包括nandflash的bit數(shù),以確定是否支持當(dāng)前選用的nandflash芯片;- 明確該芯片的 nandflash 控制器 ecc 校驗(yàn)功能的工作流程;
2. 通讀 nandflash 芯片手冊(cè):
- 了解 nandflash 芯片的基本信息,例如ID、容量、類(lèi)型(SLC/MLC)- 結(jié)合板子的原理圖一起查看,以確定 CPU 和 nandflash 芯片的引腳連接是否正確。不同廠商(例如三星、鎂光)生產(chǎn)的nandflash引腳不一定完全兼容,可能會(huì)有一兩根引腳有差異;
3. 在 U-boot 或者 Linux 下實(shí)現(xiàn)讀取 nandflash 芯片的ID值的功能:nand_read_id()
- U-boot 和 Linux哪個(gè)順手用哪個(gè),U-boot的優(yōu)點(diǎn)是啟動(dòng)快,做測(cè)試方便點(diǎn),而 Linux的優(yōu)點(diǎn)是支持網(wǎng)絡(luò)/文件系統(tǒng),功能強(qiáng)大;- 能讀到 ID 只能說(shuō)明 CPU 和 nandflash 芯片硬件連接上有了些許保障 (例如發(fā)命令、讀數(shù)據(jù)),但是某些隱蔽的錯(cuò)誤硬件連接仍然會(huì)導(dǎo)致寫(xiě)數(shù)據(jù)異常;
4. 在 U-boot 或者 Linux 下實(shí)現(xiàn)讀取擦除 一塊數(shù)據(jù)的功能:nand_erase_block()
- 相比起讀寫(xiě)數(shù)據(jù),擦除 nandflash 數(shù)據(jù)塊較為容易。而且只有成功擦除了,才能進(jìn)一步驗(yàn)證讀寫(xiě)nandflash的功能。nandflash 數(shù)據(jù)塊被擦除后所有數(shù)據(jù)均為 0xFF,利用這個(gè)特性可以驗(yàn)證稍后需要實(shí)現(xiàn)的讀一頁(yè)的操作是否正常;
5. 在 U-boot 或者 Linux 下實(shí)現(xiàn)裸讀一頁(yè)數(shù)據(jù)( 不考慮ecc校驗(yàn) )的功能:nand_read_page_raw()
- nandflash 的1頁(yè)包括 main 區(qū)域和oob區(qū)域, main 區(qū)域用于保存用戶數(shù)據(jù),spare 區(qū)域用于保存 ecc校驗(yàn)碼;- 一般說(shuō)寫(xiě)一頁(yè)數(shù)據(jù)時(shí),需要結(jié)合上下文才能判斷是寫(xiě) main 區(qū)域還是寫(xiě) main + spare 區(qū)域;- nandflash 一般需要ecc 校驗(yàn)功能來(lái)保證數(shù)據(jù)的安全,但是在前期調(diào)試階段,我們可以不考慮ecc 校驗(yàn)直接實(shí)現(xiàn)裸讀一頁(yè)數(shù)據(jù)的功能。事實(shí)上,我們也無(wú)法考慮ecc 校驗(yàn)的功能,因?yàn)榈浆F(xiàn)在為止還不能寫(xiě)數(shù)據(jù)到 nandflash的main區(qū)域,更別說(shuō)寫(xiě) ecc 校驗(yàn)碼到oob區(qū)域;- 我們需要先實(shí)現(xiàn)讀數(shù)據(jù)的功能,確保讀數(shù)據(jù)功能的可靠后,待會(huì)才能用其來(lái)驗(yàn)證寫(xiě)數(shù)據(jù)的操作;
6. 在 U-boot 或者 Linux 下實(shí)現(xiàn)裸寫(xiě)一頁(yè)數(shù)據(jù)( 不考慮ecc校驗(yàn) )的功能;nand_write_page_raw()- 裸寫(xiě)一頁(yè)和裸讀一頁(yè)的操作可以相互協(xié)同驗(yàn)證;- uboot 的 cmp 命令可以對(duì)比兩塊內(nèi)存的數(shù)據(jù)是否相同,該命令可以用于驗(yàn)證寫(xiě)操作是否成功;
7. 在 U-boot 或者 Linux 下實(shí)現(xiàn)寫(xiě)一頁(yè)數(shù)據(jù)到 main區(qū)域,并將 nandflash 控制器生成的 ecc 校驗(yàn)碼填寫(xiě)到oob區(qū)域:nand_write_page()
- 寫(xiě)一頁(yè)數(shù)據(jù)到 main 區(qū)域時(shí),nandflash 控制器會(huì)生成 ecc 校驗(yàn)碼,這些校驗(yàn)碼就是用來(lái)保護(hù)這一頁(yè)數(shù)據(jù)的;
8. 在 U-boot 或者 Linux 下實(shí)現(xiàn)讀一頁(yè)數(shù)據(jù)的功能,包括讀 main 區(qū)域的數(shù)據(jù)和 spare 區(qū)域的 ecc 校驗(yàn)碼:nand_read_page()
- 從nandflash spare 區(qū)域讀到的 ecc 校驗(yàn)碼應(yīng)該發(fā)送給 nandflash 控制器,nandflash 控制器會(huì)幫我們計(jì)算好是否有bit 錯(cuò)誤,并且將結(jié)果和糾錯(cuò)需要用到的信息保存在寄存器中,軟件通過(guò)寄存器里的信息推導(dǎo)出正確的數(shù)據(jù);
9. 由于bit 錯(cuò)誤的問(wèn)題不容易出現(xiàn),所以在調(diào)試階段需要人為制造出與 spare 區(qū)域 不匹配的 main 數(shù)據(jù),以檢驗(yàn)ecc 校驗(yàn)功能是否正常,即數(shù)據(jù)是否能被糾正,大體的思路是:
- 通過(guò) nand_write_page() 寫(xiě)一頁(yè)正確的數(shù)據(jù)到 main 區(qū)域 和 spare 區(qū)域;- 篡改在內(nèi)存中的數(shù)據(jù),然后通過(guò) nand_write_page_raw() 將篡改后的數(shù)據(jù)填寫(xiě)到 main 區(qū)域,spare 區(qū)域保持不變;- 通過(guò)nand_read_page 讀 一頁(yè)數(shù)據(jù),如果能執(zhí)行糾錯(cuò)相關(guān)的代碼,并且能獲取到被篡改之前的數(shù)據(jù),則說(shuō)明校驗(yàn)功能是可以工作的;
10. 如果 main 區(qū)域的 ecc 校驗(yàn)碼字節(jié)數(shù)比較多,并且 spare 區(qū)域足夠大的話,可以對(duì)存放在 spare 區(qū)域里的 main ecc校驗(yàn)碼進(jìn)行二次 ecc,這時(shí)生成的 ecc 校驗(yàn)碼我將其稱(chēng)為 spare ecc,它一般會(huì)存放在spare區(qū)域的末尾,并不是必須的;
(五) Linux Nand Flash驅(qū)動(dòng)
參考:
《韋東山嵌入式Linux視頻第二期-nandflash》
Linux MTD stack
對(duì)于nandflash 驅(qū)動(dòng),需要重點(diǎn)關(guān)注的地方:
Flash memory abstraction layer/MTD layerdrivers/mtd/mtd*.c
Flash type abstration layer/NAND coredrivers/mtd/nand/nand_*.c
Flash controller driversdrivers/mtd/nand/*_nand.c
NAND legacy stack( Linux-4.16 之前)
/dev/mtd0是nandflash設(shè)備的字符設(shè)備驅(qū)動(dòng)節(jié)點(diǎn),上圖展示了 read(”/dev/mtd0“) 的底層實(shí)現(xiàn)(MTD layer-》NAND core-》Controller driver)。
NAND legacy stack 的弊端
無(wú)法執(zhí)行細(xì)粒度的NAND Flash 命令,粒度的大小被限制在NAND core層面了;
芯片廠商更新的NAND Flash特性時(shí)需修改所有的Controller driver;
NAND new stack( Linux-4.16 之后)
將NAND 的控制邏輯下放到Controller driver層,NAND Core統(tǒng)一調(diào)用Controller driver提供的鉤子函數(shù):exec_op();
(六) 測(cè)試穩(wěn)定性和性能
MTD tests support
mtd_nandecctest.ko:nand flash的ECC校驗(yàn)測(cè)試
mtd_pagetest.ko:nand flash的page讀寫(xiě)測(cè)試
mtd_speedtest.ko:MTD分區(qū)的讀寫(xiě)速度測(cè)試
mtd_subpagetest.ko:nand flash的sub-page接口測(cè)試
mtd_oobtest.ko:nand falsh的OOB區(qū)域讀寫(xiě)測(cè)試
mtd_readtest.ko:讀取整個(gè)MTD分區(qū)
mtd_stresstest.ko:隨機(jī)讀寫(xiě),擦除操作測(cè)試
mtd_torturetest.ko:該功能可用于做穩(wěn)定性或者壽命測(cè)試,隨機(jī)操作直到發(fā)生錯(cuò)誤
示例如下:
insmod mtd_stresstest.ko dev=9 count=1000
[ 3289.273771] =================================================
[ 3289.279826] mtd_stresstest: MTD device: 9
[ 3289.284079] mtd_stresstest: MTD device size 268435456, eraseblock size 131072, page size 2048, count of eraseblocks 2048, pages per eraseblock 64, OOB size 64
[ 3289.303250] mtd_stresstest: scanning for bad eraseblocks
[ 3289.420267] mtd_stresstest: scanned 2048 eraseblocks, 0 are bad
[ 3289.426534] mtd_stresstest: doing operations
[ 3289.431031] mtd_stresstest: 0 operations done
[ 3339.606972] mtd_stresstest: finished, 1000 operations done
[ 3339.612992] =================================================
一個(gè)反復(fù)讀寫(xiě)并校驗(yàn)數(shù)據(jù)正確性的小腳本:
#!/bin/sh
rm -rf /media/local/
count=1
while [ ${count} -lt 600 ]; do
TSTAMP=”`date` | ---》 ${count}“echo”$TSTAMP“
mkdir -p /media
time cp /usr/local /media/ -raf
diff /usr/local /media/local -r || exit -1
rm -rf /media/local;
sync
let count=${count}+1
done
三、NAND Flash 文件系統(tǒng)的選擇:YAFFS2
參考:
《基于nand flash的文件系統(tǒng)的整理》
《Cramfs、JFFS2、YAFFS2的全面對(duì)比》
針對(duì) nandflash 特點(diǎn)優(yōu)化其性能以及克服其缺點(diǎn)
nanflash 不是通常意義上的塊設(shè)備,塊設(shè)備的特點(diǎn)是可以對(duì)數(shù)據(jù)塊進(jìn)行讀、寫(xiě)操作(如磁盤(pán),文件系統(tǒng)等),但是對(duì)于nanflash 來(lái)說(shuō)有三種操作分別是:讀、寫(xiě)、擦除。只有對(duì)已擦除的塊才能進(jìn)行寫(xiě)操作。所以為了使其兼容傳統(tǒng)的硬件和系統(tǒng),需要對(duì)其進(jìn)行特殊處理;
當(dāng)一個(gè)閃存處在干凈狀態(tài)時(shí)(被擦除過(guò),但是還沒(méi)有寫(xiě)操作發(fā)生),這塊flash上的每一位(bit)都是邏輯1;
閃存的使用壽命是有限的,具體來(lái)說(shuō),閃存的使用壽命是由擦除塊的最大可擦除次數(shù)來(lái)決定的。超過(guò)了最大可擦除次數(shù),這個(gè)擦除塊就成為壞塊(bad block)了。因此要避免某個(gè)擦除塊被過(guò)度使用,以至于先于其他擦除塊變成壞塊,應(yīng)該在盡量少影響性能的前提下,使擦寫(xiě)操作均勻分布在每個(gè)擦除塊上,叫做損耗均衡(wear leveling)。
YAFFS意為「Yet Another Flash File System」,是目前唯一一個(gè)專(zhuān)門(mén)為NAND Flash設(shè)計(jì)的文件系統(tǒng)。它采用了類(lèi)日志結(jié)構(gòu),結(jié)合NAND Flash的特點(diǎn),提供了損耗平衡和掉電保護(hù)機(jī)制,可以有效地避免意外掉電對(duì)文件系統(tǒng)一致性和完整性的影響。
nanflash 和 YAFFS2之間是如何配合的?
通過(guò)分析mkyaffs2iamge.c可知:
yaffs2 映像文件是由一個(gè)個(gè)的main(4096) + spare(224)數(shù)據(jù)組成;
main里存放的是文件(包括目錄、普通文件、特殊文件等)數(shù)據(jù);
spare里前面的nand_oobinfo-》oobfree(2+22=24)個(gè)字節(jié)歸yaffs2自由使用,然后接下來(lái)的nand_oobinfo-》eccbytes(104)個(gè)字節(jié)都填0xFF,即yaffs2 images本身是不含有ecc校驗(yàn)碼的;(以上數(shù)值跟實(shí)際nandflash芯片相關(guān))
更多細(xì)節(jié):
how-yaffs-works[1]
[1]YAFF2官網(wǎng):https://yaffs.net/documents/how-yaffs-works編輯:jq
-
芯片
+關(guān)注
關(guān)注
455文章
50816瀏覽量
423615 -
NAND
+關(guān)注
關(guān)注
16文章
1682瀏覽量
136159 -
電壓
+關(guān)注
關(guān)注
45文章
5607瀏覽量
115776 -
嵌入式設(shè)備
+關(guān)注
關(guān)注
0文章
110瀏覽量
16963 -
slc
+關(guān)注
關(guān)注
0文章
49瀏覽量
22724
原文標(biāo)題:關(guān)于NAND Flash調(diào)試的一點(diǎn)總結(jié)
文章出處:【微信號(hào):zhuyandz,微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論