版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、1.字符設(shè)備驅(qū)動編寫流程8.2 字符設(shè)備驅(qū)動編程1按模塊化設(shè)計,一個典型的Linux設(shè)備驅(qū)動程序應(yīng)包含哪幾部分?在Linux操作系統(tǒng)中如何實現(xiàn)一個驅(qū)動程序的開發(fā)?設(shè)備驅(qū)動程序通常包含中斷處理程序和設(shè)備服務(wù)子程序兩部分。一個典型的Linux設(shè)備驅(qū)動程序應(yīng)包含以下幾部分代碼:設(shè)備服務(wù)子程序(驅(qū)動程序模塊的注冊與注銷函數(shù)、設(shè)備的打開、關(guān)閉、讀、寫及需要的其他操作函數(shù))設(shè)備的中斷服務(wù)程序。在Linux操作系統(tǒng)中實現(xiàn)一個驅(qū)動程序的開發(fā),必須按照如下步驟進行:設(shè)備或模塊的初始化;實現(xiàn)該文件操作接口;注冊設(shè)備中斷;編寫中斷服務(wù)程序;文件讀寫操作。22.重要數(shù)據(jù)結(jié)構(gòu) 驅(qū)動程序中最重要的三個結(jié)構(gòu):inode 文
2、件file 文件描述符 I/O操作函數(shù)8.2 字符設(shè)備驅(qū)動編程3struct loff_t (*llseek) (struct file *, loff_t, int);ssize_t (*read) (struct file *filp, char *buff, size_t count, loff_t *offp);ssize_t (*write) (struct file *filp, const char *buff, size_t count, loff_t *offp);int (*readdir) (struct file *, void *, filldir_t);unsign
3、ed int (*poll) (struct file *, struct poll_table_struct *);int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);int (*mmap) (struct file *, struct vm_area_struct *);int (*open) (struct inode *, struct file *);int (*flush) (struct file *);int (*release) (struct inode *, struct fi
4、le *);int (*fsync) (struct file *, struct dentry *);int (*fasync) (int, struct file *, int);int (*check_media_change) (kdev_t dev);int (*revalidate) (kdev_t dev);int (*lock) (struct file *, int, struct *);4mode_t f_mode;/*標識文件是否可讀或可寫,F(xiàn)MODE_READ或FMODE_WRITE*/dev_t f_rdev; /* 用于/dev/tty */off_t f_pos;
5、 /* 當前文件位移 */unsigned short f_flags; /* 文件標志,如O_RDONLY、O_NONBLOCK和O_SYNC */unsigned short f_count; /* 打開的文件數(shù)目 */unsigned short f_reada;struct inode *f_inode; /*指向inode的結(jié)構(gòu)指針 */struct *f_op;/* 文件索引指針 */;struct file 5struct inodedev_t i_rdev,表示設(shè)備文件對應(yīng)的設(shè)備號。structcdev *i_cdev,成員指向cdev設(shè)備。除了從dev_t得到主設(shè)備號和次設(shè)備
6、號外,這里還可以使用imajor()和iminor()函數(shù)從i_rdev中得到主設(shè)備號和次設(shè)備號。imajor()函數(shù)在內(nèi)部調(diào)用MAJOR宏,如下代碼所示。staticinlineunsignedimajor(conststructinode*inode) returnMAJOR(inode-i_rdev);/*從inode-i_rdev中提取主設(shè)備號*/ 同樣,iminor()函數(shù)在內(nèi)部調(diào)用MINOR宏,如下代碼所示。staticinlineunsignediminor(conststructinode*inode) returnMINOR(inode-i_rdev);/*從inode-i_
7、rdev中提取次設(shè)備號*/ 68.2.3設(shè)備驅(qū)動程序主要組成1.早期版本的字符設(shè)備注冊register_chrdev() 8.2 字符設(shè)備驅(qū)動編程78.2.3設(shè)備驅(qū)動程序主要組成1.早期版本的字符設(shè)備注冊unregister_chrdev() 8.2 字符設(shè)備驅(qū)動編程88.2.3設(shè)備驅(qū)動程序主要組成2.設(shè)備號相關(guān)函數(shù)獲取設(shè)備號MAJOR(dev_t dev); /*獲得主設(shè)備號*/MINOR(dev_t dev); /*獲得次設(shè)備號*/MKDEV(int major, int minor);設(shè)備注冊于注銷8.2 字符設(shè)備驅(qū)動編程98.2.3設(shè)備驅(qū)動程序主要組成2.設(shè)備號相關(guān)函數(shù)獲取設(shè)備號MAJ
8、OR(dev_t dev); /*獲得主設(shè)備號*/MINOR(dev_t dev); /*獲得次設(shè)備號*/MKDEV(int major, int minor);設(shè)備注冊于注銷8.2 字符設(shè)備驅(qū)動編程108.2.3設(shè)備驅(qū)動程序主要組成3.新版本設(shè)備注冊8.2 字符設(shè)備驅(qū)動編程11舉例structtest_fops=read:read_test,write:write_test,open:open_test,release:release_test,;unsignedinttest_major=254;/設(shè)備號intresult;result=register_chrdev(test_major
9、,test,&test_fops);if(resultprivate_data的數(shù)據(jù)結(jié)構(gòu)。檢查設(shè)備特定的錯誤(諸如設(shè)備未就緒或類似的硬件問題)。8.2 字符設(shè)備驅(qū)動編程138.2.3設(shè)備驅(qū)動程序主要組成5.釋放設(shè)備int (*release) (struct inode *, struct file *); 釋放設(shè)備的主要操作:釋放打開設(shè)備時系統(tǒng)所分配的內(nèi)存空間(包括filp-private_data指向的內(nèi)存空間)。在最后一次關(guān)閉設(shè)備(使用close()系統(tǒng)調(diào)用)時,才會真正釋放設(shè)備(執(zhí)行release()函數(shù))。即在打開計數(shù)等于0時的close()系統(tǒng)調(diào)用才會真正進行設(shè)備的釋放操作。8.2
10、 字符設(shè)備驅(qū)動編程14模塊計數(shù)的實現(xiàn)Linux 2.4內(nèi)核MOD_INC_USE_COUNTMOD_DEC_USE_COUNTLinux 2.6內(nèi)核try_module_get(&module)int try_module_get(struct module *module);該函數(shù)用于增加模塊使用計數(shù);若返回為0,表示調(diào)用失敗,希望使用的模塊沒有被加載或正在被卸載中。module_put (&module)void module_put(struct module *module);該函數(shù)用于減少模塊使用計數(shù)。15舉例linux2.4staticintopen_test(structinod
11、e*inode,structfile*file)MOD_INC_USE_COUNT;return0;staticintrelease_test(structinode*inode,structfile*file)MOD_DEC_USE_COUNT;return0;16舉例linux2.6static void _exit module_close(void) len=0; printk(KERN_ALERTUnloading.n); unregister_chrdev_region(MKDEV(DP_MAJOR,DP_MINOR),10); cdev_del(chardev); 178.2.3
12、設(shè)備驅(qū)動程序主要組成6.讀寫設(shè)備 read()和write()函數(shù) 8.2 字符設(shè)備驅(qū)動編程188.2.3設(shè)備驅(qū)動程序主要組成6.讀寫設(shè)備 copy_to_user()和copy_from_user() 8.2 字符設(shè)備驅(qū)動編程19舉例char*str_test;/存放內(nèi)存空間的指針unsignedintcount_driver;/當前內(nèi)存中擁有的數(shù)據(jù)的字節(jié)數(shù)constunsignedintcount_driver_max=255;/容量的最大值static ssize_t write_test(struct file * char *buf,size_t count,loff_t *t)in
13、t result;if(count0)if(count_driver=count)if(result=copy_to_user(buf,str_test,count)!=0)read_num=count;elseread_num=0;elseif(result=copy_to_user(buf,str_test,count_driver)!=0)read_num=count_driver;elseread_num=0;elseread_num=0;return read_num;218.2.3設(shè)備驅(qū)動程序主要組成7.ioctl 大部分設(shè)備除了讀寫操作,還需要硬件配置和控制(例如,設(shè)置串口設(shè)備的
14、波特率)等很多其他操作。在字符設(shè)備驅(qū)動中ioctl函數(shù)接口給用戶提供對設(shè)備的非讀寫操作機制。8.2 字符設(shè)備驅(qū)動編程228.2.3設(shè)備驅(qū)動程序主要組成8.獲取內(nèi)存kmalloc()/kfree()kmalloc語法格式:8.2 字符設(shè)備驅(qū)動編程238.2.3設(shè)備驅(qū)動程序主要組成if(str_test=(char*)kmalloc(256,GFP_KERNEL)=NULL)/申請256字節(jié)的內(nèi)存空間printk(kmallocerrorn);return-1;8.2 字符設(shè)備驅(qū)動編程241.什么是GPIO接口?其主要作用? GPIO接口就是通用輸入輸出(General Purpose Input
15、/Output) 主要作用是傳送需并行交互的信息,或者是開關(guān)量信號。 2.內(nèi)核模塊的編程和普通應(yīng)用程序的編程有哪些區(qū)別? 主要區(qū)別為:(1)因為內(nèi)核模塊運行在內(nèi)核態(tài),所以包含的頭文件是內(nèi)核程序相關(guān)的頭文件,而普通程序則包含的是glibc的頭文件(2)模塊程序沒有main函數(shù),而是通過init_module函數(shù)在加載后初始化。(3)模塊程序內(nèi)可直接調(diào)用內(nèi)核函數(shù),而普通程序則只能通過系統(tǒng)調(diào)用使用內(nèi)核函數(shù)。(4)普通用戶程序可運行多次,而內(nèi)核函數(shù)通常則只能加載1次。253.Linux中的設(shè)備可以分為哪幾類,各有何特點? Linux中的設(shè)備可以分為三類:字符設(shè)備、塊設(shè)備和網(wǎng)絡(luò)設(shè)備。各自的特點是:字符設(shè)
16、備是指數(shù)據(jù)處理以字節(jié)為單位按順序進行的設(shè)備,它沒有緩沖區(qū),不支持隨機讀寫。在對字符設(shè)備發(fā)出讀/寫請求時,實際的硬件I/O一般就緊接著發(fā)生了。塊設(shè)備是指那些在輸入/輸出時數(shù)據(jù)處理以塊為單位的設(shè)備,它一般都采用了緩存技術(shù),支持數(shù)據(jù)的隨機讀寫。網(wǎng)絡(luò)設(shè)備面向的上一層不是文件系統(tǒng)層而是網(wǎng)絡(luò)協(xié)議層,設(shè)備節(jié)點只有在系統(tǒng)正確初始化網(wǎng)絡(luò)控制器之后才能建立。內(nèi)核和網(wǎng)絡(luò)設(shè)備驅(qū)動程序間的通信,與字符設(shè)備驅(qū)動程序、塊設(shè)備驅(qū)動程序與內(nèi)核間的通信也是完全不一樣的。在Linux中,整個網(wǎng)絡(luò)接口驅(qū)動程序的框架可分為四層,從上到下分別為協(xié)議接口層、網(wǎng)絡(luò)設(shè)備接口層、提供實際功能的設(shè)備驅(qū)動功能層、以及網(wǎng)絡(luò)設(shè)備和網(wǎng)絡(luò)媒介層。26驅(qū)動模
17、塊編寫測試步驟編寫模塊代碼編譯代碼 gcc 加載模塊insmod 查看設(shè)備號/proc/device映射為設(shè)備文件 mknod /dev/fs c 254 0編寫測試代碼生成可執(zhí)行測試文件運行測試27#include#include#include#include#include#include#include#include#includeMODULE_LICENSE(GPL);unsignedinttest_major=254;/設(shè)備號char*str_test;/存放內(nèi)存空間的指針unsignedintcount_driver;/當前內(nèi)存中擁有的數(shù)據(jù)的字節(jié)數(shù)constunsignedin
18、tcount_driver_max=255;/容量的最大值structtest_fops=read:read_test,write:write_test,open:open_test,release:release_test,;28模塊初始化函數(shù)為staticinttest_init_module(void) intresult;result=register_chrdev(test_major,test,&test_fops);if(result0) printk(KERN_INFOtest:cantgetmajornumbern);returnresult;printk(registero
19、kn);if(str_test=(char*)kmalloc(256,GFP_KERNEL)=NULL)/申請256字節(jié)的內(nèi)存空間printk(kmallocerrorn);return-1;Elseprintk(kamllocsuccess!n);count_driver=0;return0; 29open和close的實現(xiàn), 只是一個計數(shù)功能:staticintopen_test(structinode*inode,structfile*file)MOD_INC_USE_COUNT;return0;staticintrelease_test(structinode*inode,struct
20、file*file)MOD_DEC_USE_COUNT;return0;30Write函數(shù)的實現(xiàn)static ssize_t write_test(struct file * char *buf,size_t count,loff_t *t)int result;if(count0)if(count_driver=count)if(result=copy_to_user(buf,str_test,count)=0)read_num=count;elseread_num=0;elseif(result=copy_to_user(buf,str_test,count_driver)=0)read_num=count_driver;elseread_num=0;elseread_num=0;return read_num;32gcc-DMODULE-D_KERNEL_-I/usr/src/linux-2.4.20/include-ctest.cinsmod test.omknod /dev/test c 254 0c表示字符設(shè)備,254為主設(shè)備號,0為次設(shè)備號。33Test_w.c#include#include#include#includeint main(void)int i;in
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《脊柱的運動解剖》課件
- 第6單元 科技文化與社會生活(A卷·知識通關(guān)練)(解析版)
- 中華傳統(tǒng)文化宣傳教育2
- 雙十二時尚之道
- 駛向輝煌共創(chuàng)精彩
- 音樂制作師勞動合同三篇
- 深部護理科護士的工作總結(jié)
- 競選班干部的演講稿模板集錦八篇
- 2023年-2024年安全管理人員安全教育培訓試題附答案(A卷)
- 2024年企業(yè)主要負責人安全培訓考試題附參考答案【突破訓練】
- 2024年菏澤單州市政工程集團有限公司招聘筆試參考題庫附帶答案詳解
- 教育創(chuàng)新智慧課堂賦能學習
- 園林綠化員工培訓課件
- 《雷達對抗原理》課件
- 《CT檢查技術(shù)》課件-CT圖像后處理
- 刑事辯護策略技巧案例
- 土壤檢測報告表
- 2024年陜西西安高新區(qū)管委會工作人員招聘筆試參考題庫附帶答案詳解
- 上海高端住宅市場分析報告
- 《產(chǎn)品價值點》課件
- 內(nèi)科醫(yī)生如何與患者建立有效的溝通
評論
0/150
提交評論