本文引用地址:http://dyxdggzs.com/article/201809/389000.htm3 FLASH驅動(dòng)程序開(kāi)發(fā)
3.1 Linux系統下的驅動(dòng)程序
Linux系統將所有的設備都看作具體的文件,通過(guò)文件系統對設備進(jìn)行管理。所以在Linux架構中,和設備相關(guān)的處理分成兩層:文件系統層和設備驅動(dòng)層。設備驅動(dòng)層用來(lái)屏蔽具體設備的細節,文件系統層向用戶(hù)提供一組統一的接口。這種設備管理方法可以很好的實(shí)現設備無(wú)關(guān)性,使Linux系統可以隨著(zhù)外部設備的發(fā)展進(jìn)行擴展,比如要添加一個(gè)設備,只要根據該硬件設備特性向文件系統提供一組接口,應用程序通過(guò)系統調用接口來(lái)訪(fǎng)問(wèn)設備。
Linux系統里將FLASH設備歸屬到MTD設備下管理,相對于常規塊設備驅動(dòng)程序,MTD設備驅動(dòng)程序能更好的支持和管理閃存。具體講,基于MTD的 FLAsH驅動(dòng)程序,對上層可以很好的支持JFFS(針對NorFLASH)和YAFFS(針對NandFLASH)等文件系統,對下層FLASH的讀寫(xiě),擦除,壞塊處理都能進(jìn)行很好的管理,它在硬件設備和上層文件系統間提供一個(gè)抽象接口。
3.2 FLASH驅動(dòng)程序開(kāi)發(fā)流程
FLASH驅動(dòng)程序有兩種編程方式。一種是直接編程進(jìn)內核(Kernel),另一種是編程成模塊(Modules),如果編程進(jìn)內核,會(huì )增加內核的大小,還要改動(dòng)內核源文件,不能動(dòng)態(tài)卸載,不利于調試,所以FLASH驅動(dòng)編程采用模塊化方式較好。
FLASH驅動(dòng)開(kāi)發(fā)流程要經(jīng)過(guò)四步:模塊化設計,編譯,加載,調用驗證。如圖4所示。

3.2.1 驅動(dòng)程序的模塊化設計
構成FLASH驅動(dòng)程序的所有子程序,要進(jìn)行模塊化設計,必須加入兩個(gè)函數:入口函數module init()和出口函數module_exit()。在執行程序時(shí)module_init()會(huì )調用int_init cfi probe_init(void),負責初始化MTD芯片,同時(shí)這個(gè)函數還調用register_mtd_chip_driver(),將cfi_chipdrv加入至 MTD驅動(dòng)器列表chip_drvs_list中。初始化成功返回0,否則返回負值。實(shí)現代碼為:

另一個(gè)函數module_exit()執行時(shí),會(huì )調用staticvoid_exit cfi_probe_exit(void),負責清除MTD芯片驅動(dòng)工作。同時(shí)這個(gè)函數還調用unregister_mtd_chip_driver(),將cfi_chipdrv從MTD芯片驅動(dòng)器列表chip_drvs_list中刪除。實(shí)現代碼為:

|

