Linux設(shè)備驅(qū)動程序設(shè)計(jì)完全教程.ppt_第1頁
Linux設(shè)備驅(qū)動程序設(shè)計(jì)完全教程.ppt_第2頁
Linux設(shè)備驅(qū)動程序設(shè)計(jì)完全教程.ppt_第3頁
Linux設(shè)備驅(qū)動程序設(shè)計(jì)完全教程.ppt_第4頁
Linux設(shè)備驅(qū)動程序設(shè)計(jì)完全教程.ppt_第5頁
已閱讀5頁,還剩23頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、Linux 設(shè)備驅(qū)動程序設(shè)計(jì),Linux設(shè)備驅(qū)動程序設(shè)計(jì),郗閩軍 牛建偉,實(shí)驗(yàn)?zāi)康?學(xué)習(xí)Linux下進(jìn)行驅(qū)動程序設(shè)計(jì)的原理 掌握Linux設(shè)備驅(qū)動程序開發(fā)的基本過程和設(shè)計(jì)方法,實(shí)驗(yàn)內(nèi)容,內(nèi)核驅(qū)動設(shè)計(jì)入門模塊方式驅(qū)動程序(5.1) 內(nèi)核驅(qū)動設(shè)計(jì)實(shí)驗(yàn)觸摸屏驅(qū)動(5.2) 寫一個(gè)簡單的應(yīng)用程序,顯示觸摸位置的坐標(biāo)(x,y) 開發(fā)一個(gè)LED(數(shù)碼管)驅(qū)動程序,并編寫一個(gè)應(yīng)用程序?qū)λ_發(fā)的驅(qū)動程序進(jìn)行測試(大作業(yè)) 實(shí)驗(yàn)實(shí)現(xiàn)的功能是上電復(fù)位后,數(shù)碼管顯示數(shù)字0-7,然后每一個(gè)數(shù)字依次閃爍一次,小數(shù)點(diǎn)也要點(diǎn)亮,即: 0.1.2.3.4.5.6.7.,Linux的設(shè)備驅(qū)動程序,硬件設(shè)備與應(yīng)用程序之間的一個(gè)中

2、間軟件層 它使得某個(gè)特定硬件能夠響應(yīng)一個(gè)定義良好的內(nèi)部編程接口,同時(shí)完全隱蔽了設(shè)備的工作細(xì)節(jié) 用戶通過一組與具體設(shè)備無關(guān)的標(biāo)準(zhǔn)化的調(diào)用來完成相應(yīng)的操作 驅(qū)動程序的任務(wù)就是把這些標(biāo)準(zhǔn)化的系統(tǒng)調(diào)用映射到具體設(shè)備對于實(shí)際硬件的特定操作上 驅(qū)動程序是內(nèi)核的一部分,可以使用中斷、DMA等操作 驅(qū)動程序在用戶態(tài)和內(nèi)核態(tài)之間傳遞數(shù)據(jù),設(shè)備驅(qū)動程序的分類,字符設(shè)備 所有能夠象字節(jié)流一樣訪問的設(shè)備都通過字符設(shè)備來實(shí)現(xiàn) 它們被映射為文件系統(tǒng)中的節(jié)點(diǎn),通常在/dev/目錄下面 一般要包含open read write close等系統(tǒng)調(diào)用的實(shí)現(xiàn) 塊設(shè)備 通常是指諸如磁盤、內(nèi)存、Flash等可以容納文件系統(tǒng)的存儲設(shè)備

