![第6講 Linux字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)_第1頁(yè)](http://file4.renrendoc.com/view11/M01/28/20/wKhkGWX7YbiAZWRKAAJkZJ_t5Uk124.jpg)
![第6講 Linux字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)_第2頁(yè)](http://file4.renrendoc.com/view11/M01/28/20/wKhkGWX7YbiAZWRKAAJkZJ_t5Uk1242.jpg)
![第6講 Linux字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)_第3頁(yè)](http://file4.renrendoc.com/view11/M01/28/20/wKhkGWX7YbiAZWRKAAJkZJ_t5Uk1243.jpg)
![第6講 Linux字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)_第4頁(yè)](http://file4.renrendoc.com/view11/M01/28/20/wKhkGWX7YbiAZWRKAAJkZJ_t5Uk1244.jpg)
![第6講 Linux字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)_第5頁(yè)](http://file4.renrendoc.com/view11/M01/28/20/wKhkGWX7YbiAZWRKAAJkZJ_t5Uk1245.jpg)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1第6講
Linux字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)嵌入式操作系統(tǒng)2本講主要內(nèi)容6.1
Linux設(shè)備驅(qū)動(dòng)簡(jiǎn)介6.2字符設(shè)備驅(qū)動(dòng)程序框架6.3字符設(shè)備舉例
6.1
Linux設(shè)備驅(qū)動(dòng)簡(jiǎn)介設(shè)備驅(qū)動(dòng)程序和應(yīng)用程序的關(guān)系:3應(yīng)用程序驅(qū)動(dòng)程序設(shè)備writereadioctlioctlLinux設(shè)備驅(qū)動(dòng)屬于內(nèi)核模塊的一部分。Linux內(nèi)核模塊介紹
Linux內(nèi)核的整體結(jié)構(gòu)非常龐大,其包含的組件非常多。我們?nèi)绾伟研枰牟糠侄及趦?nèi)核中呢?把需要的功能都編譯到linux內(nèi)核,隨同Linux啟動(dòng)時(shí)加載。以模塊方式擴(kuò)展內(nèi)核功能。使用insmod加載,使用rmmod刪除。這種方式控制了內(nèi)核的大小,而模塊一旦被插入到內(nèi)核,它就和內(nèi)核其他部分一樣。
4Linux內(nèi)核模塊的優(yōu)點(diǎn)與缺點(diǎn)優(yōu)點(diǎn)使內(nèi)核更加緊湊和靈活;修改內(nèi)核時(shí),不必全部重新編譯整個(gè)內(nèi)核。系統(tǒng)如果需要使用新模塊,只要編譯相應(yīng)的模塊,然后使用insmod將模塊裝載即可;模塊的目標(biāo)代碼一旦被鏈接到內(nèi)核,它的作用域和靜態(tài)鏈接的內(nèi)核目標(biāo)代碼完全等價(jià)。缺點(diǎn)由于內(nèi)核所占用的內(nèi)存是不會(huì)被換出的,所以鏈接進(jìn)內(nèi)核的模塊會(huì)給整個(gè)系統(tǒng)帶來(lái)一定的性能和內(nèi)存利用方面的損失;裝入內(nèi)核的模塊就成為內(nèi)核的一部分,可以修改內(nèi)核中的其他部分,因此,模塊的使用不當(dāng)會(huì)導(dǎo)致系統(tǒng)崩潰;為了讓內(nèi)核模塊能訪問(wèn)所有內(nèi)核資源,內(nèi)核必須維護(hù)符號(hào)表,并在裝入和卸載模塊時(shí)修改符號(hào)表;模塊會(huì)要求利用其它模塊的功能,所以,內(nèi)核要維護(hù)模塊之間的依賴性。Linux內(nèi)核模塊與應(yīng)用程序的區(qū)別C語(yǔ)言程序Linux內(nèi)核模塊運(yùn)行用戶空間內(nèi)核空間入口main()module_init()指定;出口無(wú)module_exit()指定;
連接ldinsmod運(yùn)行直接運(yùn)行insmod7設(shè)備分類:字符設(shè)備以字節(jié)為單位逐個(gè)進(jìn)行I/O操作字符設(shè)備中的緩存是可有可無(wú)不支持隨機(jī)訪問(wèn)如串口設(shè)備等塊設(shè)備塊設(shè)備的存取是通過(guò)buffer、cache來(lái)進(jìn)行可以進(jìn)行隨機(jī)訪問(wèn)例如IDE硬盤設(shè)備可以支持可安裝文件系統(tǒng)網(wǎng)絡(luò)設(shè)備通過(guò)BSD套接口訪問(wèn)設(shè)備文件Linux抽象了對(duì)硬件的處理,所有的硬件設(shè)備都可以作為普通文件一樣來(lái)看待??梢允褂煤筒僮魑募嗤摹?biāo)準(zhǔn)的系統(tǒng)調(diào)用接口來(lái)完成打開、關(guān)閉、讀寫和I/O控制操作字符設(shè)備和塊設(shè)備是通過(guò)文件節(jié)點(diǎn)訪問(wèn)的。在Linux的文件系統(tǒng)中,可以找到(或者使用mknod創(chuàng)建)設(shè)備對(duì)應(yīng)的文件名,稱這種文件為設(shè)備文件。主設(shè)備號(hào)和次設(shè)備號(hào)主設(shè)備號(hào):標(biāo)識(shí)該設(shè)備的種類,也標(biāo)識(shí)了該設(shè)備所使用的驅(qū)動(dòng)程序:主設(shè)備號(hào)的范圍只能是1-255Linux內(nèi)核支持動(dòng)態(tài)分配主設(shè)備號(hào)次設(shè)備號(hào):標(biāo)識(shí)使用同一設(shè)備驅(qū)動(dòng)程序的不同硬件設(shè)備。同一個(gè)驅(qū)動(dòng)程序可以管理多個(gè)設(shè)備,它們依靠次設(shè)備號(hào)來(lái)區(qū)別。次設(shè)備號(hào)只在驅(qū)動(dòng)程序內(nèi)部使用,系統(tǒng)內(nèi)核直接把次設(shè)備號(hào)傳遞給驅(qū)動(dòng)程序,由驅(qū)動(dòng)程序去管理。6.2字符設(shè)備驅(qū)動(dòng)程序框架
——基于linux2.6.38Linux設(shè)備驅(qū)動(dòng)程序大致可分為如下幾個(gè)部分:驅(qū)動(dòng)程序的注冊(cè)與注銷、設(shè)備的打開與釋放、設(shè)備的讀寫操作、設(shè)備的控制操作、設(shè)備的中斷和輪詢處理。10
驅(qū)動(dòng)程序使用的2個(gè)重要結(jié)構(gòu)structfile 文件描述結(jié)構(gòu)structfile_operations 文件操作結(jié)構(gòu)structmiscdevice 混雜設(shè)備結(jié)構(gòu)structdev 設(shè)備結(jié)構(gòu)structfile structfile數(shù)據(jù)結(jié)構(gòu)定義位于include/fs.hstructfile結(jié)構(gòu)與驅(qū)動(dòng)相關(guān)的成員mode_tf_mode
標(biāo)識(shí)文件的讀寫權(quán)限loff_tf_pos
當(dāng)前讀寫位置unsignedint_f_flag
文件標(biāo)志,主要進(jìn)行阻塞/非阻塞型操作structfile_operation*f_op
文件操作的結(jié)構(gòu)指針void*private_data
驅(qū)動(dòng)程序一般將它指向已經(jīng)分配的數(shù)據(jù)structdentry*f_dentry 文件對(duì)應(yīng)的目錄項(xiàng)結(jié)構(gòu)設(shè)備驅(qū)動(dòng)程序接口staticstructfile_operationsdemo_fops={ owner: THIS_MODULE, write: demo_write, read: demo_read, ioctl: demo_ioctl, open: demo_open, release: demo_release,};設(shè)備驅(qū)動(dòng)程序接口(structfile_operations)設(shè)備驅(qū)動(dòng)程序接口是指structfile_operations{},它的定義位于include/linux/fs.h中。在嵌入式系統(tǒng)的開發(fā)中,通常只要實(shí)現(xiàn)如下幾個(gè)接口函數(shù)就能完成系統(tǒng)所需要的功能:init
加載驅(qū)動(dòng)程序時(shí),內(nèi)核自動(dòng)調(diào)用read
從設(shè)備中讀取數(shù)據(jù)write向字符設(shè)備中寫數(shù)據(jù)ioctl
控制設(shè)備,實(shí)現(xiàn)除讀寫操作以外的其他控制命令open
打開設(shè)備并進(jìn)行初始化release關(guān)閉設(shè)備并釋放資源exit卸載驅(qū)動(dòng)程序時(shí),內(nèi)核自動(dòng)調(diào)用驅(qū)動(dòng)程序注冊(cè)過(guò)程(動(dòng)態(tài)分配主設(shè)備號(hào))insmodmodule_name;加載驅(qū)動(dòng)程序,運(yùn)行init函數(shù)(register_chrdev(dev_Major,“module_name”,*fs))查看/proc/devicesmknod/dev/module_namec/b主設(shè)備號(hào)次設(shè)備號(hào)rmmodmodule_name;卸載驅(qū)動(dòng),運(yùn)行exit函數(shù)(unregister_chrdev(dev_Major,“module_name”,*fs))用戶程序調(diào)用open(“/dev/module_name”,mode);O_RDWRioctl()write()read()close()混雜設(shè)備結(jié)構(gòu):structmiscdevice 在Linux驅(qū)動(dòng)中把無(wú)法歸類的五花八門的設(shè)備定義為混雜設(shè)備(用miscdevice結(jié)構(gòu)體表述)。miscdevice共享一個(gè)主設(shè)備號(hào)MISC_MAJOR(即10),但次設(shè)備號(hào)不同。所有的miscdevice設(shè)備形成了一個(gè)鏈表,對(duì)設(shè)備訪問(wèn)時(shí)內(nèi)核根據(jù)次設(shè)備號(hào)查找對(duì)應(yīng)的miscdevice設(shè)備,然后調(diào)用其file_operations結(jié)構(gòu)中注冊(cè)的文件操作接口進(jìn)行操作。
17structmiscdevice內(nèi)部結(jié)構(gòu)186.3字符設(shè)備舉例例1:LED驅(qū)動(dòng)程序。191、結(jié)構(gòu)#defineDEVICE_NAME"gd_leds" //設(shè)備名稱structdev{ structmiscdevice*miscp;};structdev*devp;staticstructfile_operationsdev_fops={ .owner =THIS_MODULE, .unlocked_ioctl =mini6410_leds_ioctl,};20staticstructmiscdevicemisc={ .minor=MISC_DYNAMIC_MINOR, //動(dòng)態(tài)申請(qǐng)?jiān)O(shè)備號(hào)
.name=DEVICE_NAME, //設(shè)備名稱
.fops=&dev_fops,};212、ioctl()函數(shù)staticlongmini6410_ioctl(structfile*filp,unsignedintcmd,unsignedlongarg){ switch(cmd) { unsignedtmp; case0: case1: if(arg>4) { return–EINVAL; } tmp=ioread8((void*)S3C64XX_GPKDAT); //讀K口 Tmp&=~(1<<(4+arg)); tmp|=((!cmd)<<(4+arg)); iowrite8(tmp,(void*)S3C64XX_GPKDAT); //寫K口 Return0; default: return–EINVAL; }}223、模塊初始化函數(shù)staticint__initdev_init(void){ intret; unsignedtmp;
//設(shè)置K口4~7為輸出
tmp=readl((void*)S3C64XX_GPKCON); tmp=(tmp&~(0xffffU<<16))|(0x1111U<<16); writel(tmp,(void*)S3C64XX_GPKCON);
//設(shè)置K口4~7為高電平(LED滅) tmp=ioread8((void*)S3C64XX_GPKDAT); tmp|=(0xF<<4); iowrite8(tmp,(void*)S3C64XX_GPKDAT);
devp=(structdev*)kmalloc(sizeof(structdev),GFP_KERNEL);
devp->miscp=&misc;
ret=misc_register(devp->miscp); //注冊(cè)設(shè)備
printk(DEVICE_NAME”\tinitialized\n”);
returnret;}234、模塊退出函數(shù)staticvoid__exitdev_exit(void){ misc_deregister(devp->miscp); //釋放設(shè)備
kfree(devp);}245、模塊說(shuō)明宏module_init(dev_init);module_exit(dev_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("GuangZhouUniversity.");256、將驅(qū)動(dòng)程序gd_leds.c放在linux字符設(shè)備驅(qū)動(dòng)程序目錄。26
一般編譯2.6版本的驅(qū)動(dòng)模塊需要把驅(qū)動(dòng)代碼加入內(nèi)核代碼樹,并做相應(yīng)的配置。7、編輯配置文件Kconfig,加入驅(qū)動(dòng)選項(xiàng)。
打開linux-2.6.38/drivers/char/Kconfig文件,添加如圖所示:278、配置
在linux-2.6.38目錄位置運(yùn)行一下makemenuconfig就可以在DeviceDrivers的Characterdevices菜單中看到剛才所添加的選項(xiàng)了。
按下空格鍵將會(huì)選擇為<M>,此意為要把該選項(xiàng)編譯為模塊方式;再按下空格會(huì)變?yōu)?lt;*>,意為要把該選項(xiàng)編譯到內(nèi)核中,在此我們選擇<M>。289、在Makefile中把內(nèi)核配置選項(xiàng)和真正的源代碼聯(lián)系起來(lái),打開linux-2.6.38/drivers/char/Makefile并添加:obj-$(CONFIG_OUR_LEDS_DRIVER) +=our_leds_driver.o2910、執(zhí)行配置makemodules3011、下載驅(qū)動(dòng)程序our_leds_driver.ko到目標(biāo)板。操作如第5講的5.4的例3的11、12。11、拷貝目標(biāo)程序到nfs目錄12、掛載目標(biāo)機(jī)到宿主機(jī)(NFS)在超級(jí)終端輸入@#ifconfigeth000@#mount–tnfs–onolock00:/home/nfs/mnt@#cd/mnt3112、加載LED驅(qū)動(dòng)程序入內(nèi)核。 insmodgd_leds.ko3213、編寫、運(yùn)行用戶端的測(cè)試程序。
如第5講的5.4的例2,將程序改為:33#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/ioctl.h>#include<fcntl.h>intma
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 打深水井工程合同范本
- 商業(yè)秘密保密協(xié)議書范本
- 現(xiàn)代產(chǎn)業(yè)學(xué)院合作協(xié)議書范本
- 蘇科版數(shù)學(xué)九年級(jí)下冊(cè)5.5《用二次函數(shù)解決問(wèn)題》聽(tīng)評(píng)課記錄
- 寶山中學(xué)8年級(jí)數(shù)學(xué)試卷
- 人物動(dòng)作描寫聽(tīng)評(píng)課記錄
- 淘氣的作息時(shí)間(經(jīng)過(guò)時(shí)間)(說(shuō)課稿)-2023-2024學(xué)年數(shù)學(xué)二年級(jí)下冊(cè)北師大版
- 八年級(jí)上學(xué)期期中考試數(shù)學(xué)試題
- 人教版數(shù)學(xué)八年級(jí)上冊(cè)聽(tīng)評(píng)課記錄《14-2乘法公式》(第3課時(shí))
- 部編人教版歷史九年級(jí)上冊(cè)第6課《希臘羅馬古典文化》聽(tīng)課評(píng)課記錄1
- 牧場(chǎng)物語(yǔ)-礦石鎮(zhèn)的伙伴們-完全攻略
- 供電公司一把手講安全
- 2020年血液凈化感染控制操作規(guī)程課件
- 計(jì)算機(jī)輔助工藝設(shè)計(jì)課件
- 汽車銷售流程與技巧培訓(xùn)課件
- 管理學(xué)專業(yè):管理基礎(chǔ)知識(shí)試題庫(kù)(附含答案)
- 外周血細(xì)胞形態(tài)課件
- 2022年三級(jí)安全教育塔吊司機(jī)類試題及答案
- 地鐵工程結(jié)算審核的難點(diǎn)及要點(diǎn)分析
- 低壓開關(guān)柜基礎(chǔ)知識(shí)和IP防護(hù)等級(jí)具體要求
- 自主招生培訓(xùn)物理講義
評(píng)論
0/150
提交評(píng)論