其中:-O指定代碼優(yōu)化的級別;-D內核模塊必須按照特殊定義的參數進(jìn)行編譯,這些參數跟在選項-D后;MODULE通知頭文件要給出適當的內核模塊定義;-KERNEL-通知頭文件形成的目標代碼在內核態(tài)運行。得到的文件*.O就是一個(gè)FLASH驅動(dòng)程序的目標文件,這樣FLAsH驅動(dòng)程序編譯好。編譯好的模塊*.O放在/lib/roodules/2.4.18/misc下,然后用dep-mod-a使此模塊成為可加載模塊。 3.2.3 驅動(dòng)程序的加載 加載模塊要用到兩個(gè)命令:insmod(加載),rmmod(卸載)。加載時(shí),module_init()函數被調用,這個(gè)函數向系統設備表登記 FLAsH設備。卸載時(shí),module_exit()函數被調用,它釋放FLASH設備在系統設備表中占有的表項。注冊成功后就可以用mknod命令將 FLASH設備映射為一個(gè)特別文件,其他程序使用FLASH設備時(shí),只要對此文件進(jìn)行操作就行。Linux在/dev目錄中為每個(gè)設備建立了一個(gè)文件,用 ls-1命令列出函數返回值,若小于O,表示注冊失??;否則表示注冊成功。注冊以后,Linux將FLAsH設備名與主、次設備號聯(lián)系起來(lái)。當對 FLASH訪(fǎng)問(wèn)時(shí),Linux通過(guò)請求訪(fǎng)問(wèn)FLASH設備名得到主、次設備號;然后把此訪(fǎng)問(wèn)發(fā)送到FLASH設備驅動(dòng),FLASH驅動(dòng)再根據次設備號調用不同的函數。 3.2.4 驅動(dòng)程序的調用驗證 模塊加載到內核后,然后就要調用驗證。在Linux根目錄下有dev子目錄,這里面是節點(diǎn)名,這些結點(diǎn)是通過(guò)mknod建立的,里面有MTD字符設備節點(diǎn)和MTD塊設備節點(diǎn),通過(guò)訪(fǎng)問(wèn)這些節點(diǎn)來(lái)訪(fǎng)問(wèn)設備驅動(dòng)程序。Open一般是設備節點(diǎn)上的第一個(gè)操作,訪(fǎng)問(wèn)設備時(shí)其實(shí)就是系統調用open()函數,然后 open()函數打開(kāi)設備準備進(jìn)行I/O操作,該函數注冊進(jìn)mtd_fops結構中。 上面就是NorFLASH和NandFLASH驅動(dòng)程序架構,具體開(kāi)發(fā)驅動(dòng)程序時(shí),就要填充架構里的程序代碼,來(lái)完成驅動(dòng)程序。這個(gè)框架中有一個(gè)函數表,具體到Linux系統里,需要提供一個(gè)結構來(lái)向系統說(shuō)明FLASH驅動(dòng)程序所提供的一組入口點(diǎn),這個(gè)結構就是fop函數表。 FLASH驅動(dòng)程序運行時(shí),向內核注冊,告訴系統fop函數表是跟FLASH驅動(dòng)程序相關(guān)聯(lián)的。當用戶(hù)去訪(fǎng)問(wèn)驅動(dòng)程序時(shí),系統就告訴文件系統的管理程序,調用fop函數表就可以,然后調用函數表里的函數,完成用戶(hù)要求。當從設備來(lái)收發(fā)數據時(shí),系統不是調用read(),write()這兩個(gè)函數,fop結構里沒(méi)這兩個(gè)函數,而是要用到一個(gè)函數blk_init_queue(),這個(gè)函數向上注冊了一個(gè)請求處理函數request,對FLASH設備的讀取和發(fā)送數據,都是從請求隊列發(fā)出一個(gè)請求,請求調用請求處理函數,由請求處理函數執行具體的讀寫(xiě)操作。設計驅動(dòng)程序90%工作來(lái)完成fop函數表及re- quest函數,10%完成驅動(dòng)程序中的一些函數接口。完成了這些函數加上上面的FLASH驅動(dòng)程序架構就構成了完整的FLASH驅動(dòng)程序。
4 結 語(yǔ) 基于Samsung公司的s3c2410處理器平臺,分析和設計NorFLASH和NandFLASH的接口和驅動(dòng),詳細介紹兩種FLASH的硬件結構、性能差異、讀寫(xiě)時(shí)序、以及驅動(dòng)開(kāi)發(fā)。NorFLASH和NandFLASH因其在存儲數據和程序以及性?xún)r(jià)比方面的優(yōu)勢,占據的存儲器市場(chǎng)份額越來(lái)越多,并在嵌入式系統中得到廣泛應用。
|
評論