3、。 塊設(shè)備也是通過文件系統(tǒng)來訪問,與字符設(shè)備的區(qū)別是:內(nèi)核管理數(shù)據(jù)的方式不同 它允許象字符設(shè)備一樣以字節(jié)流的方式來訪問,也可一次傳遞任意多的字節(jié)。 網(wǎng)絡(luò)接口設(shè)備 通常它指的是硬件設(shè)備,但有時(shí)也可能是一個(gè)軟件設(shè)備(如回環(huán)接口loopback),它們由內(nèi)核中網(wǎng)絡(luò)子系統(tǒng)驅(qū)動,負(fù)責(zé)發(fā)送和接收數(shù)據(jù)包。 它們的數(shù)據(jù)傳送往往不是面向流的,因此很難將它們映射到一個(gè)文件系統(tǒng)的節(jié)點(diǎn)上。,基本概念,主設(shè)備號和次設(shè)備號 主設(shè)備號和次設(shè)備號能夠唯一地標(biāo)識一個(gè)設(shè)備 128(V2.0以前), 256(V2.0以后) 主設(shè)備號相同的設(shè)備使用相同的驅(qū)動程序,次設(shè)備號用于區(qū)分具體設(shè)備的實(shí)例 動態(tài)獲取主設(shè)備號 Linux下對設(shè)備號

4、的分配請參考Documentation/devices.txt 設(shè)備文件 Linux使用設(shè)備文件來統(tǒng)一對設(shè)備的訪問接口,將設(shè)備文件放在/dev/目錄下 設(shè)備的命名一般為設(shè)備文件名+數(shù)字或者字母表示的子類,例如/dev/hda1, /dev/hda2等 Linux 2.4以后引入了設(shè)備文件系統(tǒng)(devfs)的概念,所有的設(shè)備文件作為一個(gè)可以掛裝的文件系統(tǒng),這樣就可以被文件系統(tǒng)統(tǒng)一管理,從而設(shè)備文件就可以掛裝到任何需要的地方。一般將主設(shè)備建立一個(gè)目錄,再將具體的子設(shè)備文件建立在此目錄下。例如,/dev/mtdblock0,基本概念,驅(qū)動程序使用的2個(gè)重要結(jié)構(gòu) struct file struct

5、file_operations,基本概念,struct file,基本概念,struct file數(shù)據(jù)結(jié)構(gòu) 定義位于include/fs.h struct file結(jié)構(gòu)與驅(qū)動相關(guān)的成員 mode_t f_mode標(biāo)識文件的讀寫權(quán)限 loff_t f_pos當(dāng)前讀寫位置 unsigned int_f_flag文件標(biāo)志,主要進(jìn)行阻塞/非阻塞型操作時(shí)檢查 struct file_operation * f_op 文件操作的結(jié)構(gòu)指針 void * private_data驅(qū)動程序一般將它指向已經(jīng)分配的數(shù)據(jù) struct dentry* f_dentry 文件對應(yīng)的目錄項(xiàng)結(jié)構(gòu),基本概念,設(shè)備驅(qū)動程序接口

6、( struct file_operations), 標(biāo)記化方法: static struct file_operations demo_fops = owner: THIS_MODULE, write: demo_write, read: demo_read, ioctl: demo_ioctl, open: demo_open, release: demo_release, ;,基本概念,設(shè)備驅(qū)動程序接口( struct file_operations ) 通常所說的設(shè)備驅(qū)動程序接口是指struct file_operations ,它的定義位于include/linux/fs.h中。 在

