LonWorks現(xiàn)場(chǎng)總線設(shè)備驅(qū)動(dòng)設(shè)計(jì)與實(shí)現(xiàn)
(3) 模塊初始化與模塊卸載
本文引用地址:http://www.ex-cimer.com/article/83666.htm●LonWorks現(xiàn)場(chǎng)總線網(wǎng)卡驅(qū)動(dòng)模塊初始化,通過對(duì)init_module的實(shí)現(xiàn)來完成以下幾個(gè)任務(wù)。以字符設(shè)備類型向系統(tǒng)注冊(cè)LonWorks現(xiàn)場(chǎng)總線設(shè)備卡,同時(shí)動(dòng)態(tài)獲得其設(shè)備號(hào)。通過調(diào)用下面這個(gè)函數(shù)int register_ chrdev(unsigned int major, const char*name, struct file_operations *fops)來實(shí)現(xiàn)。這里我們使major參數(shù)為0,這樣系統(tǒng)就會(huì)動(dòng)態(tài)的分配并返回主設(shè)備號(hào)。name參數(shù)是用于標(biāo)識(shí)設(shè)備的字符串。file_ operatons傳入的是如前所述的lmdev_fops。然后,向系統(tǒng)申請(qǐng)LonWorks現(xiàn)場(chǎng)總線網(wǎng)卡的I/O端口地址。我們根據(jù)該卡上的跳線得到的I/O地址,調(diào)用系統(tǒng)提供的宏:check_region(start,n)//檢查端口地址范圍start到start+n-1是否可用,是則返回0,否則返回1。request_region(start,n,name)//用于申請(qǐng)通過以上函數(shù)檢查的地址范圍。接下來,做一些必要的系統(tǒng)日志,根據(jù)各種條件用printk向系統(tǒng)日志緩沖區(qū)寫入不同級(jí)別的信息。最后,控制對(duì)內(nèi)核資源提供的符號(hào)表輸出的符號(hào)信息(即在可加載模塊機(jī)制部分提到的模塊要注冊(cè)的服務(wù))。這里使用EX- PORT_NO_SYMBOLS使得該模塊不輸出任何符號(hào)信息。
●LonWorks現(xiàn)場(chǎng)總線網(wǎng)卡模塊卸載需要完成以下幾個(gè)任務(wù):
調(diào)用release_region(start,n)宏釋放模塊初始化時(shí)申請(qǐng)的I/O端口資源。
調(diào)用int unregister_chrdev(unsigned int major, const char*name);
向系統(tǒng)注銷該字符設(shè)備,本程序中major參數(shù)即前面注冊(cè)時(shí)動(dòng)態(tài)獲得的主設(shè)備號(hào),name與注冊(cè)時(shí)提供的name字符串相同。調(diào)用printk函數(shù),做一些必要的系統(tǒng)日志。
(4) 對(duì)file operations結(jié)構(gòu)中入口點(diǎn)的實(shí)現(xiàn)
●open和release入口點(diǎn)。
這兩個(gè)入口點(diǎn)在本模塊中被賦予的就是前面在介紹file_operations結(jié)構(gòu)時(shí)給出的lmdev_open和lmdev_ close函數(shù)指針,它們主要通過調(diào)用MOD_INC_USE_COUNT及MOD_DEC_USE _COUNT來進(jìn)行模塊計(jì)數(shù)。用計(jì)數(shù)來對(duì)LonWorks現(xiàn)場(chǎng)總線設(shè)備驅(qū)動(dòng)模塊是否正在被使用進(jìn)行控制,防止模塊正在使用時(shí)被意外卸載而導(dǎo)致核心對(duì)設(shè)備操作出現(xiàn)異常。
●對(duì)read/write入口點(diǎn)的實(shí)現(xiàn)
這個(gè)入口點(diǎn)在本模塊中被賦予的就是前面在介紹file_operations結(jié)構(gòu)時(shí)給出的lmdev_read函數(shù)指針,它是對(duì)設(shè)備操作的核心部分,根據(jù)前面描述的算法,它實(shí)現(xiàn)了如下幾個(gè)功能:
用inb_p宏,訪問硬件的狀態(tài)和數(shù)據(jù)端口,以讀取相應(yīng)的狀態(tài)和數(shù)據(jù)信息。
調(diào)用long_sleep_on_timeout(wait_queue_head_t *q, long timeout)函數(shù)把當(dāng)前進(jìn)程加入時(shí)鐘等待隊(duì)列q中,使它等待timeout時(shí)間。根據(jù)LonWorks現(xiàn)場(chǎng)總線卡的工作方式來看,這樣做可以減少輪詢時(shí)間,大大的提高了效率。
Linux分為核心空間和用戶空間,用戶空間的代碼不能直接訪問核心空間,故需調(diào)用Linux核心提供的copy_to_user(to,from,n)宏,把數(shù)據(jù)從內(nèi)核空間地址from拷貝到用戶空間地址to中。這樣,系統(tǒng)調(diào)用返回后,用戶空間的代碼就可以通過to指針來訪問相應(yīng)的數(shù)據(jù)并進(jìn)行處理了。這樣核心驅(qū)動(dòng)模塊部分的程序就完成了。
(5) 編譯內(nèi)核模塊
在程序完成后,用gcc編譯成目標(biāo)文件(不鏈接,生成*.o文件),要做到這一點(diǎn)只需在gcc命令行里加上-c參數(shù)。另外,還要加上-D_ KERNEL_ -DMODULE參數(shù)。上述程序可以這么編譯。
root# gcc -c -D-KERNEL_-DMODULE -Wall -02 lmdev.c。其中參數(shù)-Wall的功能是打印附加的警告信息。由于頭文件中的函數(shù)都是聲明為inline的,還必須給編譯器指定-O選項(xiàng)。gcc只有打開優(yōu)化選項(xiàng)后才能擴(kuò)展內(nèi)嵌函數(shù),不過它能同時(shí)接受-g和-O選項(xiàng),這樣就可以調(diào)試那些內(nèi)嵌函數(shù)的代碼了。優(yōu)化參數(shù)-O有三個(gè)級(jí)別:Ol, 02, 03,它們的優(yōu)化程度不同,優(yōu)化效果03大于02大于Ol。
編譯好模塊后的如何加載模塊,在前面已經(jīng)有所描述,這里就不再敘述了。
3.4 應(yīng)用程序開發(fā)
在對(duì)以上模塊編譯并加載后,Linux根據(jù)用戶可用mknod命令,利用動(dòng)態(tài)分配的主設(shè)備號(hào)(該設(shè)備號(hào)在用戶空間可以從/proc/devices文件中用設(shè)備名獲得)建立相應(yīng)的設(shè)備文件,并對(duì)它設(shè)置恰當(dāng)讀寫權(quán)限后,就可以在我們的應(yīng)用程序中,使用Linux的文件系統(tǒng)調(diào)用通過這個(gè)設(shè)備文件來操作LonWorks現(xiàn)場(chǎng)總線卡了。這樣做不僅使得應(yīng)用程序編程風(fēng)格更加統(tǒng)一,代碼更具魯棒性,應(yīng)用系統(tǒng)更加安全更易于維護(hù)。而且可在核心級(jí)來保證關(guān)鍵部分的實(shí)時(shí)響應(yīng),從而降低了用戶程序開發(fā)的難度。
下面是我們?yōu)檫@個(gè)驅(qū)動(dòng)開發(fā)的測(cè)試程序的一些實(shí)驗(yàn)結(jié)果,測(cè)試項(xiàng)目為:
通過智能控制器檢測(cè)LonWorks現(xiàn)場(chǎng)總線網(wǎng)絡(luò)節(jié)點(diǎn)分布狀況。測(cè)試結(jié)果如圖4所示:
圖4 LonWorks現(xiàn)場(chǎng)總線網(wǎng)絡(luò)節(jié)點(diǎn)檢測(cè)結(jié)果
結(jié)果分析:智能控制器分別檢測(cè)出1#LonWorks現(xiàn)場(chǎng)總線通道6號(hào)節(jié)點(diǎn)有一個(gè)開關(guān)量前端(LM1202),2#LonWorks現(xiàn)場(chǎng)總線通道11號(hào)節(jié)點(diǎn)有一模擬量前端(LM1101)。智能控制器檢測(cè)結(jié)果與實(shí)際LonWorks現(xiàn)場(chǎng)總線網(wǎng)絡(luò)節(jié)點(diǎn)分布一致,這說明LonWorks現(xiàn)場(chǎng)總線設(shè)備驅(qū)動(dòng)程序正確運(yùn)行。到此,LonWorks現(xiàn)場(chǎng)總線設(shè)備驅(qū)動(dòng)開發(fā)完成。
4 結(jié)束語
本文在研究了基于嵌入式Linux平臺(tái)的驅(qū)動(dòng)程序開發(fā)機(jī)制后,研究實(shí)現(xiàn)了嵌入式Linux環(huán)境下的LonWorks現(xiàn)場(chǎng)總線網(wǎng)卡的設(shè)備驅(qū)動(dòng)。應(yīng)用實(shí)現(xiàn)結(jié)果表明,該設(shè)備驅(qū)動(dòng)運(yùn)轉(zhuǎn)正常、性能可靠。這一研究課題的成功的解決對(duì)于拓寬LonWorks現(xiàn)場(chǎng)總線應(yīng)用領(lǐng)域具有借鑒和推廣意義。
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)
評(píng)論