羅東華,李海崗,王忠民
(1.山東傳媒職業(yè)學(xué)院信息工程系,山東濟(jì)南250200;2.72946部隊(duì),山東淄博255000;3.山東省科學(xué)院自動(dòng)化研究所,山東濟(jì)南250014)
隨著計(jì)算機(jī)控制技術(shù)的不斷發(fā)展,嵌入式系統(tǒng)已經(jīng)廣泛滲透到儀器儀表、工業(yè)控制等各個(gè)領(lǐng)域,成為備受關(guān)注的熱點(diǎn)[1].而Linux作為一個(gè)源碼公開(kāi)、結(jié)構(gòu)清晰、功能強(qiáng)大,且穩(wěn)定可靠的操作系統(tǒng),在嵌入式系統(tǒng)中占據(jù)主流位置[2].在工業(yè)控制與監(jiān)測(cè)領(lǐng)域,溫度監(jiān)控是一項(xiàng)必不可少的功能模塊.文中介紹了基于模擬量傳輸?shù)臏囟葌鞲衅髟贚inux系統(tǒng)下驅(qū)動(dòng)程序的開(kāi)發(fā)方法,闡述了可動(dòng)態(tài)加載的設(shè)備驅(qū)動(dòng)程序的配置、設(shè)計(jì)和調(diào)試步驟.
驅(qū)動(dòng)程序的目的是驅(qū)動(dòng)硬件正常工作,所以編寫(xiě)驅(qū)動(dòng)程序要針對(duì)特定的硬件來(lái)進(jìn)行.Linux設(shè)備驅(qū)動(dòng)程序是為特定的硬件提供給應(yīng)用程序的一組標(biāo)準(zhǔn)化接口,它隱藏了設(shè)備工作的細(xì)節(jié).設(shè)備驅(qū)動(dòng)程序從總體上看分為兩部分:驅(qū)動(dòng)程序與Linux內(nèi)核的接口、驅(qū)動(dòng)程序與設(shè)備的接口[3].其代碼結(jié)構(gòu)大致可以分為如下幾個(gè)部分:驅(qū)動(dòng)程序的注冊(cè)與注銷(xiāo)、設(shè)備的打開(kāi)與釋放、設(shè)備的讀寫(xiě)操作、設(shè)備的控制操作、設(shè)備的中斷和輪詢(xún)處理[4].
Liunx系統(tǒng)的設(shè)備分為三種類(lèi)型:字符設(shè)備、塊設(shè)備和網(wǎng)絡(luò)設(shè)備.基于模數(shù)轉(zhuǎn)換模塊(ADC)的溫度傳感器屬于字符設(shè)備,其實(shí)現(xiàn)流程包括設(shè)備的注冊(cè),文件操作結(jié)構(gòu)體(file_operations)賦值,以及編寫(xiě)文件操作結(jié)構(gòu)體中用到的函數(shù).模數(shù)轉(zhuǎn)換模塊功能非常簡(jiǎn)單,所以在文件操作結(jié)構(gòu)體中只需要設(shè)置打開(kāi)函數(shù)(open)、釋放函數(shù)(release)以及讀取函數(shù)(read)的指針,相應(yīng)的僅需要實(shí)現(xiàn)open函數(shù)、release函數(shù)和read函數(shù).
open函數(shù)提供給驅(qū)動(dòng)程序以初始化的能力,主要工作內(nèi)容如下:
1)檢查設(shè)備特定的錯(cuò)誤(諸如設(shè)備未就緒或類(lèi)似的硬件問(wèn)題).
2)如果設(shè)備是首次打開(kāi),則對(duì)其進(jìn)行初始化.
3)如果有必要,更新file_operations指針[5].在Linux系統(tǒng)用戶(hù)空間的應(yīng)用程序中,如果要打開(kāi)溫度傳感器設(shè)備,需要調(diào)用此內(nèi)核函數(shù)(device_open).另外,還可以在此函數(shù)中使用一個(gè)全局變量,記錄設(shè)備打開(kāi)次數(shù),以標(biāo)識(shí)設(shè)備是否為第一次打開(kāi).
release函數(shù)作用與open正好相反,它釋放由open分配的所有資源,并關(guān)閉設(shè)備.同樣的,記錄設(shè)備打開(kāi)次數(shù)的全局變量需要在此函數(shù)中進(jìn)行減操作.
read函數(shù)的作用是拷貝數(shù)據(jù)到應(yīng)用程序空間,其表達(dá)式為:
static ssize_t device_read(struct file*file,char*buffer,size_t length,loff_t*offset)
參數(shù)file是文件指針,參數(shù)buffer是指向用戶(hù)空間的緩沖區(qū),參數(shù)length是數(shù)據(jù)長(zhǎng)度,參數(shù)loff_t是指向長(zhǎng)偏移量類(lèi)型(long offset type)對(duì)象的指針.該函數(shù)內(nèi)部的程序流程圖如圖1所示.
圖1 read函數(shù)程序流程圖
read函數(shù)還檢查用戶(hù)空間的指針是否有效,如果指針無(wú)效,就不會(huì)進(jìn)行拷貝;如果在拷貝過(guò)程中遇到無(wú)效地址,則僅僅會(huì)復(fù)制部分?jǐn)?shù)據(jù).
驅(qū)動(dòng)程序編寫(xiě)完成后,還需要建立該程序的makefile文件,代碼如下:
其中,obj-m是生成目標(biāo)文件的名稱(chēng),KERNELDIR是內(nèi)核路徑.
有了adcdriver.c和makefile文件,使用make命令即可得到驅(qū)動(dòng)文件adcdriver.ko.然后使用insmod命令動(dòng)態(tài)加載驅(qū)動(dòng)程序,基于模數(shù)轉(zhuǎn)換模塊的溫度傳感器驅(qū)動(dòng)就加載進(jìn)了Linux內(nèi)核中.
為了測(cè)試該驅(qū)動(dòng)程序,需要編寫(xiě)Linux系統(tǒng)用戶(hù)空間下的應(yīng)用程序adc.c,程序流程圖如圖2所示.
圖2 應(yīng)用程序adc.c的流程圖
在Linux的用戶(hù)空間運(yùn)行此應(yīng)用程序,能夠得到嵌入式處理器S3C2440模數(shù)轉(zhuǎn)換模塊的有效數(shù)據(jù),根據(jù)溫度傳感器模擬量數(shù)值與溫度的對(duì)應(yīng)關(guān)系,即可獲取外部環(huán)境溫度.
文中介紹了Linux操作系統(tǒng)下驅(qū)動(dòng)程序的基本原理和框架,編寫(xiě)了基于模數(shù)轉(zhuǎn)換模塊(ADC)的溫度傳感器的驅(qū)動(dòng)程序和應(yīng)用程序,并給出實(shí)際項(xiàng)目中的操作步驟,對(duì)實(shí)現(xiàn)同類(lèi)芯片的其他硬件驅(qū)動(dòng)有很好的參考價(jià)值.
[1] 張威,黃沖.嵌入式Linux設(shè)備驅(qū)動(dòng)的設(shè)計(jì)方法研究[J] .江西師范大學(xué)學(xué)報(bào):自然科學(xué)版,2007,31(4):391-393.
[2] 巍鶩,張煥強(qiáng),方貴明.基于Linux的USB驅(qū)動(dòng)程序?qū)崿F(xiàn)[J] .計(jì)算機(jī)應(yīng)用,2002,22(8):17-19.
[3] 李亞峰,歐文盛.ARM嵌入式Linux系統(tǒng)開(kāi)發(fā)從入門(mén)到精通[M] .北京:清華大學(xué)出版社,2007.
[4] 陳濤,余學(xué)才,朱良銷(xiāo).信號(hào)發(fā)生模塊的Linux驅(qū)動(dòng)程序設(shè)計(jì)[J] .化工自動(dòng)化及儀表,2010,37(11):88-91.
[5] Corbet J,Rubini A,Hartman G K.Linux設(shè)備驅(qū)動(dòng)程序[M] .北京:中國(guó)電力出版社,2006.