7、嵌入式系統(tǒng)的開發(fā)中,通常只要實(shí)現(xiàn)如下幾個(gè)接口函數(shù)就能完成系統(tǒng)所需要的功能 init加載驅(qū)動程序時(shí),內(nèi)核自動調(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ū)動程序時(shí),內(nèi)核自動調(diào)用,基本概念,驅(qū)動程序注冊過程(動態(tài)分配主設(shè)備號) insmod module_name ;加載驅(qū)動程序,運(yùn)行init函數(shù)(register_chrdev(dev_Major, “module_name”, * fs ) 查看/proc/devices mknod /dev/m

8、odule_name c/b 主設(shè)備號 次設(shè)備號 rmmod module_name ;卸載驅(qū)動,運(yùn)行 exit函數(shù)(unregister_chrdev(dev_Major, “module_name”, * fs )) 用戶程序調(diào)用 Open(“/dev/module_name”, mode) ;O_RDWR Ioctl() Write() Read() Close(),開發(fā)驅(qū)動程序時(shí)須注意的事項(xiàng),中斷處理 中斷是現(xiàn)代微處理器的一個(gè)重要功能 Linux驅(qū)動程序中的中斷處理函數(shù) extern int request_irq(unsigned int irq, void(*handler)(in

9、t, void*, struct pt_regs *), unsigned long flag, const char *dev_name, void *dev_id);/請求為中斷號irq分配中斷處理函數(shù) extern void free_irq(unsigned int, void*);/釋放中斷 注意事項(xiàng) 不能向用戶空間發(fā)送或者接收數(shù)據(jù) 不能執(zhí)行有睡眠操作的函數(shù) 不能調(diào)用調(diào)度函數(shù) 謹(jǐn)慎使用全局變量(可重入) 自旋鎖的使用,基本概念,字符設(shè)備的管理 驅(qū)動程序模塊通過函數(shù) int register_chrdev(unsigned int major, const char *name, st

10、ruct file_operations *fops) 完成向內(nèi)核的注冊,其中major是主設(shè)備號,name是設(shè)備名,fops是針對該設(shè)備的驅(qū)動程序的接口。 在系統(tǒng)中為驅(qū)動程序模塊建立一個(gè)設(shè)備節(jié)點(diǎn) minjunRedHatAS $ mknod /dev/demo c 254 0 其中/dev/demo標(biāo)識設(shè)備名為demo,“c”說明是字符設(shè)備,254是指定的主設(shè)備號, 0是次設(shè)備號,基本概念,驅(qū)動程序的編譯 以demo.c為例 Makefile的形式參考實(shí)驗(yàn)指導(dǎo)書 命令行的形式 minjunRedHatAS $ armv4l-unknown-linux-gcc -Wall -c -O -D_K

11、ERNEL_ -I/home/minjun/embedded/kernel-2410s/include demo.c -o demo.o 加載驅(qū)動 minjunRedHatAS $ insmod demo.o 卸載驅(qū)動 minjunRedHatAS $ rmmod demo.o,基本概念,測試程序?qū)嵗?/test.c #include #include #include int main() int fd; fd=open(/dev/demo, O_RDWR); if(fd 0) exit(fd); /your code here read(fd, buffer, size); write(f

12、d, buffer, size); . close(fd); return 0; ,驅(qū)動程序的實(shí)現(xiàn)驅(qū)動程序框架,#include #include #include #include /* printk() */ #include /* everything. */ #include /* error codes */ #include /* size_t */ #include #include /* O_ACCMODE */ #include /* COPY_TO_USER */ #include /* cli(), *_flags */ #define DEVICE_NAMEdemo #

13、define demo_MAJOR 250 #define demo_MINOR 0 static ssize_t demo_write(struct file *filp,const char *buffer, size_t count) copy_from_user(drv_buf , buffer, count); WRI_LENGTH = count; printk(user write data to drivern); /your code here return count; ,驅(qū)動程序的實(shí)現(xiàn)驅(qū)動程序框架,static ssize_t demo_read(struct file

14、*filp, char *buffer, size_t count, loff_t *ppos) if(count MAX_BUF_LEN) count=MAX_BUF_LEN; copy_to_user(buffer, drv_buf,count); printk(user read data from drivern); return count; static int demo_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) printk(ioctl runingn);

15、switch(cmd) case 1:printk(runing command 1 n);break; case 2:printk(runing command 2 n);break; default: printk(error cmd numbern);break; return 0; static int demo_open(struct inode *inode, struct file *file) MOD_INC_USE_COUNT; sprintf(drv_buf,device open sucess!n); printk(device open sucess!n); retur

16、n 0; ,驅(qū)動程序的實(shí)現(xiàn)驅(qū)動程序框架,static int demo_release(struct inode *inode, struct file *filp) MOD_DEC_USE_COUNT; printk(device releasen); return 0; static struct file_operations demo_fops = owner:THIS_MODULE, write:demo_write, read:demo_read, ioctl:demo_ioctl, open:demo_open, release:demo_release, ; static in

