版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、Linux設(shè)備驅(qū)動(dòng)程序開發(fā)基礎(chǔ)主講人:TonyShenLinux設(shè)備驅(qū)動(dòng)程序開發(fā)基礎(chǔ)主講人:TonyShen課程目標(biāo)Linux設(shè)備驅(qū)動(dòng)程序開發(fā)簡介Linux設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)Linux設(shè)備驅(qū)動(dòng)程序加載方式實(shí)驗(yàn):編寫一個(gè)字符設(shè)備驅(qū)動(dòng)程序(LED或蜂鳴器)分別用靜態(tài)編譯,模塊動(dòng)態(tài)加載方法實(shí)現(xiàn)加入內(nèi)核課程目標(biāo)設(shè)備驅(qū)動(dòng)程序應(yīng)用程序驅(qū)動(dòng)程序設(shè)備writereadioctlioctl設(shè)備驅(qū)動(dòng)程序應(yīng)驅(qū)設(shè)writereadioctlioctl設(shè)備驅(qū)動(dòng)程序特點(diǎn)核心代碼:設(shè)備驅(qū)動(dòng)程序是核心的一部分,像核心中其他的代碼一樣,出錯(cuò)將導(dǎo)致系統(tǒng)的嚴(yán)重?fù)p傷。一個(gè)編寫不當(dāng)?shù)脑O(shè)備驅(qū)動(dòng)程序甚至能夠使系統(tǒng)崩潰導(dǎo)致文件系統(tǒng)的破壞和數(shù)據(jù)
2、的丟失;標(biāo)準(zhǔn)接口:設(shè)備驅(qū)動(dòng)程序必須為Linux核心或者其從屬的子系統(tǒng)提供一個(gè)標(biāo)準(zhǔn)的接口;核心機(jī)制:設(shè)備驅(qū)動(dòng)程序可以使用標(biāo)準(zhǔn)的核心服務(wù)比如內(nèi)存分配、中斷發(fā)送和等待對列等;動(dòng)態(tài)可加載:多數(shù)的Linux設(shè)備驅(qū)動(dòng)程序可以在核心模塊發(fā)出加載請求時(shí)進(jìn)行加載,同時(shí)在不使用設(shè)備時(shí)進(jìn)行卸載,這樣核心可以有效地利用系統(tǒng)的資源可配置:Linux設(shè)備驅(qū)動(dòng)屬于核心的一部分,用戶可以根據(jù)自己的需要進(jìn)行配置來選擇適合自己的驅(qū)動(dòng)設(shè)備驅(qū)動(dòng)程序特點(diǎn)核心代碼:設(shè)備驅(qū)動(dòng)程序是核心的一部分,像核用戶態(tài)與內(nèi)核態(tài)Linux運(yùn)轉(zhuǎn)在兩種模式下,一種是用戶態(tài),另一種是內(nèi)核態(tài)。內(nèi)核態(tài)有較高的權(quán)限,可以控制處理器內(nèi)存的映射和分配方式,訪問外設(shè)空間和
3、處理器狀態(tài)寄存器,控制中斷等。用戶態(tài)只能運(yùn)行系統(tǒng)上的應(yīng)用程序。驅(qū)動(dòng)程序作為系統(tǒng)內(nèi)核的一部分,工作在內(nèi)核態(tài)。通過get_user put_user copy_from_user copy_to_user等函數(shù)實(shí)現(xiàn)應(yīng)用程序和驅(qū)動(dòng)程序之間傳送數(shù)據(jù)(指針)。用戶態(tài)與內(nèi)核態(tài)Linux運(yùn)轉(zhuǎn)在兩種模式下,一種是用戶態(tài),另一Linux設(shè)備的分類字符設(shè)備以字節(jié)為單位逐個(gè)進(jìn)行I/O操作字符設(shè)備中的緩存是可有可無不支持隨機(jī)訪問如串口設(shè)備塊設(shè)備塊設(shè)備的存取是通過buffer、cache來進(jìn)行可以進(jìn)行隨機(jī)訪問例如IDE硬盤設(shè)備可以支持可安裝文件系統(tǒng)網(wǎng)絡(luò)設(shè)備通過BSD套接口訪問Linux設(shè)備的分類字符設(shè)備設(shè)備文件Linu
4、x抽象了對硬件的處理,所有的硬件設(shè)備都可以作為普通文件一樣來看待可以使用和操作文件相同的、標(biāo)準(zhǔn)的系統(tǒng)調(diào)用接口來完成打開、關(guān)閉、讀寫和I/O控制操作對用戶來說,設(shè)備文件與普通文件并無區(qū)別字符設(shè)備和塊設(shè)備是通過文件節(jié)點(diǎn)訪問的。在Linux的文件系統(tǒng)中,可以找到(或者使用mknod創(chuàng)建)設(shè)備對應(yīng)的文件名,稱這種文件為設(shè)備文件。設(shè)備文件設(shè)備文件命令 ls l /dev 可列出系統(tǒng)的設(shè)備文件設(shè)備文件命令 ls l /dev 可列出系統(tǒng)的設(shè)備文件主設(shè)備號和次設(shè)備號主設(shè)備號:標(biāo)識(shí)該設(shè)備的種類,也標(biāo)識(shí)了該設(shè)備所使用的驅(qū)動(dòng)程序主設(shè)備號的范圍只能是1-255Linux內(nèi)核支持動(dòng)態(tài)分配主設(shè)備號次設(shè)備號:標(biāo)識(shí)使用同一
5、設(shè)備驅(qū)動(dòng)程序的不同硬件設(shè)備同一個(gè)驅(qū)動(dòng)程序可以管理多個(gè)設(shè)備,它們依靠次設(shè)備號來區(qū)別。次設(shè)備號只在驅(qū)動(dòng)程序內(nèi)部使用,系統(tǒng)內(nèi)核直接把次設(shè)備號傳遞給驅(qū)動(dòng)程序,由驅(qū)動(dòng)程序去管理。主設(shè)備號和次設(shè)備號主設(shè)備號:標(biāo)識(shí)該設(shè)備的種類,也標(biāo)識(shí)了該設(shè)備設(shè)備文件系統(tǒng)Linux內(nèi)核自己管理設(shè)備文件,完成設(shè)備文件節(jié)點(diǎn)的創(chuàng)建、刪除。(devfs,device file system)在linux2.4/2.6內(nèi)核中,設(shè)備文件系統(tǒng)可在配置內(nèi)核時(shí)定制。linux2.4內(nèi)核配置層次 File systems -/dev file system supportlinux2.6內(nèi)核配置層次 File systems -Pseudo f
6、ile system -/dev file system support系統(tǒng)驅(qū)動(dòng)程序通過CONFIG_DEVFS_FS宏定義判斷系統(tǒng)是否有對設(shè)備文件系統(tǒng)的支持。設(shè)備文件系統(tǒng)Linux內(nèi)核自己管理設(shè)備文件,完成設(shè)備文件節(jié)點(diǎn)配置設(shè)備文件系統(tǒng)配置設(shè)備文件系統(tǒng)Linux設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)Linux設(shè)備驅(qū)動(dòng)程序的代碼結(jié)構(gòu)大致可以分為如下幾個(gè)部分:驅(qū)動(dòng)程序的注冊與注銷、設(shè)備的打開與釋放、設(shè)備的讀寫操作、設(shè)備的控制操作、設(shè)備的中斷和輪詢處理。一個(gè)最簡單字符驅(qū)動(dòng)程序,由下面5個(gè)函數(shù)和1個(gè)結(jié)構(gòu)體就可組成。static int my_open(struct inode * inode, struct file *
7、filp) 設(shè)備打開時(shí)的操作 static int my_release(struct inode * inode, struct file * filp) 設(shè)備關(guān)閉時(shí)的操作 static int my_write(struct file *file, const char * buffer, size_t count, loff_t * ppos) 設(shè)備寫入時(shí)的操作 Linux設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)Linux設(shè)備驅(qū)動(dòng)程序的代碼結(jié)構(gòu)大驅(qū)動(dòng)程序結(jié)構(gòu)static struct file_operations my_fops = 對文件操作結(jié)構(gòu)體成員定義初始值static int _init my_ini
8、t(void)初始化硬件,注冊設(shè)備,創(chuàng)建設(shè)備節(jié)點(diǎn) static void _exit my_exit(void)刪除設(shè)備節(jié)點(diǎn),注銷設(shè)備 驅(qū)動(dòng)程序結(jié)構(gòu)static struct file_opera頭文件與系統(tǒng)定義#include #include #include #include #include #include #include #include 9200.h“#ifndef _KERNEL_#define _KERNEL_#endif#ifndef MODULE#define MODULE#endif#define LED AT91C_PIO_PB11static AT91PS_SYS
9、 AT91_SYS1 = (AT91PS_SYS) AT91C_VA_BASE_SYS;#define DEVICE_NAME = “my_led”static int Led_Major = 0;#ifdef CONFIG_DEVFS_FSstatic devfs_handle_t Devfs_Led_Dir, Devfs_Led_Raw;#endif頭文件與系統(tǒng)定義#include linux/module打開和關(guān)閉操作my_open和my_release函數(shù)會(huì)在設(shè)備打開和關(guān)閉時(shí)被調(diào)用,其工作很簡單,僅僅執(zhí)行兩個(gè)宏:”MOD_INC_USE_COUNT”,”MOD_DEC_USE_COUN
10、T”。這兩個(gè)宏負(fù)責(zé)記錄(增加或者減少)設(shè)備模塊被使用的情況,防止當(dāng)有應(yīng)用程序使用驅(qū)動(dòng)程序時(shí),此模塊被意外地卸載。static int my_open(struct inode * inode, struct file * filp)MOD_INC_USE_COUNT;return 0; static int my_release(struct inode * inode, struct file * filp MOD_DEC_USE_COUNT return 0; 打開和關(guān)閉操作my_open和my_release函數(shù)會(huì)在設(shè)寫入操作static int my_write(struct file
11、 *file, const char * buffer, size_t count, loff_t * ppos) char led_status = 0; copy_from_user(&led_status, buffer, sizeof(led_status); if(led_status = 0 x01)/如果應(yīng)用程序傳來的數(shù)據(jù)是0 x01AT91F_PIOB_SetOutput(LED);/打開LED elseAT91F_PIOB_ClearOutput(LED); /關(guān)閉LED return 0;寫入操作static int my_write(struct文件操作結(jié)構(gòu)體初始化sta
12、tic struct file_operations my_fops = open: my_open,write: my_write,release:my_release,;文件操作結(jié)構(gòu)體初始化static struct file_ostruct file_operationsstruct module *owner;loff_t (*llseek) (struct file *, loff_t, int);ssize_t(*read) (struct file *, char *, size_t, loff_t*);ssize_t(*write) (struct file *, const
13、char *, size_t, loff_t*);int(*readdir) (struct file *, void *, filldir_t);unsigned 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
14、 *);int(*flush) (struct file *);int(*release) (struct inode*, struct file *);int(*fsync) (struct file *, struct dentry*, intdatasync);int(*fasync) (int, struct file *, int);int(*lock) (struct file *, int, struct file_lock*);ssize_t(*readv) (struct file *, const struct iovec*, unsigned long, loff_t*)
15、;ssize_t(*writev) (struct file *, const struct iovec*, unsigned long, loff_t*);ssize_t(*sendpage) (struct file *, struct page *, int, size_t, loff_t*, int);unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);文件操作結(jié)構(gòu)體struct file_operations文件操作結(jié)
16、設(shè)備初始化static int _init my_init(void)/硬件初始化 AT91F_PIOB_Enable(LED);AT91F_PIOB_OutputEnable(LED);/字符設(shè)備注冊Led_Major = register_chrdev(0, DEVICE_NAME, &my_fops);if (Led_Major 0)printk(DEVICE_NAME cant get major numbern);return Led_Major;/ 創(chuàng)建設(shè)備文件#ifdef CONFIG_DEVFS_FS Devfs_Led_Dir = devfs_mk_dir(NULL, led
17、, NULL); Devfs_Led_Raw = devfs_register(Devfs_Led_Dir, 0, DEVFS_FL_DEFAULT, Led_Major, 1, S_IFCHR|S_IRUSR|S_IWUSR,&my_fops, NULL);#endif設(shè)備初始化static int _init my_init設(shè)備注銷static void _exit my_exit(void)/刪除設(shè)備文件#ifdef CONFIG_DEVFS_FSdevfs_unregister(Devfs_Led_Raw);devfs_unregister(Devfs_Led_Dir);#endif/
18、注銷設(shè)備unregister_chrdev(Led_Major, DEVICE_NAME);module_init(my_init); /向Linux系統(tǒng)記錄設(shè)備初始化的函數(shù)名稱module_exit(my_exit); /向Linux系統(tǒng)記錄設(shè)備退出的函數(shù)名稱設(shè)備注銷static void _exit my_exit驅(qū)動(dòng)程序編譯Makefile文件內(nèi)容OBJ=io_led.oSOURCE=io_led.cCC=arm-linux-gccCOMP=-Wall -O2 -DMODULE -D_KERNEL_ -I /home/armlinux/linux-2.4.19-rmk7/include
19、c$(OBJ):$(SOURCE)$(CC) $(COMP) $(SOURCE)clean:rm $(OBJ)運(yùn)行make 命令,編譯通過后當(dāng)前目錄下就生成名為io_led.o的驅(qū)動(dòng)程序驅(qū)動(dòng)程序編譯Makefile文件內(nèi)容OBJ=io_led.o驅(qū)動(dòng)程序加載Linux內(nèi)核有2種加載驅(qū)動(dòng)程序的方法:Linux系統(tǒng)啟動(dòng)時(shí),通過代碼自身加載模塊.這種方式稱為靜態(tài)編譯入內(nèi)核, 驅(qū)動(dòng)程序開發(fā)完畢后一般使用這種方式.Linux系統(tǒng)啟動(dòng)后,通過insmod等命令加載模塊.這種方式稱為動(dòng)態(tài)加載,驅(qū)動(dòng)程序開發(fā)調(diào)試過程中一般使用這種方式.驅(qū)動(dòng)程序加載模塊動(dòng)態(tài)加載驅(qū)動(dòng)程序模塊插入內(nèi)核查看是否載入,如果載入成功會(huì)顯示你的設(shè)備名稱my_led從內(nèi)核移除設(shè)備#insmod io_led.o#cat /proc/devices#rmmod io_led模塊動(dòng)態(tài)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(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ǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 意識(shí)的課件教學(xué)課件
- 2024年建筑工程施工合同詳細(xì)描述
- 2024年度戰(zhàn)略合作合同(含合作領(lǐng)域)
- 春艾青課件教學(xué)課件
- 2024年度水果品牌授權(quán)合同:授權(quán)生產(chǎn)和銷售的具體條款
- 2024年度金融服務(wù)合同:銀行為客戶提供2024年度綜合金融服務(wù)
- 2024年專利實(shí)施許可合同:生物醫(yī)藥產(chǎn)品專利應(yīng)用
- 2024年度航空器材買賣合同
- 幼兒清明課件教學(xué)課件
- 毛筆楷體課件教學(xué)課件
- 火災(zāi)逃生與自救技能培訓(xùn)
- 新高中歷史課標(biāo)思路15.5課件
- 煤氣發(fā)生爐拆除方案
- 債權(quán)人自愿放棄債權(quán)承諾書
- 國際經(jīng)濟(jì)與貿(mào)易專業(yè)生涯人物訪談報(bào)告
- xxxx學(xué)校教育事業(yè)統(tǒng)計(jì)工作總結(jié)
- “大力弘揚(yáng)教育家精神”2023征文10篇
- 《扣件式鋼管腳手架安全技術(shù)規(guī)范》JGJ130-2023
- 《雅思考試介紹》課件
- 2021音樂表演職業(yè)生涯規(guī)劃書
- 幼兒園安全教育課件:《危險(xiǎn)的小圓珠》
評論
0/150
提交評論