亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        嵌入式Linux的設(shè)備驅(qū)動研究與開發(fā)

        2007-01-01 00:00:00茍培培郭麥成
        計算機時代 2007年5期

        摘要:首先介紹了嵌入式Linux環(huán)境下設(shè)備驅(qū)動程序的開發(fā)流程,詳細描述了Linux設(shè)備驅(qū)動程序的體系結(jié)構(gòu)和Linux設(shè)備文件的概念。然后通過一個例子描述了如何設(shè)計和編寫Linux設(shè)備驅(qū)動程序,并解釋了其中的核心代碼。最后構(gòu)建一個Glade工程來調(diào)用這個設(shè)備驅(qū)動程序,完成測試工作。

        關(guān)鍵詞:嵌入式Linux;設(shè)備文件;設(shè)備驅(qū)動;Glade

        0 引言

        Linux是開放源代碼的操作系統(tǒng),由于其高效穩(wěn)定、執(zhí)行速度快、實現(xiàn)了真正的多任務(wù)、多用戶環(huán)境、強大的網(wǎng)絡(luò)功能、較好的可裁減性與移植性等特點,在嵌入式系統(tǒng)領(lǐng)域獲得了飛速發(fā)展。針對ARM體系結(jié)構(gòu)CPU開發(fā)的,具有MMU功能的嵌入式Linux操作系統(tǒng)無疑是ARM平臺上操作系統(tǒng)的最佳選擇。本文主要研究了在Linux下開發(fā)驅(qū)動程序并構(gòu)建一個GUI程序來使用這個驅(qū)動程序的一般流程。

        1 Linux設(shè)備驅(qū)動程序

        Linux支持三類硬件設(shè)備:字符設(shè)備、塊設(shè)備和網(wǎng)絡(luò)設(shè)備。字符設(shè)備是指無須緩存直接按字節(jié)讀寫的設(shè)備。塊設(shè)備以塊為單位進行讀寫,能夠進行隨機訪問。網(wǎng)絡(luò)設(shè)備在Linux里有專門的處理,它沒有被映射到文件系統(tǒng)的設(shè)備節(jié)點,對它的訪問采用socket機制。字符設(shè)備與塊設(shè)備的主要區(qū)別是:在對字符設(shè)備發(fā)出讀/寫請求時,實際的硬件I/O一般緊接著發(fā)生;塊設(shè)備是利用一塊系統(tǒng)內(nèi)存作緩沖區(qū)來進行實際的I/O操作。

        圖1 設(shè)備驅(qū)動流程

        在Linux中,幾乎所有的內(nèi)容都是文件,對設(shè)備驅(qū)動的訪問也是以文件操作的方式實現(xiàn)。無論是字符設(shè)備還是塊設(shè)備,用戶對沒備的操作都是通過虛擬文件系統(tǒng)(VFS)轉(zhuǎn)化為設(shè)備驅(qū)動與硬件操作例程的交互(見圖1)。即使是訪問網(wǎng)絡(luò)設(shè)備的socket接口,也是通過VFS實現(xiàn)的。Linux通過VFS為用戶提供了一個統(tǒng)一的設(shè)備訪問接口,使用戶能夠透明地訪問設(shè)備驅(qū)動程序。所有的硬件設(shè)備都可以使用和操作系統(tǒng)調(diào)用接口來打開、關(guān)閉、讀寫和I/O控制,而驅(qū)動程序的主要任務(wù)就是實現(xiàn)這些系統(tǒng)調(diào)用函數(shù)。Linux系統(tǒng)中的所有硬件設(shè)備都使用一種特殊的設(shè)備文件來表示。每個設(shè)備文件都有兩個設(shè)備號:一個是主設(shè)備號,它用來標(biāo)識該設(shè)備的種類,也標(biāo)識該設(shè)備使用的驅(qū)動程序;另一個是次設(shè)備號,用來標(biāo)識使用同一設(shè)備驅(qū)動程序的不同硬件設(shè)備。

        實現(xiàn)一個嵌入式Linux設(shè)備驅(qū)動的大致流程如下:

        (1)定義主、次設(shè)備號;也可以動態(tài)獲取。

        (2)實現(xiàn)驅(qū)動初始化和清除函數(shù),如果驅(qū)動程序采用模塊方式,則要實現(xiàn)模塊初始化和清除函數(shù)。

        (3)設(shè)計所要實現(xiàn)的文件操作,定義file_operations結(jié)構(gòu)。

        (4)實現(xiàn)所需的文件操作調(diào)用,如read、write等。

        (5)實現(xiàn)中斷服務(wù)函數(shù),并用request_irq向內(nèi)核注冊。中斷并不是每個設(shè)備驅(qū)動所需要。

        (6)將驅(qū)動編譯到內(nèi)核或編譯成模塊,用insmod命令加載。

        (7)生成設(shè)備節(jié)點文件。

        下面以一個簡單的例子來說明設(shè)備驅(qū)動程序的結(jié)構(gòu),這個驅(qū)動程序用來控制目標(biāo)板上的一組LED燈。led_fops結(jié)構(gòu)體定義了該設(shè)備需要的操作接口。它的成員全部是函數(shù)指針,所以實質(zhì)上就是函數(shù)跳轉(zhuǎn)表。

        struct file_operations led_fops={

        open:led_open,

        /*打開設(shè)備操作*/

        read:led_read,

        /*讀設(shè)備操作*/

        write:led_write,

        /*寫設(shè)備操作*/

        ioctl:led_ioctl,

        /*控制模塊的設(shè)置*/

        release:led_release /*釋放設(shè)備操作*/

        }:

        ssize_t led_read(struct nIe*flip,char*Putbuf,size_t length,

        loff__t*f_pos)

        {unsigned short BottonStatus;

        unsigned char Bottontmp=0;

        int i;

        BottonStatus=(KEY_CSOxff);/*獲取當(dāng)前8個按鍵的狀態(tài)*/

        for(i=0:i<8:++i)

        {if(((BottonStatus>>i)&1)==0)

        Bottontmp=i+1;

        }

        copy_to user(Putbuf,Bottontmp,length);

        /*將內(nèi)核空間的數(shù)據(jù)復(fù)制到用戶空間*/

        return length;

        }

        ssize_t led_write(struct file *filp,const char *Getbuf,

        size_t length,loff-t *f_pos)

        {int num;

        unsigned char UsrWantLed;

        copy_from_user(UsrWantLed,Getbuf,length);

        /*將用戶空間的寫入到設(shè)備文件的內(nèi)容傳送到內(nèi)核空間*/

        num=((UsrWantLed)0xff);

        LED_CS=-(1<<(num-1));

        /*通過對LED_CS地址賦值來控制LED的亮滅*/

        return(0);

        }

        int led_ioctl(struct inode *inode,struct file*filp,

        unsigned int cmd,unsigned long arg)

        {switch(cmd)/*利用cmd和arg參數(shù)可以完成有些復(fù)雜的I/O

        操作*/

        { case LED_SHOW:

        {if(arg)

        led_off_on();

        break;

        }

        }return 0:

        }

        static int inn keypad_init(void)

        {int result;

        result=register_chrdev(Led_MAJOR.“l(fā)ed”,led_fops);

        /*這個函數(shù)是向內(nèi)核注冊設(shè)備,Led_MAJOR是驅(qū)動的主設(shè)備

        號,led是驅(qū)動名,led_fops是驅(qū)動所執(zhí)行的操作*/

        printk(“%s%sinitialized.\n”,KEYPAD_NAME,KEYPAD_VERSION);

        return 0;

        }

        static void_exit keypad_exit(void)

        {unregister_chrdev(Led_MAJOR,“l(fā)ed”);/*向內(nèi)核注銷設(shè)備*/

        led_off_on();

        }

        module_init(keypad_init);

        module_exit(keypad_exit);

        module_init()和module_exit()這對宏是對程序模塊的初始化和退出函數(shù)名稱進行記錄。它能顯式地命名模塊的注冊和注銷函數(shù)并保證內(nèi)核中驅(qū)動名的惟一性。

        2 嵌入式LInux的GUI

        Tiny-X是由XFree86核心小組的成員Keith Packard一手設(shè)計的。它能夠在配有IMB以下內(nèi)存的系統(tǒng)上,建立起標(biāo)準(zhǔn)的X系統(tǒng),是一個性能相當(dāng)出色并且免費的嵌入式圖形界面GUI。在嵌入式系統(tǒng)中,使用Tiny-X圖形界面開發(fā)產(chǎn)品,上層的應(yīng)用程序編寫將會很方便。可以通過GTK的集成開發(fā)環(huán)境——Glade完成界面布局并生成原始代碼(界面圖如圖2),再通過文本編輯工具添加事件響應(yīng)程序。 在程序控制硬件設(shè)備之前要打開設(shè)備文件,所以要在執(zhí)行g(shù)tk_main()前調(diào)用設(shè)備打開函數(shù)。這個函數(shù)主要用于打開設(shè)備文件并獲得主設(shè)備號。關(guān)鍵代碼如下: int fd_keypad;

        static char*dev_keypad=“/dev/keypad”;

        fd_keypad=open(dev_keypad,O_RDWR);

        return fd_keypad;

        圖2 Glade工程界面

        然后對每個button添加click響應(yīng)事件。對buttonl的click響應(yīng)事件編寫控制函數(shù)如下:

        write(fd_keypad,(const char*)lednum,sizeof((const char)

        lednum));

        進入該工程目錄,使用命令:#./autogen.sh配置相應(yīng)的程序以及生成所需的Makefiles文件,然后修改Makefile文件,把自行編寫的C文件添加到編譯表中,主要是在參數(shù)Led_SOURCE和Led_OBJECTS中。然后執(zhí)行下面的命令:

        #exportCC=arm-linux-gcc

        /*通過設(shè)置環(huán)境變量.指定編譯工具為arm-linux-gcc*/

        #./configure host=arm build=i686

        target=armwith-gtk-exec-prefix=usr/Iocal/arm-linux

        /*設(shè)置生成二進制文件的工作環(huán)境為arm,并指定Linux內(nèi)核所

        在的目錄*/

        #make

        /*在/src編譯生成二進制代碼,下載到開發(fā)平臺上即可運行*/

        用戶程序的開發(fā)調(diào)試主要有兩種方式:一是在主機上編寫用戶程序,將其直接編譯入內(nèi)核,整體下載入目標(biāo)板,再進行調(diào)試;二是在主機上通過交叉編譯器編譯用戶程序,生成能在目標(biāo)板上執(zhí)行的二進制文件,通過串口或網(wǎng)絡(luò)將用戶程序下載到目標(biāo)板上,進行調(diào)試。第一種方式由于每次更改程序都需要編譯入內(nèi)核、下載到目標(biāo)板,顯得靈活性較低,且十分繁瑣。而第二種開發(fā)方式每次只用下載用戶程序即可調(diào)試,非常方便,因此筆者在驅(qū)動程序開發(fā)中使用了第二種方式。

        3 結(jié)束語

        在Linux中,系統(tǒng)調(diào)用是操作系統(tǒng)內(nèi)核和應(yīng)用程序之間的接口,而設(shè)備驅(qū)動程序就是操作系統(tǒng)內(nèi)核和機器硬件之間的接口。內(nèi)核利用驅(qū)動程序的接口完成對設(shè)備的初始化和釋放,在系統(tǒng)內(nèi)核和硬件、設(shè)備文件和應(yīng)用程序之間傳送數(shù)據(jù),并時刻檢測和處理設(shè)備出現(xiàn)的錯誤。當(dāng)操作系統(tǒng)對設(shè)備進行操作時,會調(diào)用驅(qū)動程序注冊的file_operations結(jié)構(gòu)中的函數(shù)指針,找到相應(yīng)的功能函數(shù)。

        注:本文中所涉及到的圖表、注解、公式等內(nèi)容請以PDF格式閱讀原文。

        国产精品三级自产拍av| a级毛片毛片免费观看久潮喷| 色诱久久av| 天堂av在线一区二区| 亚洲一区二区三区偷拍视频| 欧美性猛交xxxx三人| 欧美午夜一区二区福利视频| 久久久久无码精品国| 国产一区二区三区在线男友| 精品无码国产自产拍在线观看| 欧美变态口味重另类在线视频| 国产成人亚洲综合小说区| 精品人妻av一区二区三区四区| 午夜免费视频| 婷婷四房播播| 精品日本韩国一区二区三区| 亚洲av无一区二区三区久久蜜桃| 国产l精品国产亚洲区久久| 日本欧美国产精品| 一区二区视频资源在线观看| 亚洲一区二区三区中国| 久久久久久好爽爽久久| 无码在线观看123| 亚洲人成精品久久熟女| av无码国产在线看免费网站| 特级毛片a级毛片在线播放www| 日本女优在线观看一区二区三区| 中文字幕乱码熟女人妻在线| 亚洲h在线播放在线观看h| 国产精品无码专区综合网| 麻豆成年人视频在线观看| 国产电影无码午夜在线播放| 国产亚洲精品久久久久久久久动漫 | 亚洲中文字幕精品久久久| 无码a级毛片免费视频内谢| 品色堂永远的免费论坛| 少妇被爽到自拍高潮在线观看| 亚洲tv精品一区二区三区| 亚洲av永久无码精品国产精品| 91久久综合精品国产丝袜长腿| 青青草激情视频在线播放|