




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、嵌入式設(shè)備驅(qū)動(dòng)陳文智 浙江大學(xué)計(jì)算機(jī)學(xué)院2019年4月提綱l1、Linux下設(shè)備驅(qū)動(dòng)程序簡(jiǎn)介 l2、設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu) l3、設(shè)備驅(qū)動(dòng)實(shí)驗(yàn)l實(shí)驗(yàn)一:編寫(xiě)一個(gè)簡(jiǎn)單的驅(qū)動(dòng)程序 l實(shí)驗(yàn)二:設(shè)計(jì)和實(shí)現(xiàn)一個(gè)KED&LED驅(qū)動(dòng)程序 l實(shí)驗(yàn)三:靜態(tài)編譯驅(qū)動(dòng)程序,連接到內(nèi)核 l實(shí)驗(yàn)四:使用中斷方式的驅(qū)動(dòng)程序設(shè)計(jì) 1、Linux下設(shè)備驅(qū)動(dòng)程序簡(jiǎn)介l系統(tǒng)調(diào)用是操作系統(tǒng)內(nèi)核和應(yīng)用程序之間的接口 l設(shè)備驅(qū)動(dòng)程序是操作系統(tǒng)內(nèi)核和機(jī)器硬件之間的接口 lLinux設(shè)備驅(qū)動(dòng)的特點(diǎn)是可以以模塊的形式加載各種設(shè)備類(lèi)型 l因?yàn)榍度胧皆O(shè)備往往具有大量的獨(dú)有外設(shè),開(kāi)發(fā)人員需要把很多精力放在設(shè)備驅(qū)
2、動(dòng)方面 1.1 Linux設(shè)備的分類(lèi) l字符設(shè)備l以字節(jié)為單位逐個(gè)進(jìn)行I/O操作 l字符設(shè)備中的緩存是可有可無(wú) l不支持隨機(jī)訪問(wèn) l如串口設(shè)備/dev/cua0和/dev/cua1 l塊設(shè)備 l塊設(shè)備的存取是通過(guò)buffer、cache來(lái)進(jìn)行 l可以進(jìn)行隨機(jī)訪問(wèn) l例如IDE硬盤(pán)設(shè)備/dev/hda l可以支持可安裝文件系統(tǒng)l網(wǎng)絡(luò)設(shè)備 l通過(guò)BSD套接口訪問(wèn) 1.2 Linux設(shè)備文件 lLinux抽象了對(duì)硬件的處理,所有的硬件設(shè)備都可以作為普通文件一樣來(lái)看待 l可以使用和操作文件相同的、標(biāo)準(zhǔn)的系統(tǒng)調(diào)用接口來(lái)完成打開(kāi)、關(guān)閉、讀寫(xiě)和I/O控制操作 l對(duì)用戶來(lái)說(shuō),設(shè)備文件與普通文件并無(wú)區(qū)別 1.3
3、 主設(shè)備號(hào)和次設(shè)備號(hào) l主設(shè)備號(hào):標(biāo)識(shí)該設(shè)備的種類(lèi),也標(biāo)識(shí)了該設(shè)備所使用的驅(qū)動(dòng)程序l次設(shè)備號(hào):標(biāo)識(shí)使用同一設(shè)備驅(qū)動(dòng)程序的不同硬件設(shè)備 l所有已經(jīng)注冊(cè)即已經(jīng)加載了驅(qū)動(dòng)程序的硬件設(shè)備的主設(shè)備號(hào)可以從/proc/devices文件中得到 l rootwzchent# mknod /dev/lp0 c 6 01.4 Linux設(shè)備驅(qū)動(dòng)代碼的分布 l/block l/char l/cdrom l/pci l/scsi l/net l/sound l注:IDE接口的CD驅(qū)動(dòng)位于drivers/block/ide-cd.c中,而SCSI CD驅(qū)動(dòng)位于drivers/scsi/scsi.c中 1.5 Linu
4、x設(shè)備驅(qū)動(dòng)程序的特點(diǎn) l設(shè)備驅(qū)動(dòng)是內(nèi)核的一部分,影響內(nèi)核穩(wěn)定l為內(nèi)核或其從屬子系統(tǒng)提供一個(gè)標(biāo)準(zhǔn)接口l使用標(biāo)準(zhǔn)的內(nèi)核服務(wù)如內(nèi)存分配、中斷和等待隊(duì)列等 l大多數(shù)Linux設(shè)備驅(qū)動(dòng)可以動(dòng)態(tài)可加載 lLinux設(shè)備驅(qū)動(dòng)程序可配置 l驅(qū)動(dòng)程序維護(hù)其控制的設(shè)備,該設(shè)備即使不存在也不影響系統(tǒng)的運(yùn)行,此時(shí)設(shè)備驅(qū)動(dòng)只是占用少量系統(tǒng)內(nèi)存,不會(huì)對(duì)系統(tǒng)造成什么危害 2、設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu) lLinux的設(shè)備驅(qū)動(dòng)程序與外界的接口可以分成三部分:l與操作系統(tǒng)內(nèi)核的接口 l與系統(tǒng)引導(dǎo)的接口 l與設(shè)備的接口 lLinux設(shè)備驅(qū)動(dòng)程序的代碼結(jié)構(gòu)大致可以分為如下幾個(gè)部分:l驅(qū)動(dòng)程序的注冊(cè)與注銷(xiāo)、設(shè)備的打開(kāi)與釋放、設(shè)備的讀寫(xiě)操作、設(shè)
5、備的控制操作、設(shè)備的中斷和輪詢處理。 2.1驅(qū)動(dòng)程序的注冊(cè)與注銷(xiāo) l注冊(cè) lregister_chrdev( );/在fs/devices.clregister_blkdev( );/在fs/block_dev.cl注銷(xiāo) lunregister_chrdev( ) lunregister_blkdev( ) 2.2 翻開(kāi)、釋放、讀、寫(xiě)、控制等struct file_operations struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char
6、 *, size_t, loff_t *); ssize_t (*write) (struct file *, const 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
7、 file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, struct dentry *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct
8、file_lock *); ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *); 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 f
9、ile *, unsigned long, unsigned long, unsigned long, unsigned long);lLinux內(nèi)核將通過(guò)file_operations結(jié)構(gòu)訪問(wèn)驅(qū)動(dòng)程序提供的函數(shù) l字符設(shè)備的讀寫(xiě)直接使用函數(shù)read( )和write( ) l塊設(shè)備需要調(diào)用函數(shù)block_read( )和block_write( ) lioctl( )的用法與具體設(shè)備密切關(guān)聯(lián),因此需要根據(jù)設(shè)備的實(shí)際情況進(jìn)行具體分析 2.3 設(shè)備的輪詢和中斷處理 l輪詢l內(nèi)核定期對(duì)設(shè)備的狀態(tài)進(jìn)行查詢 l消耗不少的內(nèi)核資源 l如果設(shè)備驅(qū)動(dòng)被連接進(jìn)入內(nèi)核,這時(shí)使用輪詢方式將會(huì)帶來(lái)災(zāi)難性的后果 l中
10、斷l(xiāng)設(shè)備驅(qū)動(dòng)向內(nèi)核注冊(cè)其使用的中斷 l內(nèi)核負(fù)責(zé)把硬件產(chǎn)生的中斷傳遞給相應(yīng)的設(shè)備驅(qū)動(dòng) l設(shè)備驅(qū)動(dòng)在其中斷處理過(guò)程中做得越少越好 l問(wèn)題:l如何查看設(shè)備驅(qū)動(dòng)所對(duì)應(yīng)的中斷號(hào)及類(lèi)型 ?3、設(shè)備驅(qū)動(dòng)試驗(yàn)l實(shí)驗(yàn)一:編寫(xiě)一個(gè)簡(jiǎn)單的驅(qū)動(dòng)程序 l實(shí)驗(yàn)二:設(shè)計(jì)和實(shí)現(xiàn)一個(gè)KED&LED實(shí)驗(yàn) l實(shí)驗(yàn)三:動(dòng)態(tài)加載和靜態(tài)編譯驅(qū)動(dòng)到內(nèi)核 l實(shí)驗(yàn)四:使用中斷方式的驅(qū)動(dòng)程序設(shè)計(jì) 實(shí)驗(yàn)一:編寫(xiě)簡(jiǎn)單的驅(qū)動(dòng)程序1)l1) 任務(wù):l 在XSBase開(kāi)發(fā)板上編寫(xiě)一個(gè)簡(jiǎn)單的字符設(shè)備驅(qū)動(dòng)程序。該字符設(shè)備具備4個(gè)基本操作:xsbase_open()、xsbase_write()、 xsbase_read() 、xsbase_relea
11、se(),實(shí)現(xiàn)向這個(gè)新建的字符設(shè)備先寫(xiě)入一些數(shù)據(jù),然后再?gòu)倪@個(gè)設(shè)備中讀取這些數(shù)據(jù)。 實(shí)驗(yàn)一:編寫(xiě)簡(jiǎn)單的驅(qū)動(dòng)程序2)l2)主要數(shù)據(jù)結(jié)構(gòu)和全局變量 l系統(tǒng)fs/devices.c的struc device_struct結(jié)構(gòu) l創(chuàng)建一個(gè)xsbase.c文件,其中包含一些必要的頭文件、宏和全局變量 struct device_struct const char * name; struct file_operations * fops;static struct device_struct chrdevsMAX_CHRDEV;實(shí)驗(yàn)一:編寫(xiě)簡(jiǎn)單的驅(qū)動(dòng)程序3)l主要接口函數(shù) lfile_operation
12、s 結(jié)構(gòu)的實(shí)例 l注:這種結(jié)構(gòu)的聲明方法是一種標(biāo)記化格式聲明,便于移植。 static struct file_operations chr_fops = read: xsbase_read, write: xsbase_write, open: xsbase_open, release: xsbase_release,;實(shí)驗(yàn)一:編寫(xiě)簡(jiǎn)單的驅(qū)動(dòng)程序4)lxsbase_open()和xsbase_release() static int xsbase_open(struct inode *inode, struct file *file) MOD_INC_USE_COUNT; printk(Th
13、is chrdev is opened!n); return 0;static int xsbase_release(struct inode *inode, struct file *file) MOD_DEC_USE_COUNT; printk(this chrdev is released!n); return 0;實(shí)驗(yàn)一:編寫(xiě)簡(jiǎn)單的驅(qū)動(dòng)程序5)lxsbase_read() static ssize_t xsbase_read(struct file *file, char *buf, size_t count, loff_t *f_pos) int len; if(count 0) r
14、eturn -EINVAL; len = strlen(data); if(len count) count = len; copy_to_user(buf, data, count+1); return count;實(shí)驗(yàn)一:編寫(xiě)簡(jiǎn)單的驅(qū)動(dòng)程序6)lxsbase_write() static ssize_t xsbase_write( struct file *file, const char *buffer, size_t count, loff_t *f_pos) if(count 0) return -EINVAL; kfree(data); data = (char *)kmalloc
15、(sizeof(char)*(count+1), GFP_KERNEL); if(!data) return -ENOMEM; copy_from_user(data, buffer, count+1); return count;實(shí)驗(yàn)一:編寫(xiě)簡(jiǎn)單的驅(qū)動(dòng)程序7)l3)模塊加載:是兩種將驅(qū)動(dòng)加入內(nèi)核的方式之一l編寫(xiě)init_module()llres = register_chrdev(0, xsbase, &chr_fops); llif(xsbase_major = 0)l xsbase_major = res;l編寫(xiě)cleanup_module() llunregister_chr
16、dev(xsbase_major, xsbase);l實(shí)驗(yàn)一:編寫(xiě)簡(jiǎn)單的驅(qū)動(dòng)程序8)l4)驅(qū)動(dòng)安裝過(guò)程l新建xsbase.c文件,實(shí)現(xiàn)主要數(shù)據(jù)結(jié)構(gòu)和函數(shù)接口。l編譯生成xsbase.ol把目標(biāo)文件加載到內(nèi)核 l在Minicom中使用ZMODEM協(xié)議發(fā)送文件l執(zhí)行$ arm-linux-gcc xsbase.c I /usr/src/xscale-linux/include c xsbase.c D_KERNEL_ -DMODULE$ insmod f xsbase.o實(shí)驗(yàn)一:編寫(xiě)簡(jiǎn)單的驅(qū)動(dòng)程序9)l創(chuàng)建一個(gè)設(shè)備文件 l測(cè)試lOVER$ mknod /dev/xsbase c major min
17、or實(shí)驗(yàn)二:編寫(xiě)KED&LED驅(qū)動(dòng)1)l在這個(gè)實(shí)驗(yàn)中,通過(guò)設(shè)計(jì)和實(shí)現(xiàn)一個(gè)KED&LED驅(qū)動(dòng)程序,來(lái)控制目標(biāo)板上的一組LED燈,在安裝完驅(qū)動(dòng)后,運(yùn)行測(cè)試程序,就能點(diǎn)亮LED燈。 實(shí)驗(yàn)二:編寫(xiě)KED&LED驅(qū)動(dòng)2)#define EXT_KEY_CS EXT_PORT2#define EXT_LED_CS EXT_PORT3void led_off_on()int i;EXT_LED_CS = 0 xff;for(i =0 ; i8;+i)EXT_LED_CS = (1 i) & 0 xff);udelay(30000);EXT_LED_CS = 0 xff;實(shí)驗(yàn)三
18、:靜態(tài)編譯驅(qū)動(dòng)到內(nèi)核1) l在確定自己代碼位置的前提下,建立自己的源碼目錄、文件、Makefile、Config.in等。 l修改上層的config.in文件,把自己的驅(qū)動(dòng)加入到內(nèi)核配置系統(tǒng)中。 l修改上層Makefile,把自己的程序加入到內(nèi)核編譯系統(tǒng)中。 l確保自己的初始化函數(shù)被調(diào)用。 ldrivers/char/mem.c中的chr_dev_init() 或drivers/block/ll_rw_blk.c中的blk_dev_init() l用宏module_init來(lái)申明你的初始化函數(shù) 實(shí)驗(yàn)三:靜態(tài)編譯驅(qū)動(dòng)到內(nèi)核2)l驅(qū)動(dòng)位置和目錄結(jié)構(gòu) $ cd drivers/xsbase$ tre
19、e .|- Config.in|- Makefile|- xsbase.c- xsbase_test.c實(shí)驗(yàn)三:靜態(tài)編譯驅(qū)動(dòng)到內(nèi)核3)l修改配置文件 l1drivers/xsbase/Config.in # XSBASE driver configurationmainmenu_option next_commentcomment XSBASE Driverbool XSBASE support CONFIG_XSBASEif $CONFIG_XSBASE = y ; then tristate TEST user-space interface CONFIG_TEST_USER bool T
20、EST CPU CONFIG_TEST_CPUfiendmenu實(shí)驗(yàn)三:靜態(tài)編譯驅(qū)動(dòng)到內(nèi)核4)l2) arch/arm/config.in l編寫(xiě)Makefile l1drivers/xsbase/Makefile source drivers/xsbase/Config.inL_TARGET := test.aexport-objs := test.oobj-$(CONFIG_TEST) += test.oinclude $(TOPDIR)/Rules.makeclean:rm -f *.oa .*.flags實(shí)驗(yàn)三:靜態(tài)編譯驅(qū)動(dòng)到內(nèi)核5)l2drivers/Makefile l3Makef
21、ilesubdir-$(CONFIG_MMC) += mmcsubdir-$(CONFIG_XSBASE) += xsbaseinclude $(TOPDIR)/Rules.makeDRIVERS-$(CONFIG_PLD) += drivers/pld/pld.oDRIVERS-$(CONFIG_MMC) += drivers/mmc/mmcdrivers.oDRIVERS-$(CONFIG_XSBASE) += drivers/xsbase/xsbase.oDRIVERS := $(DRIVERS-y)實(shí)驗(yàn)四:中斷方式的驅(qū)動(dòng)程序1) l注冊(cè)中斷處理程序 l什么叫中斷信號(hào)線IRQ號(hào))?l何時(shí)
22、請(qǐng)求IRQ號(hào)更合適?l初始化時(shí)l設(shè)備第一次打開(kāi)時(shí) int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *dev_name, void *dev_id);void free_irq(unsigned int irq, void *dev_id);實(shí)驗(yàn)四:中斷方式的驅(qū)動(dòng)程序2)l編寫(xiě)中斷處理程序 static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *
23、regs) spin_lock (&rtc_lock); rtc_irq_data += 0 x100; rtc_irq_data &= 0 xff; rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0 xF0); if (rtc_status & RTC_TIMER_ON) mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); spin_unlock (&rtc_lock); wake_up_interruptible(&rtc
24、_wait); kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);實(shí)驗(yàn)四:中斷方式的驅(qū)動(dòng)程序3)l中斷處理機(jī)制的實(shí)現(xiàn) 實(shí)驗(yàn)四:中斷方式的驅(qū)動(dòng)程序4)l中斷控制l 這些函數(shù)更新可編程中斷控制器PIC中指定中斷的掩碼,因而,這樣就可以在所有的處理器上禁止或者啟動(dòng) IRQ。對(duì)這些函數(shù)的調(diào)用是可以嵌套的假如 disable_irq() 被成功調(diào)用兩次,在 IRQ 真正重新打開(kāi)之前,需要執(zhí)行兩次 enable_irq() 調(diào)用。 void disable_irq(int irq); void disable_irq_nosync(int irq); void enable_irq(int irq);驅(qū)動(dòng)設(shè)計(jì)中涉及的一些具體問(wèn)題驅(qū)動(dòng)設(shè)計(jì)中涉及的一些具體問(wèn)題 l用戶空間和內(nèi)核空間 l/proc文件系統(tǒng) 文件/目錄名描述Apm高級(jí)電源管理信息Bus包含了總線以及總線上設(shè)備信息的目錄,子目錄
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 買(mǎi)花合同范例
- 江蘇專(zhuān)用2024高考語(yǔ)文提分限時(shí)規(guī)范練十語(yǔ)言文字運(yùn)用+名句名篇默寫(xiě)+散文閱讀含解析
- 2024高中化學(xué)第一章認(rèn)識(shí)有機(jī)化合物第二節(jié)有機(jī)化合物的結(jié)構(gòu)特點(diǎn)課后提升練習(xí)含解析新人教版選修5
- 金屬龍骨拆除施工方案
- 與 簽訂施工合同范例
- 專(zhuān)業(yè)團(tuán)隊(duì)開(kāi)荒保潔合同范例
- 全投資合伙合同范例
- 加盟造價(jià)公司合同范例
- 鄉(xiāng)村建筑租賃合同范例
- 中介臺(tái)面租賃合同范例
- 2025年度事業(yè)單位招聘考試公共基礎(chǔ)知識(shí)模擬試卷及答案(共四套)
- 2024年海東市第二人民醫(yī)院自主招聘專(zhuān)業(yè)技術(shù)人員筆試真題
- 專(zhuān)題07 綜合性學(xué)習(xí)【知識(shí)精研】中考語(yǔ)文二輪復(fù)習(xí)
- 2025年江西陶瓷工藝美術(shù)職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)技能測(cè)試題庫(kù)1套
- 《計(jì)算機(jī)基礎(chǔ)與應(yīng)用(Office 和 WPS Office )》課件 項(xiàng)目二?計(jì)算機(jī)操作系統(tǒng)配置與應(yīng)用
- 2025年湖南電氣職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)技能測(cè)試題庫(kù)及參考答案
- 混凝土拌合站拌合運(yùn)輸工程合同
- 機(jī)床操作與數(shù)控編程作業(yè)指導(dǎo)書(shū)
- 2025云南昆明空港投資開(kāi)發(fā)集團(tuán)招聘7人高頻重點(diǎn)模擬試卷提升(共500題附帶答案詳解)
- 2024-2025學(xué)年人教版數(shù)學(xué)六年級(jí)下冊(cè)第二單元百分?jǐn)?shù)(二)單元檢測(cè)(含答案)
- 人教版 八年級(jí)英語(yǔ)下冊(cè) Unit 2 單元綜合測(cè)試卷(2025年春)
評(píng)論
0/150
提交評(píng)論