李洋 Michael Collier
摘要:隨著全球電視數(shù)字廣播的發(fā)展,數(shù)字電視已然成為市場的主流,集成模擬和數(shù)字電視信源解碼和高端后處理能力的SOC核心處理器芯片具有廣闊的市場前景。NAND Flash作為一種大容量的存儲設備,滿足了數(shù)字電視嵌入式系統(tǒng)對功耗、體積、成本及抗震性的苛刻要求,因而得到了廣泛的應用。該論文主要探討NAND Flash設備在數(shù)字電視中的工作原理以及基于Linux系統(tǒng)框架下的NAND Flash驅動程序的設計與實現(xiàn)。
關鍵詞:數(shù)字電視;嵌入式系統(tǒng);NAND Flash;驅動開發(fā);Linux
中圖分類號:TP316文獻標識碼:A文章編號:1009-3044(2012)01-0070-04
Design and Implementation of NAND Flash Driver in Digital TV
LI Yang,Michael Collier
(College of Information and Electrical Engineering, Shandong University of Science and Technology, Qingdao 266590, China)
Abstract: With the global development of digital broadcasting, digital television has become the mainstream of market, SOC processor chips integrated analog and digital TV source decoder and high capabilities of post-processing has broad market prospects. As a kind of large-capacity storage devices, NAND Flash meets the harsh requirements of power, size, cost and resistance to shock by embedded system, which has been widely used. This paper probes into the principles of the NAND Flash devices in DTV and the design and implementation of NAND Flash driver based on the framework of Linux.
Key words: digital TV; embedded system; NAND Flash; driver development; Linux
在嵌入式系統(tǒng)開發(fā)過程中,大容量存儲器模塊的設計已經(jīng)成了不可或缺的重要方面。數(shù)字電視SOC芯片的NAND Flash支持由兩部分組成[1]:NAND Flash控制器和NAND Flash存儲芯片(H27U1G8F2B)。當要訪問NAND Flash中的數(shù)據(jù)時,必須通過NAND Flash控制器發(fā)送命令才能完成,因此開發(fā)一個高效的NAND Flash控制器的驅動程序顯得尤其重要。
1 NAND Flash工作原理
1.1 NAND Flash組織結構
該數(shù)字電視系統(tǒng)采用的NAND Flash型號為K9F1G08U0B,整個芯片分為1024個塊(block),塊是擦除的基本單位。每個塊又分為64頁(page),每個頁包含2112字節(jié)的容量,其中2K字節(jié)用于存放數(shù)據(jù),64個字節(jié)用來存放ECC校驗信息及其他額外數(shù)據(jù)。用戶數(shù)據(jù)存儲區(qū)總容量為128MB,額外數(shù)據(jù)區(qū)總容量為4MB。NAND Flash以頁為單位讀寫數(shù)據(jù),而以塊為單位擦除數(shù)據(jù)[2]。NAND Flash的存儲結構如圖1所示。
圖1 Nand Flash存儲結構圖
1.2 NAND Flash尋址方式
按照上述的組織方式可以形成三類地址:
Column Address:列地址
Page Address:頁地址
Block Address:塊地址
表1 NAND Flash尋址方式表
A0 ~A11是列地址,共12位以保證能尋址到2112的頁容量;A12~A17是頁地址,共6位,保證能尋址到每個塊中的64個頁;A18~A27是塊地址,共10位,用來尋址1024個塊。由于地址只能在I/O[7:0]上傳遞,因此,必須采用移位的方式進行。整個地址傳遞過程需要如下4步才能完成,稱為4-step addressing。
第1步是傳遞列地址的前8位,也就是A[0:7],不需移位即可傳遞到I/O[0:7]上;第2步是將NAND_ADDR右移8位,將列地址的后4位A[8:11]傳到I/O[0:7]上;第3步將NAND_ADDR再右移8位,將頁地址跟塊地址的前兩位放到I/O[0:7]上;
第4步將NAND_ADDR繼續(xù)右移8位,將塊地址的最后8位放到I/O[0:7]上。
1.3 NAND Flash操作方式
1)擦除操作:
擦除操作時以塊為單位進行的,擦除的啟動指令為60h,隨后的2個時鐘周期是塊地址。其中只有A17到A27是有效的,而A12到A17是可以忽略的。塊地址之后是擦除確認指令D0h,用來開始內(nèi)部的擦除操作。器件檢測到擦除確認命令后,在/WE的上升沿啟動內(nèi)部寫控制器,開始執(zhí)行擦除和擦除校驗。內(nèi)部擦除操作完成后,應該檢測寫狀態(tài)位(I/O 0),從而了解擦除操作是否成功完成。
2)寫操作:
寫入操作以頁為單位。寫入之前必須在擦除之后,否則寫入時將會出現(xiàn)錯誤。頁寫入周期中包括以下步驟:
寫入串行數(shù)據(jù)輸入指令80h。然后寫入4個字節(jié)的地址,最后串行寫入數(shù)據(jù)。串行寫入的數(shù)據(jù)最多為2112B。串行數(shù)據(jù)寫入完成后,需要寫入“頁寫入確認”指令10h,這條指令將初始化器件內(nèi)部寫入操作。10h寫入之后,NAND Flash的內(nèi)部寫控制器將自動執(zhí)行內(nèi)部寫入和校驗中必要的算法和時序,系統(tǒng)可以通過檢測R/B的輸出,或讀狀態(tài)寄存器的狀態(tài)位I/O 0來判斷內(nèi)部寫入是否結束。
2 NAND Flash控制器
該NAND Flash控制器的讀寫擦除都是來自AMBA APB總線的請求。NAND Flash控制器的主要功能是把來自于AMBA APB總線的請求轉化為標準的NAND Flash的命令序列。
因為NAND Flash的普通的數(shù)字讀寫都是以頁為基礎的,所以在NAND Flash控制器中使用了一個2K的數(shù)據(jù)緩存buffer。
對于數(shù)據(jù)路徑的設計,因為NAND Flash的輸入輸出總線是一個命令形式的串行總線,地址和數(shù)據(jù)復用一條總線,所以設計中有必要引入一個多路器。另外,為了提高系統(tǒng)的可靠性,數(shù)據(jù)通路中引入了可選的ECC功能。
3 NAND Flash驅動程序設計
3.1 LINUX MTD驅動框架
NAND Flash作為boot loader、內(nèi)核與文件系統(tǒng)的最佳載體,是嵌入式系統(tǒng)中必不可少的一個外設。Linux內(nèi)核引入了MTD內(nèi)存技術設備子系統(tǒng)來為NAND Flash、NOR Flash等存儲設備提供統(tǒng)一的接口,從而使Flash驅動的設計大大簡化。引入MTD框架后,NAND Flash設備驅動可以分為如圖3幾層。
圖3 NAND Flash驅動程序分層結構
1)硬件驅動層
NAND Flash硬件驅動層負責FLASH硬件設備的讀、寫、擦除,Linux MTD設備的NAND Flash驅動則位于/driver/mtd/nand子目錄下。
2) MTD原始設備層:
MTD原始設備層由兩部分構成,一部分是MTD原始設備的通用代碼(mtdcore.c、mtdpart.c),另一部分是各個特定的FLASH的數(shù)據(jù),例如分區(qū)等。
3) MTD設備層:
基于MTD原始設備,Linux系統(tǒng)可以定義出MTD的塊設備(主設備號31)和字符設備(設備號90),構成設備層。MTD字符設備在mtdchar.c實現(xiàn),MTD塊設備在mtdblock.c實現(xiàn)。
4)設備節(jié)點:
通過mknod命令在dev子目錄下建立MTD字符設備節(jié)點(主設備號為90)和塊設備節(jié)點(主設備號為31),用戶通過訪問該設備節(jié)點即可訪問MTD字符設備和塊設備。
3.2 NAND Flash平臺驅動結構體
NAND Flash平臺驅動結構體定義如下:
static struct platform_driver hiview_nand_driver = {.probe= hiview_nand_probe,
.remove= hiview_nand_remove,
.suspend = hiview_nand_suspend,.resume= hiview_nand_resume,.driver= {
.name = "hiview-nand",.owner = THIS_MODULE,},}; 1) hiview_nand_probe函數(shù)是驅動真正開始工作的部分,主要作用是初始化硬件、掃描設備、分配相應的資源等[3]。這部分代碼根據(jù)具體的NAND Flash器件有關,必須自己去實現(xiàn)。
2) hiview_nand_remove函數(shù)與函數(shù)hiview_nand_probe相對應,主要完成NAND Flash的反初始化工作,包括釋放系統(tǒng)資源及關閉硬件時鐘等。
3) suspend和resume主要用于電源管理的相關操作,在沒有電源管理的系統(tǒng)中放個空函數(shù)即可。
3.3 NAND Flash底層操作函數(shù)實現(xiàn)
通過平臺驅動中的hiview_nand_probe函數(shù)注冊之后,相應的函數(shù)都掛載完畢,初始化工作也已經(jīng)做完,此時NAND Flash便可以工作了[4]。上層在訪問NAND Flash的時候,通過MTD,一層一層向下調(diào)用,最終調(diào)用到底層的操作函數(shù)。
1) hiview_nand_write_buf和hiview_nand_read_buf:
這是兩個最基本的操作函數(shù),其功能就是往NAND Flash控制器的FIFO中讀寫數(shù)據(jù)。比如要讀取一頁的數(shù)據(jù),那么在發(fā)送完相關的讀命令和等待時間之后,就會調(diào)用到你底層的read_buf,去NAND Flash的FIFO中,一點點把所需要的數(shù)據(jù)讀取出來,放到內(nèi)存的緩存中去。寫操作也是類似,將我們內(nèi)存中的數(shù)據(jù),寫到NAND Flash的FIFO中去。
2) hiview_nand_devready:
NAND Flash的一些操作,比如讀1頁數(shù)據(jù),寫入1頁數(shù)據(jù),擦除1個塊,都需要一定的時間,在命令發(fā)送完成后,就是硬件開始忙著工作的時候了,而硬件什么時候完成。這些操作,就是通過這個函數(shù)去檢查狀態(tài)的。具體實現(xiàn)都是去讀硬件的一個狀態(tài)寄存器,其中某一位是否是1,對應著是處于“就緒”還是“忙”狀態(tài)。
3) hiview_nand_enable_hwecc:
在硬件支持的前提下,前面設置了硬件ECC的話,要實現(xiàn)這個函數(shù),用于每次在讀寫操作前,通過設置對應的硬件寄存器的某些位,使得啟用硬件ECC,這樣在讀寫操作完成后,就可以去讀取硬件校驗產(chǎn)生出來的ECC數(shù)值了。
4) hiview_nand_correct_data:
當實際操作過程中,讀取出來的數(shù)據(jù)所對應的硬件或軟件計算出來的ECC和從OOB中讀出來的ECC不一樣的時候,就是說明數(shù)據(jù)有誤了,就需要調(diào)用此函數(shù)去糾正錯誤[5]。對于常見的ECC算法來說,可以發(fā)現(xiàn)2位,糾正1位。更復雜的情況和更加注重數(shù)據(jù)安全的情況下,一般是需要另外實現(xiàn)更高效和檢錯和糾錯能力更強的ECC算法。
4結束語
在驅動開發(fā)結束之后,將此驅動程序編譯成模塊,并整合到要移植的Linux系統(tǒng)中。經(jīng)過系統(tǒng)的整機調(diào)試,此NAND Flash驅動功能完整,性能穩(wěn)定,能夠很好的支持YAFFS2文件系統(tǒng),很好地滿足了設計需求。參考文獻:
[1]宋寶華.Linux設備驅動開發(fā)詳解[M].北京:人民郵電出版社,2008.
[2]漢澤西,呂飛.大容量NAND Flash在嵌入式系統(tǒng)中的應用[J].石油儀器,2006 (2):62-66
[3] Love R. Linux內(nèi)核設計與實現(xiàn)[M].陳莉君,譯.北京:機械工業(yè)出版社,2006.
[4]徐君明,陳振林,郭天杰.嵌入式硬件設計[M].北京:中國電力出版社,2007.
[5] Bovetd,Cesati M.深入理解LINUX內(nèi)核[M].陳莉君,張瓊生,張宏偉,譯.3版.北京:中國電力出版社,2007.