




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、1.字符設(shè)備驅(qū)動(dòng)編寫流程8.2 字符設(shè)備驅(qū)動(dòng)編程1按模塊化設(shè)計(jì),一個(gè)典型的Linux設(shè)備驅(qū)動(dòng)程序應(yīng)包含哪幾部分?在Linux操作系統(tǒng)中如何實(shí)現(xiàn)一個(gè)驅(qū)動(dòng)程序的開發(fā)?設(shè)備驅(qū)動(dòng)程序通常包含中斷處理程序和設(shè)備服務(wù)子程序兩部分。一個(gè)典型的Linux設(shè)備驅(qū)動(dòng)程序應(yīng)包含以下幾部分代碼:設(shè)備服務(wù)子程序(驅(qū)動(dòng)程序模塊的注冊(cè)與注銷函數(shù)、設(shè)備的打開、關(guān)閉、讀、寫及需要的其他操作函數(shù))設(shè)備的中斷服務(wù)程序。在Linux操作系統(tǒng)中實(shí)現(xiàn)一個(gè)驅(qū)動(dòng)程序的開發(fā),必須按照如下步驟進(jìn)行:設(shè)備或模塊的初始化;實(shí)現(xiàn)該文件操作接口;注冊(cè)設(shè)備中斷;編寫中斷服務(wù)程序;文件讀寫操作。22.重要數(shù)據(jù)結(jié)構(gòu) 驅(qū)動(dòng)程序中最重要的三個(gè)結(jié)構(gòu):inode 文
2、件file 文件描述符 I/O操作函數(shù)8.2 字符設(shè)備驅(qū)動(dòng)編程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;/*標(biāo)識(shí)文件是否可讀或可寫,F(xiàn)MODE_READ或FMODE_WRITE*/dev_t f_rdev; /* 用于/dev/tty */off_t f_pos;
5、 /* 當(dāng)前文件位移 */unsigned short f_flags; /* 文件標(biāo)志,如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è)備文件對(duì)應(yīng)的設(shè)備號(hào)。structcdev *i_cdev,成員指向cdev設(shè)備。除了從dev_t得到主設(shè)備號(hào)和次設(shè)備
6、號(hào)外,這里還可以使用imajor()和iminor()函數(shù)從i_rdev中得到主設(shè)備號(hào)和次設(shè)備號(hào)。imajor()函數(shù)在內(nèi)部調(diào)用MAJOR宏,如下代碼所示。staticinlineunsignedimajor(conststructinode*inode) returnMAJOR(inode-i_rdev);/*從inode-i_rdev中提取主設(shè)備號(hào)*/ 同樣,iminor()函數(shù)在內(nèi)部調(diào)用MINOR宏,如下代碼所示。staticinlineunsignediminor(conststructinode*inode) returnMINOR(inode-i_rdev);/*從inode-i_
7、rdev中提取次設(shè)備號(hào)*/ 68.2.3設(shè)備驅(qū)動(dòng)程序主要組成1.早期版本的字符設(shè)備注冊(cè)register_chrdev() 8.2 字符設(shè)備驅(qū)動(dòng)編程78.2.3設(shè)備驅(qū)動(dòng)程序主要組成1.早期版本的字符設(shè)備注冊(cè)u(píng)nregister_chrdev() 8.2 字符設(shè)備驅(qū)動(dòng)編程88.2.3設(shè)備驅(qū)動(dòng)程序主要組成2.設(shè)備號(hào)相關(guān)函數(shù)獲取設(shè)備號(hào)MAJOR(dev_t dev); /*獲得主設(shè)備號(hào)*/MINOR(dev_t dev); /*獲得次設(shè)備號(hào)*/MKDEV(int major, int minor);設(shè)備注冊(cè)于注銷8.2 字符設(shè)備驅(qū)動(dòng)編程98.2.3設(shè)備驅(qū)動(dòng)程序主要組成2.設(shè)備號(hào)相關(guān)函數(shù)獲取設(shè)備號(hào)MAJ
8、OR(dev_t dev); /*獲得主設(shè)備號(hào)*/MINOR(dev_t dev); /*獲得次設(shè)備號(hào)*/MKDEV(int major, int minor);設(shè)備注冊(cè)于注銷8.2 字符設(shè)備驅(qū)動(dòng)編程108.2.3設(shè)備驅(qū)動(dòng)程序主要組成3.新版本設(shè)備注冊(cè)8.2 字符設(shè)備驅(qū)動(dòng)編程11舉例structtest_fops=read:read_test,write:write_test,open:open_test,release:release_test,;unsignedinttest_major=254;/設(shè)備號(hào)intresult;result=register_chrdev(test_major
9、,test,&test_fops);if(resultprivate_data的數(shù)據(jù)結(jié)構(gòu)。檢查設(shè)備特定的錯(cuò)誤(諸如設(shè)備未就緒或類似的硬件問題)。8.2 字符設(shè)備驅(qū)動(dòng)編程138.2.3設(shè)備驅(qū)動(dòng)程序主要組成5.釋放設(shè)備int (*release) (struct inode *, struct file *); 釋放設(shè)備的主要操作:釋放打開設(shè)備時(shí)系統(tǒng)所分配的內(nèi)存空間(包括filp-private_data指向的內(nèi)存空間)。在最后一次關(guān)閉設(shè)備(使用close()系統(tǒng)調(diào)用)時(shí),才會(huì)真正釋放設(shè)備(執(zhí)行release()函數(shù))。即在打開計(jì)數(shù)等于0時(shí)的close()系統(tǒng)調(diào)用才會(huì)真正進(jìn)行設(shè)備的釋放操作。8.2
10、 字符設(shè)備驅(qū)動(dòng)編程14模塊計(jì)數(shù)的實(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ù)用于增加模塊使用計(jì)數(shù);若返回為0,表示調(diào)用失敗,希望使用的模塊沒有被加載或正在被卸載中。module_put (&module)void module_put(struct module *module);該函數(shù)用于減少模塊使用計(jì)數(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ū)動(dòng)程序主要組成6.讀寫設(shè)備 read()和write()函數(shù) 8.2 字符設(shè)備驅(qū)動(dòng)編程188.2.3設(shè)備驅(qū)動(dòng)程序主要組成6.讀寫設(shè)備 copy_to_user()和copy_from_user() 8.2 字符設(shè)備驅(qū)動(dòng)編程19舉例char*str_test;/存放內(nèi)存空間的指針unsignedintcount_driver;/當(dāng)前內(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ū)動(dòng)程序主要組成7.ioctl 大部分設(shè)備除了讀寫操作,還需要硬件配置和控制(例如,設(shè)置串口設(shè)備的
14、波特率)等很多其他操作。在字符設(shè)備驅(qū)動(dòng)中ioctl函數(shù)接口給用戶提供對(duì)設(shè)備的非讀寫操作機(jī)制。8.2 字符設(shè)備驅(qū)動(dòng)編程228.2.3設(shè)備驅(qū)動(dòng)程序主要組成8.獲取內(nèi)存kmalloc()/kfree()kmalloc語法格式:8.2 字符設(shè)備驅(qū)動(dòng)編程238.2.3設(shè)備驅(qū)動(dòng)程序主要組成if(str_test=(char*)kmalloc(256,GFP_KERNEL)=NULL)/申請(qǐng)256字節(jié)的內(nèi)存空間printk(kmallocerrorn);return-1;8.2 字符設(shè)備驅(qū)動(dòng)編程241.什么是GPIO接口?其主要作用? GPIO接口就是通用輸入輸出(General Purpose Input
15、/Output) 主要作用是傳送需并行交互的信息,或者是開關(guān)量信號(hào)。 2.內(nèi)核模塊的編程和普通應(yīng)用程序的編程有哪些區(qū)別? 主要區(qū)別為:(1)因?yàn)閮?nèi)核模塊運(yùn)行在內(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)普通用戶程序可運(yùn)行多次,而內(nèi)核函數(shù)通常則只能加載1次。253.Linux中的設(shè)備可以分為哪幾類,各有何特點(diǎn)? Linux中的設(shè)備可以分為三類:字符設(shè)備、塊設(shè)備和網(wǎng)絡(luò)設(shè)備。各自的特點(diǎn)是:字符設(shè)
16、備是指數(shù)據(jù)處理以字節(jié)為單位按順序進(jìn)行的設(shè)備,它沒有緩沖區(qū),不支持隨機(jī)讀寫。在對(duì)字符設(shè)備發(fā)出讀/寫請(qǐng)求時(shí),實(shí)際的硬件I/O一般就緊接著發(fā)生了。塊設(shè)備是指那些在輸入/輸出時(shí)數(shù)據(jù)處理以塊為單位的設(shè)備,它一般都采用了緩存技術(shù),支持?jǐn)?shù)據(jù)的隨機(jī)讀寫。網(wǎng)絡(luò)設(shè)備面向的上一層不是文件系統(tǒng)層而是網(wǎng)絡(luò)協(xié)議層,設(shè)備節(jié)點(diǎn)只有在系統(tǒng)正確初始化網(wǎng)絡(luò)控制器之后才能建立。內(nèi)核和網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序間的通信,與字符設(shè)備驅(qū)動(dòng)程序、塊設(shè)備驅(qū)動(dòng)程序與內(nèi)核間的通信也是完全不一樣的。在Linux中,整個(gè)網(wǎng)絡(luò)接口驅(qū)動(dòng)程序的框架可分為四層,從上到下分別為協(xié)議接口層、網(wǎng)絡(luò)設(shè)備接口層、提供實(shí)際功能的設(shè)備驅(qū)動(dòng)功能層、以及網(wǎng)絡(luò)設(shè)備和網(wǎng)絡(luò)媒介層。26驅(qū)動(dòng)模
17、塊編寫測(cè)試步驟編寫模塊代碼編譯代碼 gcc 加載模塊insmod 查看設(shè)備號(hào)/proc/device映射為設(shè)備文件 mknod /dev/fs c 254 0編寫測(cè)試代碼生成可執(zhí)行測(cè)試文件運(yùn)行測(cè)試27#include#include#include#include#include#include#include#include#includeMODULE_LICENSE(GPL);unsignedinttest_major=254;/設(shè)備號(hào)char*str_test;/存放內(nèi)存空間的指針unsignedintcount_driver;/當(dāng)前內(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)/申請(qǐng)256字節(jié)的內(nèi)存空間printk(kmallocerrorn);return-1;Elseprintk(kamllocsuccess!n);count_driver=0;return0; 29open和close的實(shí)現(xiàn), 只是一個(gè)計(jì)數(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ù)的實(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è)備號(hào),0為次設(shè)備號(hào)。33Test_w.c#include#include#include#includeint main(void)int i;in
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 冷拔導(dǎo)軌企業(yè)縣域市場(chǎng)拓展與下沉戰(zhàn)略研究報(bào)告
- 管式沉砂裝置企業(yè)數(shù)字化轉(zhuǎn)型與智慧升級(jí)戰(zhàn)略研究報(bào)告
- 2025年聲樂演唱職業(yè)能力測(cè)試卷:中級(jí)聲樂演唱技巧與音樂鑒賞試題
- 2025年輔導(dǎo)員選拔考試:學(xué)生心理危機(jī)干預(yù)心理危機(jī)干預(yù)措施與技巧試題
- 2025年司法考試刑法刑法適用模擬試題試卷
- 農(nóng)夫車(UTV)企業(yè)縣域市場(chǎng)拓展與下沉戰(zhàn)略研究報(bào)告
- 2025年造價(jià)工程師案例分析模擬試卷:工程造價(jià)編制與審查實(shí)務(wù)試題
- 聚羥基脂肪酸酯(PHA)企業(yè)縣域市場(chǎng)拓展與下沉戰(zhàn)略研究報(bào)告
- 2025年小學(xué)教師資格考試《綜合素質(zhì)》模擬面試題庫(含答案)教育政策法規(guī)案例分析題解析
- 電機(jī)定子鐵芯迭壓機(jī)企業(yè)ESG實(shí)踐與創(chuàng)新戰(zhàn)略研究報(bào)告
- 山西省晉中市介休市2023-2024學(xué)年下學(xué)期期中測(cè)試七年級(jí)歷史試卷
- 風(fēng)機(jī)性能綜合測(cè)試系統(tǒng)的研究與開發(fā)的開題報(bào)告
- JJG 365-2008電化學(xué)氧測(cè)定儀
- 期中模擬測(cè)試卷(試卷)-2023-2024學(xué)年一年級(jí)下冊(cè)數(shù)學(xué)人教版
- 民宿服務(wù)培訓(xùn)課件
- 公路養(yǎng)護(hù)安全意識(shí)培訓(xùn)
- 控制性詳細(xì)規(guī)劃城市用地分類和代號(hào)
- 鐵路專用線設(shè)計(jì)規(guī)范(試行)(TB 10638-2019)
- 主題一+鞋子擦洗自己做+第二課時(shí)(課件)-甘肅教育出版社勞動(dòng)三年級(jí)+下冊(cè)
- ISO 45003-2021職業(yè)健康安全管理-工作中的心理健康安全-社會(huì)心理風(fēng)險(xiǎn)管理指南(中文版)
- 三年級(jí)語文 寫通知(全國一等獎(jiǎng))
評(píng)論
0/150
提交評(píng)論