




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、Linux中設備分類:按照對設備的訪問方式可分為以下三類:1. 字符設備(char device)(1) 例如:鍵盤、鼠標、串口、幀緩存等;(2) 通過/dev/下的設備節(jié)點訪問;以字節(jié)為單位訪問;(3) 一般只支持順序訪問;(特例:幀緩存framebuffer)(4) 無緩沖。2. 塊設備(block device)(1) 例如:磁盤、光驅、flash等;(2) 以固定大小為單位訪問:磁盤以扇區(qū)(512B)為單位;flash以頁為單位。(3) 支持隨機訪問;(4) 有緩沖(減少磁盤IO,提高效率)。3. 網絡設備(network device)(1) 無設備文件(節(jié)點);(2) 應用層通過s
2、ocket接口訪問網絡設備(報文發(fā)送和接收的媒介)。設備驅動在內核中的結構:1. VFS虛擬文件系統(tǒng)作用:向應用層提供一致的文件訪問接口,正是由于VFS的存在,才可以將設備以文件的方式訪問。2. 虛擬文件系統(tǒng),存在于內存中,不在磁盤上,掉電丟失。例如:/proc、/sys、/tmp。設備號:1. 作用:唯一地標識一個設備;2. 類型:dev_t devno;即32位無符號整型;3. 組成:31 主設備號major 2019 次設備號minor 0(1) 主設備號:用于區(qū)分不同類型(按功能劃分)的設備;(2) 此設備號:用于區(qū)分相同類型的不同設備。注意:相同類型的設備(主設備號相同)可以使用同一
3、個驅動。4. 構建設備號:int major = 250; int minor = 0;(1) dev_t devno = (major << 20) | minor;不建議使用;(2) 利用宏來構建:dev_t devno = MKDEV (major, minor);注意:我們可以通過文件$(srctree)/documentation/device.txt來查看內核對設備號的分配情況。(1) 該文本中的有對應設備文件的設備號是已經被申請過的,我們不可以重復使用(申請);(2) 從中可以看出,我們在編寫驅動程序時可以使用的主設備號范圍為240254,為了方便記憶,通常使用250
4、作為主設備號。字符設備驅動框架:驅動:作用,為應用層提供訪問設備的接口(對設備發(fā)的各種操作)。一、 申請設備號1. 構建設備號:dev_t devno = MKDEV (major, minor);2. 申請設備號:(1) 動態(tài)申請:alloc_chrdev_region;(2) 靜態(tài)申請: register_chrdev_region。(3) 靜態(tài)申請設備號的優(yōu)缺點:優(yōu)點:可以提前創(chuàng)建設備文件;缺點:有可能會發(fā)成沖突,導致申請失敗。(4) register_chrdev_region函數詳解:注意: 最后一個參數是設備名稱。且在/proc/devices下會有關于當前系統(tǒng)已經注冊成功的設備信
5、息; 申請設備號應在加載函數中實現(xiàn);同時,在卸載函數中我們也要調用unregister_chrdev_region來釋放設備號。二、 實現(xiàn)操作集合struct file_operations struct file_operations struct module *owner;loff_t (*llseek) (struct file *, loff_t, int);ssize_t (*read) (struct file *, char _user *, size_t, loff_t *);ssize_t (*write) (struct file *,const char _user *
6、,size_t,loff_t *);unsigned int (*poll) (struct fiel *, poll_table *);int (*fasync) (int, struct file *, int);long (*unlock_ioctl) (struct file *, unsigned int, unsigned long);int (*mmap) (struct file *, struct vm_area_struct *);int (*open) (struct inode *, struct file *);int (*release) (struct inode
7、 *, struct file *);int (*flush) (struct file *, fl_owner_t id);int (*lock) (struct file *, int, struct file_lock *);除owner成員外,其他成員均是對文件進行相關操作的函數指針。1. 對設備的大多數操作函數都有參數struct file *filp;2. 在起始階段我們可以先定義一個空的操作集合:struct file_operations .owner = THIS_MODULE ;注意:(1) 可以看出宏THIS_MODULE代表結構體struct module的起始地址;(
8、2) 我們可以通過“.<struct_member_name> = <>,”語法來給結構體指定成員賦值。三、 注冊字符設備:1. 通過結構體struct cdev將設備號devno和操作集合file_operations關聯(lián)起來;2. 并將cdev結構體加入到內核維護的cdev鏈表中。(計算機系統(tǒng)支持很多字符設備,內核會維護一個cdev鏈表,這樣我們就可以通過設備號找到對應的操作集合了)3. cdev結構體的定義如下:4. 我們通過調用內核函數cdev_init和cdev_add來完成字符設備的注冊。注意:注冊字符設備應在加載函數中實現(xiàn);同時,在卸載函數中,我們要調用c
9、dev_del函數來注銷字符設備。且注銷字符設備應在釋放設備號之前進行。應用層如何訪問設備:1. 在Linux中一切皆文件;2. 因為VFS(向應用層提供一致的文件訪問接口),應用層也可以將設備當做文件來訪問;3. 應用層要想訪問設備,首先要創(chuàng)建設備節(jié)點:命令:mknod <device_name> c/b <major> <minor>注意:(1) mknod /dev/hello c 250 0(2) mknod /dev/hello c 250 1 錯誤;(3) mknod /dev/hello1 c 250 0 正確,即可以有多個設備節(jié)點指向同一個設
10、備。操作集合打開open:1. 統(tǒng)計計數,檢查錯誤;(一個設備可以被多個進程打開)2. 申請資源:(1) 在xxx_open()函數中也可以申請資源;(2) 若在open中申請資源,則對應要在release中釋放資源;(3) 若在加載函數中申請資源,則對應要在卸載函數中釋放資源。3. 識別次設備號。(在一個驅動識別多個設備中有應用)4. 在應用層調用open函數打開設備的實現(xiàn)過程:(1) int fd = open (“/dev/hello”, O_RDWR);(2) sys_open();系統(tǒng)調用(3) vfs_open();虛擬文件系統(tǒng)提供的操作接口注意:在vfs_open()函數執(zhí)行時,
11、會在內存中創(chuàng)建兩個結構體: struct inode dev_t i_rdev; struct cdev *i_cdev;記錄所打開文件的靜態(tài)信息;是將磁盤上的inode節(jié)點信息讀過來的。 struct file struct file *f_op;記錄所打開文件的動態(tài)信息:包括打開方式、當前讀寫位置、用戶信息等。(4) xxx_open(struct inode *, struct file *);注意: 應用層的文件描述符fd與內核中的struct file結構體是一一對應的,即每打開一個設備文件,就會在內存中創(chuàng)建一個struct file類型的結構體變量。每個進程都維護有一個文件描述符表
12、:fd與struct file的對應關系。 與xxx_open()函數相對應的是xxx_release()函數。(1) file結構體:(文件的靜態(tài)屬性)struct fileconst struct file_operations *f_op;/操作集合結構體指針unsigned int f_flags;/文件打開方式:如O_NONBLOCKloff_t f_ops;/當前讀寫位置void *private_data;/文件私有數據,通常用來存放設備結構體的地址;應用: 在多個同類型的設備共用一個驅動程序時:為了在驅動中識別不同的設備,可以將設備結構體的地址保存到file結構體的私有成員中;
13、 利用file結構體的f_flags成員,判斷進程是以阻塞還是非阻塞方式訪問文件。(2) inode結構體:(文件的動態(tài)信息)struct inodeumode_t i_mode;/inode的權限uid_t i_uid;/inode擁有者的idgid_t i_gid;/inode所屬的組iddev_t i_rdev;/設備號struct timespec i_atime;/inode最近一次的存取時間struct timespec i_mtime;/inode最近一次的修改時間struct timespec i_ctime;/inode的產生時間union /若是塊設備,為其對應的block
14、_device結構體指針struct block_device *i_bdev;struct cdev *i_cdev;/若是字符設備,為其對應的cdev結構體指針;讀read:相應地,read()->sys_read()->vfs_read()->xxx_read()->copy_to_user。APP:ssize_t read (int fd, void *buf, size_t count);driver:ssize_t xxx_read (struct file *,char _user *,size_t,loff_t *);讀(寫)操作在內核空間和用戶空間會發(fā)
15、生數據交互。在xxx_read(xxx_write)函數中我們通過調用內核函數:copy_to_user(cpy_from_user)將數據返回給用戶buffer(將用戶數據讀到本地buffer)。1. read()函數:(1) 成功:返回實際讀到的字節(jié)數;(2) 失?。悍祷?1并設置errno(非負)。注意:errno就是通過將xxx_read()函數的失敗返回值取絕對值得到的。2. xxx_read()函數:(1) 成功:返回實際讀到的字節(jié)數;(2) 失?。悍祷刎摰腻e誤碼-EFAULT。3. copy_to_user()函數:(1) 成功:返回0;(2) 失?。悍祷厥S鄾]有拷貝成功的字節(jié)數
16、。注意:(1) copy_to_user和copy_from_user在執(zhí)行時進程有可能會阻塞(sleep),所以不能用于中斷處理;(2) copy_from_user():成功返回0;失敗返回剩余沒有寫成功的字節(jié)數。(3) 二者包含在頭文件<asm/uaccess.h>中。實例:mmap操作:一些設備,諸如:video/audio/framebuffer,在用戶空間和內核空間之間會有很多的數據交互,使用copy_to_user/copy_from_user,要在用戶空間和內核空間進行不斷地切換,開銷太大。我們可以利用mmap操作,作用:將設備內存映射到用戶空間訪問,減小開銷。(類
17、似于進程間通信的共享內存機制)ioctl操作:對設備的訪問控制,如果都用讀寫操作來實現(xiàn),未免開銷太大;例如,控制LED燈的亮滅,我們完全可以利用ioctl函數來實現(xiàn)。APP:int ioctl (int d, int request, . . .);driver:long (*unlock_ioctl) (struct file *,unsigned int,unsigned long);注意:在2.6.35內核之前,應用層ioctl函數驅動中的ioctl函數指針;在2.6.35內核之后,則對應unlock_ioctl函數指針。ioctl操作是通過命令字來控制底層設備的,命令字的組成如下:8b
18、it:type類型8bit:nr編號2bit:dir數據方向14bit:size數據尺寸用2bit來表示數據傳輸方向,有4種情況:無數據傳輸、用戶->內核、內核->用戶、雙向傳輸。通常,我們利用ioctl操作來控制設備,不涉及數據傳輸。內核通過四個宏用來定義命令字,且命令字要在驅動中和應用程序中約定好:_IO/_IOR/_IOW/_IORW。實例:利用ioctl對串口波特率進行讀寫:(1) 獲取波特率:int baudrate; ioctl(fd, GET_BAUD,(unsigned long)&baudrate); 為了保存波特率,我們需要對參數進行強制類型轉換。(2) 設置波特率:ioctl(fd, SET_BAUD, 115200);注意:(1) 處于安全考慮,在用戶操作設備時,需要判斷進程是否具有管理員的權限;(2) 我們可以調用內核capable()函數來判斷進程的權限:返回值為0,無權限;返回值為1,有權限。驅動程序的調試:1. /printk注釋2. #ifde
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- DB31/ 734-2020淀粉糖單位產品能源消耗限額
- 聚噻吩纖維單體合成與性能考核試卷
- 絹紡和絲織的環(huán)保生產考核試卷
- 六年級下冊作文教案
- 碎片化學習的測試方法試題及答案
- 海關關員崗位海關事務代理服務聘用合同
- 影視音樂制作團隊保密及合作協(xié)議
- 環(huán)保型流水線工人勞動權益保障協(xié)議
- 環(huán)保設施維護保養(yǎng)及優(yōu)化升級合同
- 2025年中國北京旅游行行業(yè)市場前景預測及投資價值評估分析報告
- 2025年浙江省寧波市一??茖W試卷
- 智能制造對融資租賃行業(yè)影響-全面剖析
- 2025年新高考語文【語言運用新題型】考前訓練試卷附答案解析
- GB 29743.2-2025機動車冷卻液第2部分:電動汽車冷卻液
- 安全人機工程學-人因事故分析與預防報告課件
- 生物有機肥試驗方案
- 江蘇省南通市合作盟校2025年高考化學四模試卷含解析
- 2025年小升初語文《分析人物形象》教學講義及專項練習題(附答案)
- 超星爾雅學習通《中華文化才藝(中國海洋大學)》2025章節(jié)測試附答案
- 大數據與人工智能在財務管理中的深度應用研究
- 《AI技術術語解析》課件
評論
0/150
提交評論