17、t _init demo_init(void) SET_MODULE_OWNER(,驅(qū)動程序的實(shí)現(xiàn)驅(qū)動程序框架,open 提供給驅(qū)動程序初始化設(shè)備的能力,為后續(xù)的操作做準(zhǔn)備 此外一般會遞增使用計(jì)數(shù),防止文件關(guān)閉前模塊被卸載 通常情況下,open完成如下工作: 遞增使用計(jì)數(shù) 檢查特定設(shè)備錯(cuò)誤 如果設(shè)備是首次打開,則對其進(jìn)行初始化 識別次設(shè)備號,如有必要,則修改f_op指針 分配并填寫filp-private_data中的數(shù)據(jù) release 與open正好相反 釋放由open分配的filp-private_data中的數(shù)據(jù) 在最后一次關(guān)閉操作時(shí)關(guān)閉設(shè)備 使用計(jì)數(shù)減一,驅(qū)動程序的實(shí)現(xiàn)驅(qū)動程序框架,

18、read和write read將數(shù)據(jù)從內(nèi)核拷貝到應(yīng)用程序空間,write則將數(shù)據(jù)從應(yīng)用程序空間拷貝到內(nèi)核。 由于用戶空間和內(nèi)核空間的內(nèi)存映射方式不同,所以在內(nèi)核和用戶空間傳輸數(shù)據(jù)的時(shí)候需要使用如下的函數(shù) unsigned long copy_to_user(void *to, const void* from, unsigned long count); unsigned long copy_from_user(void *to, const void *from, unsigned long count); 在阻塞型IO中,read和write調(diào)用可能會出現(xiàn)阻塞 read調(diào)用當(dāng)前無數(shù)據(jù)可讀,

19、而又沒有數(shù)據(jù)馬上可讀,這時(shí)會睡眠并且等待,write調(diào)用也會出現(xiàn)這樣的情況 等待隊(duì)列機(jī)制wait_queue_head_t;(定義在中) 如果聲明了等待隊(duì)列并完成初始化,進(jìn)程就可以睡眠,可以調(diào)用sleep_on的不同變體來完成睡眠(函數(shù)聲明位于中) 大多數(shù)情況下應(yīng)使用“可中斷”的函數(shù),如interruptible_sleep_on。 睡眠進(jìn)程被喚醒并不一定代表有數(shù)據(jù),也有可能是被其他的信號喚醒,所以醒來后需要測試condition.,8段LED顯示器外形原理圖,一個(gè)數(shù)碼管(LED)由一個(gè)8位的字節(jié)控制 當(dāng)該位為“1”時(shí)點(diǎn)亮,為“0”時(shí)滅,LED連接原理圖,LED顯示驅(qū)動器,ZLG7290 I2

20、C LED/鍵盤 驅(qū)動器 I2C 串行接口提供鍵盤中斷信號方便與處理器接口 可驅(qū)動8 位共陰數(shù)碼管或64 只獨(dú)立LED 和64 個(gè)按鍵 可控掃描位數(shù)可控任一數(shù)碼管閃爍 提供數(shù)據(jù)譯碼和循環(huán)移位段尋址等控制 8 個(gè)功能鍵可檢測任一鍵的連擊次數(shù) 無需外接元件即直接驅(qū)LED 可擴(kuò)展驅(qū)動電流和驅(qū)動電壓 詳細(xì)資料參加課程網(wǎng)站上的: zlg7290.pdf zlg7290_led.pdf,圖1 ZLG7290引腳圖,LED顯示驅(qū)動器功能框圖,IIC基地址是0 x70 有24個(gè)8位寄存器(0 x00 x17),通過IIC總線訪問,必須是字節(jié)操作 主要寄存器 SystemReg 0 x0 FlashOnOff

21、0 x0c ScanNum 0 x0d DpRam07 0 x10-0 x17 CmdBuf02 0 x7-0 x8 兩種控制方式: -寄存器映象控制 -命令解釋控制 參考zlg7290.pdf,LED驅(qū)動程序的主要函數(shù),static int led_write(struct file* filp, const char* buffer, size_t count, loff_t* ppos) static int led_ioctl(struct inode *inode, struct file*file, unsigned int cmd, unsigned long arg) static int led_open(struct inode* inode, struct file* filp) static int led_release(struct inode* inod

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論