鄭雯玉,陳軍樺,吳志勇,趙 磊,于 瀟
(山東理工大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,山東 淄博 255049)
嵌入式系統(tǒng)強(qiáng)調(diào)軟件和硬件的協(xié)同性、整合性和可裁剪性,以滿足系統(tǒng)對(duì)功能、成本、體積及功耗等方面的要求[1].通常,嵌入式系統(tǒng)要求嵌入式操作系統(tǒng)具有更高的可靠性和實(shí)時(shí)性.PC/104是與PC/AT兼容的專門(mén)為嵌入式系統(tǒng)定義的一種總線標(biāo)準(zhǔn),它具有結(jié)構(gòu)緊湊、自堆棧、功耗低等優(yōu)點(diǎn),在工業(yè)控制領(lǐng)域得到了廣泛的應(yīng)用.本文研究嵌入式Linux操作系統(tǒng)在PC/104環(huán)境下的應(yīng)用技術(shù),結(jié)合數(shù)據(jù)采集卡驅(qū)動(dòng)程序的設(shè)計(jì)過(guò)程,討論了硬件設(shè)備驅(qū)動(dòng)程序的設(shè)計(jì)方法及編程技術(shù),并給出實(shí)驗(yàn)結(jié)果.
___實(shí)驗(yàn)系統(tǒng)地硬件結(jié)構(gòu)分為上位機(jī)和下位機(jī)兩部分.上位機(jī)是標(biāo)準(zhǔn)的個(gè)人計(jì)算機(jī),下位機(jī)是PC/104標(biāo)準(zhǔn)的嵌入式計(jì)算機(jī)系統(tǒng),該嵌入式系統(tǒng)由嵌入式系統(tǒng)主板和數(shù)據(jù)采集模塊(Diamond-MM-32-AT)構(gòu)成.嵌入式系統(tǒng)的外部存儲(chǔ)器是一張CF卡(Compact Flash),主板上配備了CF卡的卡座.上位機(jī)和下位機(jī)通過(guò)網(wǎng)線相互連接.系統(tǒng)框架如圖1所示.
圖1 系統(tǒng)框架圖
嵌入式系統(tǒng)主板采用盛博協(xié)同嵌入式計(jì)算機(jī)公司生產(chǎn)的SCM/LX-3160,它是一款高性能的“ALL IN ONE”P(pán)C/104 CPU模塊.該模塊采用AMD Geode LX 800 CPU,工作頻率500M Hz;具有128KB一級(jí)高速緩存和128KB二級(jí)高速緩存;在板表貼256M RAM;VGA控制器支持CRT輸出;兩個(gè)以太網(wǎng)接口;一個(gè)CF卡接口;具有一個(gè)與8259A等同的中斷控制器.
數(shù)據(jù)采集模塊采用美國(guó)鉆石公司生產(chǎn)的Diamond-MM-32-AT,帶有16位精度的32路模擬輸入通道,輸入信號(hào)幅值范圍可調(diào),最高采樣頻率為200kHz,板載FIFO緩沖區(qū)1024字節(jié),具有自動(dòng)校準(zhǔn)功能.
嵌入式系統(tǒng)軟件開(kāi)發(fā)環(huán)境包括上位機(jī)軟件開(kāi)發(fā)環(huán)境和下位機(jī)軟件開(kāi)發(fā)環(huán)境.上位機(jī)的操作系統(tǒng)是Ubuntu 9.03,程序編輯器使用Geany,程序編譯器使用gcc 4.3.3.Linux操作系統(tǒng)內(nèi)核的定制裁剪、Diamond-MM-32-AT在Linux內(nèi)核之上的驅(qū)動(dòng)程序的編寫(xiě)和編譯在上位機(jī)進(jìn)行.上位機(jī)編譯好的驅(qū)動(dòng)程序通過(guò)NFS(Network File System,網(wǎng)絡(luò)文件系統(tǒng))傳輸給下位機(jī)的CF卡.下位機(jī)軟件系統(tǒng)環(huán)境的構(gòu)建,包括Linux內(nèi)核的裁剪與移植、根文件系統(tǒng)的搭建和啟動(dòng)引導(dǎo)程序的安裝[2].簡(jiǎn)要構(gòu)建過(guò)程如下:
(1)將CF卡分區(qū)并格式化為ext3文件系統(tǒng),然后安裝引導(dǎo)加載器grub V0.97.
(2)編譯linux內(nèi)核.所用內(nèi)核版本為2.6.31.配置過(guò)程中先禁用模塊支持,盡可能根據(jù)硬件最小化配置,配置為可搶占式內(nèi)核以提高實(shí)時(shí)性,最后啟用模塊支持并保存配置.執(zhí)行make bzImage命令,編譯生成內(nèi)核鏡像文件bzImage.拷貝bzImage文件到CF卡上/boot目錄下.編譯后的內(nèi)核源碼樹(shù)原樣保留,將用于驅(qū)動(dòng)編譯.在后面的驅(qū)動(dòng)程序的makefile中,內(nèi)核源碼樹(shù)路徑應(yīng)該為編譯內(nèi)核時(shí)的源碼樹(shù)路徑.[3]
(3)根文件系統(tǒng)采用busybox 1.15.1.為提高運(yùn)行速度和避免手動(dòng)添加動(dòng)態(tài)庫(kù)的麻煩,將busybox編譯成一個(gè)靜態(tài)文件,而不使用共享庫(kù).
(4)建立基本設(shè)備文件/dev/null、/dev/zero、/dev/console,并編寫(xiě)啟動(dòng)配置文件.必需的三個(gè)配置文 件 是/etc/inittab、/etc/init.d/rcS和/boot/grub/menu.lst.其中g(shù)rub配置文件menu.lst中,使用“root=/dev/hda1”方式直接引導(dǎo)CF卡上的根文件系統(tǒng).
至此,下位機(jī)的軟件環(huán)境構(gòu)建過(guò)程完畢.將CF卡插入嵌入式主板SCM/LX-3160的CF卡座.開(kāi)啟下位機(jī)電源,下位機(jī)系統(tǒng)開(kāi)始運(yùn)行.本系統(tǒng)各組成部分所占用空間見(jiàn)表1.
表1 系統(tǒng)各部分體積
硬件設(shè)備驅(qū)動(dòng)程序的核心功能有兩點(diǎn):一是對(duì)硬件設(shè)備端口的操作;二是對(duì)硬件設(shè)備中斷的控制和響應(yīng).設(shè)備驅(qū)動(dòng)程序是Linux內(nèi)核與硬件之間的接口,并對(duì)內(nèi)核屏蔽了硬件設(shè)備的細(xì)節(jié).Linux把所有的設(shè)備當(dāng)作一種特殊的文件(設(shè)備文件)來(lái)處理,所以應(yīng)用程序可以像操作普通文件一樣操作硬件設(shè)備.作為內(nèi)核模塊的一部分,驅(qū)動(dòng)程序主要完成以下功能:
(1)硬件設(shè)備的初始化和關(guān)閉.
(2)從硬件設(shè)備端口讀取數(shù)據(jù),以及將內(nèi)核數(shù)據(jù)傳送到硬件設(shè)備端口.
(3)把來(lái)自用戶程序的設(shè)置和數(shù)據(jù)傳送給設(shè)備文件,以及將數(shù)據(jù)從設(shè)備文件讀出.
(4)控制和響應(yīng)外部中斷.
(5)檢測(cè)并處理設(shè)備運(yùn)行時(shí)出現(xiàn)的錯(cuò)誤[4].
Diamond-MM-32-AT工作模式定義在頭文件dmm32.h中,該頭文件同時(shí)也定義了用于在用戶空間和內(nèi)核空間傳遞參數(shù)的結(jié)構(gòu)體.因此,用戶應(yīng)用程序必須包含該頭文件.該模塊模擬量采集的三種工作模式定義如下:
DMM32_IOC_AD_SINGLE 是最簡(jiǎn)單的A/D采樣模式,以軟觸發(fā)方式啟動(dòng)A/D轉(zhuǎn)換,讀取數(shù)據(jù)并保存到用戶空間后,緊接著啟動(dòng)下一次A/D轉(zhuǎn)換,直到讀取到用戶程序所要求的數(shù)據(jù)量后退出.無(wú)法以精確的頻率采樣.
DMM32_IOC_AD_CLKINT 用板載計(jì)數(shù)器82c54的輸出脈沖觸發(fā)中斷,中斷處理例程軟觸發(fā)啟動(dòng)A/D轉(zhuǎn)換并將數(shù)據(jù)保存到一個(gè)全局?jǐn)?shù)組buffer中,待所需數(shù)據(jù)全部采集完畢后禁用中斷并喚醒已經(jīng)休眠的讀進(jìn)程read(),read()將內(nèi)核空間buffer里的數(shù)據(jù)讀入用戶空間后退出.
DMM32_IOC_AD_FIFOINT 用板載計(jì)數(shù)器82c54的輸出作為A/D轉(zhuǎn)換的啟動(dòng)信號(hào),轉(zhuǎn)換所得數(shù)據(jù)由硬件自行寫(xiě)入板載FIFO,待FIFO中的數(shù)據(jù)量到達(dá)設(shè)定閾值時(shí)觸發(fā)硬件中斷.中斷處理例程將從FIFO中讀取設(shè)定數(shù)量的數(shù)據(jù),并送入一個(gè)循環(huán)緩沖區(qū)內(nèi),同時(shí)喚醒已經(jīng)休眠的讀進(jìn)程read();read()從循環(huán)緩沖區(qū)中讀取用戶指定的數(shù)據(jù)量,并寫(xiě)入用戶空間.在用戶應(yīng)用程序中不停地調(diào)用read()即可以得到連續(xù)的數(shù)據(jù)流.
3.3.1 添加頭文件以及系統(tǒng)宏
#include"dmm32.h"http://用戶編寫(xiě)的頭文件,包括模式(即ioctl命令字)定義和用戶所需參數(shù)結(jié)構(gòu)體定義
#include"dmm32_buffer.h"http://用戶自定義緩沖區(qū),在DMM32_IOC_AD_FIFOINT模式時(shí),將FIFO中的數(shù)據(jù)讀入用戶空間,使用該緩沖區(qū)以防止數(shù)據(jù)丟失
MODULE_LICENSE("Dual BSD/GPL");//告訴內(nèi)核該模塊使用自由許可證,如果沒(méi)有這個(gè)聲明,系統(tǒng)在加載該模塊時(shí)會(huì)警告
驅(qū)動(dòng)程序還需要操作方式的控制參數(shù),這些參數(shù)可在insmod命令裝載模塊時(shí)賦值.參數(shù)必須使用module_param宏來(lái)聲明,使其對(duì)insmod命令可見(jiàn).
module_param(dmm32_irq_id,int,S_IRUGO);//設(shè)備中斷號(hào)
module_param(dmm32_major,int,S_IRUGO);//主設(shè)備號(hào)
module_param(dmm32_minor,int,S_IRUGO);//次設(shè)備號(hào)
module_param(dmm32_nr_devs,int,S_IRUGO;//設(shè)備數(shù)量
module_param(dmm32_fifo_depth,int,S_IRUGO);//FIFO深度
3.3.2 全局變量
dmm32.c中的全局變量保存主設(shè)備號(hào)、次設(shè)備號(hào)、設(shè)備中斷號(hào)以及FIFO深度等信息.
3.3.3 設(shè)備的初始化及釋放
module_init(dmm32_init);//宏,指定dmm32_init為用戶加載模塊時(shí)調(diào)用的初始化函數(shù)
module_exit(dmm32_exit);//宏,指定dmm32_exit為用戶卸載模塊時(shí)調(diào)用的清理函數(shù)
以上兩個(gè)宏都定義在<linux/module.h>中.
3.3.4 對(duì)設(shè)備文件的主要操作
對(duì)設(shè)備文件的打開(kāi)、關(guān)閉、讀、寫(xiě)以及控制等的操作通過(guò)file_operations結(jié)構(gòu)體向系統(tǒng)說(shuō)明,該結(jié)構(gòu)體定義如下.
圖2 應(yīng)用程序流程圖
以下是幾個(gè)設(shè)備文件的重要操作:
用戶應(yīng)用程序采用DMM32_IOC_AD_FIFOINT工作模式,此模式下FIFO深度達(dá)到512字節(jié)時(shí)觸發(fā)硬件中斷.使用一個(gè)循環(huán)隊(duì)列作為緩存,并將該緩存的定義和有關(guān)操作放在頭文件buffer.h中.模擬信號(hào)輸入通道0外接1kHz的正弦波信號(hào),電壓范圍為-5V~+5V,采樣頻率為200kHz.程序流程如圖2所示.
應(yīng)用程序?qū)?shù)據(jù)保存到一個(gè)外部文件,文件數(shù)據(jù)達(dá)到4MB時(shí)程序停止,程序運(yùn)行歷時(shí)約10s.程序停止后,打開(kāi)保存數(shù)據(jù)的外部文件,每個(gè)采樣點(diǎn)數(shù)據(jù)占用2字節(jié),每個(gè)正弦周期200個(gè)采樣點(diǎn)的電壓值同被測(cè)信號(hào)的幅值完全吻合,整個(gè)外部文件共計(jì)104個(gè)周期的2M個(gè)采樣數(shù)據(jù).此應(yīng)用程序成功調(diào)用Diamond-MM-32-AT設(shè)備驅(qū)動(dòng)程序模塊,程序運(yùn)行過(guò)程中無(wú)內(nèi)核異?;蚓?多次連續(xù)運(yùn)行亦穩(wěn)定.表明在PC/104環(huán)境下,所開(kāi)發(fā)基于Linux操作系統(tǒng)的硬件設(shè)備驅(qū)動(dòng)程序運(yùn)行可靠.
在PC/104規(guī)范的硬件環(huán)境下構(gòu)建嵌入式Linux操作系統(tǒng)的方法,研究了基于嵌入式Linux操作系統(tǒng)的硬件設(shè)備驅(qū)動(dòng)程序基本結(jié)構(gòu)及設(shè)計(jì)方法,并給出了一款高性能數(shù)據(jù)采集卡的驅(qū)動(dòng)程序?qū)嵗?通過(guò)用戶應(yīng)用程序?qū)︱?qū)動(dòng)程序的實(shí)際調(diào)用實(shí)驗(yàn),驗(yàn)證了驅(qū)動(dòng)程序的可行性和穩(wěn)定性,為進(jìn)一步研究嵌入式Linux環(huán)境下更復(fù)雜的硬件設(shè)備操作奠定了堅(jiān)實(shí)的基礎(chǔ).
[1]李善平,劉丈峰,王煥龍,等.Linux與嵌入式系統(tǒng)[M].北京:清華大學(xué)出版社,2003.
[2]許德新,談?wù)穹?胡文彬,等.嵌入式Linux在PC104平臺(tái)上的構(gòu)建與實(shí)現(xiàn)[J].應(yīng)用科技,2006,33(10):35-37.
[3]王忠凱,趙磊,郭浩,等.FAT文件系統(tǒng)在UC/OS-Ⅱ內(nèi)核上的應(yīng)用[J].山東理工大學(xué)學(xué)報(bào)(自然科學(xué)版).2009.23(5):60-65.
[4]何世烈,陳健.基于嵌入式Linux的設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用.2007,1(7):65-67.
[5]JONA THANCORBET,ALESSANDRORUBINI,G REG KROAH-HARTMAN.Linux設(shè)備驅(qū)動(dòng)程序[M].魏永明,耿岳,鐘書(shū)毅,譯.3版.北京:中國(guó)電力出版社,2005.
山東理工大學(xué)學(xué)報(bào)(自然科學(xué)版)2010年3期