3 FLASH驅(qū)動程序開發(fā)
3.1 Linux系統(tǒng)下的驅(qū)動程序
Linux系統(tǒng)將所有的設備都看作具體的文件,通過文件系統(tǒng)對設備進行管理。所以在Linux架構(gòu)中,和設備相關(guān)的處理分成兩層:文件系統(tǒng)層和設備驅(qū)動層。設備驅(qū)動層用來屏蔽具體設備的細節(jié),文件系統(tǒng)層向用戶提供一組統(tǒng)一的接口。這種設備管理方法可以很好的實現(xiàn)設備無關(guān)性,使Linux系統(tǒng)可以隨著外部設備的發(fā)展進行擴展,比如要添加一個設備,只要根據(jù)該硬件設備特性向文件系統(tǒng)提供一組接口,應用程序通過系統(tǒng)調(diào)用接口來訪問設備。
Linux系統(tǒng)里將FLASH設備歸屬到MTD設備下管理,相對于常規(guī)塊設備驅(qū)動程序,MTD設備驅(qū)動程序能更好的支持和管理閃存。具體講,基于MTD的 FLAsH驅(qū)動程序,對上層可以很好的支持JFFS(針對NorFLASH)和YAFFS(針對NandFLASH)等文件系統(tǒng),對下層FLASH的讀寫,擦除,壞塊處理都能進行很好的管理,它在硬件設備和上層文件系統(tǒng)間提供一個抽象接口。
3.2 FLASH驅(qū)動程序開發(fā)流程
FLASH驅(qū)動程序有兩種編程方式。一種是直接編程進內(nèi)核(Kernel),另一種是編程成模塊(Modules),如果編程進內(nèi)核,會增加內(nèi)核的大小,還要改動內(nèi)核源文件,不能動態(tài)卸載,不利于調(diào)試,所以FLASH驅(qū)動編程采用模塊化方式較好。
FLASH驅(qū)動開發(fā)流程要經(jīng)過四步:模塊化設計,編譯,加載,調(diào)用驗證。如圖4所示。
3.2.1 驅(qū)動程序的模塊化設計
構(gòu)成FLASH驅(qū)動程序的所有子程序,要進行模塊化設計,必須加入兩個函數(shù):入口函數(shù)module init()和出口函數(shù)module_exit()。在執(zhí)行程序時module_init()會調(diào)用int_init cfi probe_init(void),負責初始化MTD芯片,同時這個函數(shù)還調(diào)用register_mtd_chip_driver(),將cfi_chipdrv加入至 MTD驅(qū)動器列表chip_drvs_list中。初始化成功返回0,否則返回負值。實現(xiàn)代碼為:
另一個函數(shù)module_exit()執(zhí)行時,會調(diào)用staticvoid_exit cfi_probe_exit(void),負責清除MTD芯片驅(qū)動工作。同時這個函數(shù)還調(diào)用unregister_mtd_chip_driver(),將cfi_chipdrv從MTD芯片驅(qū)動器列表chip_drvs_list中刪除。實現(xiàn)代碼為:
|
其中:-O指定代碼優(yōu)化的級別;-D內(nèi)核模塊必須按照特殊定義的參數(shù)進行編譯,這些參數(shù)跟在選項-D后;MODULE通知頭文件要給出適當?shù)膬?nèi)核模塊定義;-KERNEL-通知頭文件形成的目標代碼在內(nèi)核態(tài)運行。得到的文件*.O就是一個FLASH驅(qū)動程序的目標文件,這樣FLAsH驅(qū)動程序編譯好。編譯好的模塊*.O放在/lib/roodules/2.4.18/misc下,然后用dep-mod-a使此模塊成為可加載模塊。 3.2.3 驅(qū)動程序的加載 加載模塊要用到兩個命令:insmod(加載),rmmod(卸載)。加載時,module_init()函數(shù)被調(diào)用,這個函數(shù)向系統(tǒng)設備表登記 FLAsH設備。卸載時,module_exit()函數(shù)被調(diào)用,它釋放FLASH設備在系統(tǒng)設備表中占有的表項。注冊成功后就可以用mknod命令將 FLASH設備映射為一個特別文件,其他程序使用FLASH設備時,只要對此文件進行操作就行。Linux在/dev目錄中為每個設備建立了一個文件,用 ls-1命令列出函數(shù)返回值,若小于O,表示注冊失??;否則表示注冊成功。注冊以后,Linux將FLAsH設備名與主、次設備號聯(lián)系起來。當對 FLASH訪問時,Linux通過請求訪問FLASH設備名得到主、次設備號;然后把此訪問發(fā)送到FLASH設備驅(qū)動,F(xiàn)LASH驅(qū)動再根據(jù)次設備號調(diào)用不同的函數(shù)。 3.2.4 驅(qū)動程序的調(diào)用驗證 模塊加載到內(nèi)核后,然后就要調(diào)用驗證。在Linux根目錄下有dev子目錄,這里面是節(jié)點名,這些結(jié)點是通過mknod建立的,里面有MTD字符設備節(jié)點和MTD塊設備節(jié)點,通過訪問這些節(jié)點來訪問設備驅(qū)動程序。Open一般是設備節(jié)點上的第一個操作,訪問設備時其實就是系統(tǒng)調(diào)用open()函數(shù),然后 open()函數(shù)打開設備準備進行I/O操作,該函數(shù)注冊進mtd_fops結(jié)構(gòu)中。 上面就是NorFLASH和NandFLASH驅(qū)動程序架構(gòu),具體開發(fā)驅(qū)動程序時,就要填充架構(gòu)里的程序代碼,來完成驅(qū)動程序。這個框架中有一個函數(shù)表,具體到Linux系統(tǒng)里,需要提供一個結(jié)構(gòu)來向系統(tǒng)說明FLASH驅(qū)動程序所提供的一組入口點,這個結(jié)構(gòu)就是fop函數(shù)表。 FLASH驅(qū)動程序運行時,向內(nèi)核注冊,告訴系統(tǒng)fop函數(shù)表是跟FLASH驅(qū)動程序相關(guān)聯(lián)的。當用戶去訪問驅(qū)動程序時,系統(tǒng)就告訴文件系統(tǒng)的管理程序,調(diào)用fop函數(shù)表就可以,然后調(diào)用函數(shù)表里的函數(shù),完成用戶要求。當從設備來收發(fā)數(shù)據(jù)時,系統(tǒng)不是調(diào)用read(),write()這兩個函數(shù),fop結(jié)構(gòu)里沒這兩個函數(shù),而是要用到一個函數(shù)blk_init_queue(),這個函數(shù)向上注冊了一個請求處理函數(shù)request,對FLASH設備的讀取和發(fā)送數(shù)據(jù),都是從請求隊列發(fā)出一個請求,請求調(diào)用請求處理函數(shù),由請求處理函數(shù)執(zhí)行具體的讀寫操作。設計驅(qū)動程序90%工作來完成fop函數(shù)表及re- quest函數(shù),10%完成驅(qū)動程序中的一些函數(shù)接口。完成了這些函數(shù)加上上面的FLASH驅(qū)動程序架構(gòu)就構(gòu)成了完整的FLASH驅(qū)動程序。
4 結(jié) 語 基于Samsung公司的s3c2410處理器平臺,分析和設計NorFLASH和NandFLASH的接口和驅(qū)動,詳細介紹兩種FLASH的硬件結(jié)構(gòu)、性能差異、讀寫時序、以及驅(qū)動開發(fā)。NorFLASH和NandFLASH因其在存儲數(shù)據(jù)和程序以及性價比方面的優(yōu)勢,占據(jù)的存儲器市場份額越來越多,并在嵌入式系統(tǒng)中得到廣泛應用。
|
評論