第6講 Linux字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)_第1頁(yè)
第6講 Linux字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)_第2頁(yè)
第6講 Linux字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)_第3頁(yè)
第6講 Linux字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)_第4頁(yè)
第6講 Linux字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)_第5頁(yè)
已閱讀5頁(yè),還剩28頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、1第第6 6講講 Linux字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)嵌入式操作系統(tǒng)嵌入式操作系統(tǒng) 2本講主要內(nèi)容本講主要內(nèi)容6.1 Linux設(shè)備驅(qū)動(dòng)簡(jiǎn)介設(shè)備驅(qū)動(dòng)簡(jiǎn)介6.2 字符設(shè)備驅(qū)動(dòng)程序框架字符設(shè)備驅(qū)動(dòng)程序框架6.3 字符設(shè)備舉例字符設(shè)備舉例6.1 Linux設(shè)備驅(qū)動(dòng)簡(jiǎn)介設(shè)備驅(qū)動(dòng)簡(jiǎn)介設(shè)備驅(qū)動(dòng)程序和應(yīng)用程序的關(guān)系:設(shè)備驅(qū)動(dòng)程序和應(yīng)用程序的關(guān)系:3應(yīng)用程序驅(qū)動(dòng)程序設(shè)備writereadioctlioctlLinux設(shè)備驅(qū)動(dòng)屬于內(nèi)核模塊的一部分。設(shè)備驅(qū)動(dòng)屬于內(nèi)核模塊的一部分。LinuxLinux內(nèi)核模塊介紹內(nèi)核模塊介紹 Linux內(nèi)核的整體結(jié)構(gòu)非常龐大,其包含的組件非內(nèi)核的整體結(jié)構(gòu)非常龐大,其包

2、含的組件非常多。我們?nèi)绾伟研枰牟糠侄及趦?nèi)核中呢?常多。我們?nèi)绾伟研枰牟糠侄及趦?nèi)核中呢? 把需要的功能都編譯到把需要的功能都編譯到linux內(nèi)核,隨同內(nèi)核,隨同Linux 啟動(dòng)時(shí)加載。啟動(dòng)時(shí)加載。 以模塊方式擴(kuò)展內(nèi)核功能。使用以模塊方式擴(kuò)展內(nèi)核功能。使用insmod 加載,使用加載,使用rmmod 刪除。這種方式控制了內(nèi)核的大小,而模塊一旦被插入到內(nèi)刪除。這種方式控制了內(nèi)核的大小,而模塊一旦被插入到內(nèi)核,它就和內(nèi)核其他部分一樣。核,它就和內(nèi)核其他部分一樣。4LinuxLinux內(nèi)核模塊的優(yōu)點(diǎn)與缺點(diǎn)內(nèi)核模塊的優(yōu)點(diǎn)與缺點(diǎn)優(yōu)點(diǎn)優(yōu)點(diǎn)使內(nèi)核更加使內(nèi)核更加緊湊和靈活;緊湊和靈活;修改內(nèi)核時(shí),修改

3、內(nèi)核時(shí),不必全部重新編譯不必全部重新編譯整個(gè)內(nèi)核。系統(tǒng)如果需要使用新整個(gè)內(nèi)核。系統(tǒng)如果需要使用新模塊,只要編譯相應(yīng)的模塊,然后使用模塊,只要編譯相應(yīng)的模塊,然后使用insmodinsmod將模塊裝載即可;將模塊裝載即可;模塊的目標(biāo)代碼一旦被鏈接到內(nèi)核,它的作用域和靜態(tài)鏈接的內(nèi)模塊的目標(biāo)代碼一旦被鏈接到內(nèi)核,它的作用域和靜態(tài)鏈接的內(nèi)核目標(biāo)代碼完全等價(jià)。核目標(biāo)代碼完全等價(jià)。缺點(diǎn)缺點(diǎn)由于內(nèi)核所占用的內(nèi)存是不會(huì)被換出的,所以鏈接進(jìn)內(nèi)核的模塊由于內(nèi)核所占用的內(nèi)存是不會(huì)被換出的,所以鏈接進(jìn)內(nèi)核的模塊會(huì)給整個(gè)系統(tǒng)帶來(lái)一定的會(huì)給整個(gè)系統(tǒng)帶來(lái)一定的性能和內(nèi)存利用方面的損失;性能和內(nèi)存利用方面的損失;裝入內(nèi)核的模

4、塊就成為內(nèi)核的一部分,可以修改內(nèi)核中的其他部裝入內(nèi)核的模塊就成為內(nèi)核的一部分,可以修改內(nèi)核中的其他部分,因此,模塊的使用不當(dāng)會(huì)導(dǎo)致系統(tǒng)崩潰;分,因此,模塊的使用不當(dāng)會(huì)導(dǎo)致系統(tǒng)崩潰;為了讓內(nèi)核模塊能訪問(wèn)所有內(nèi)核資源,為了讓內(nèi)核模塊能訪問(wèn)所有內(nèi)核資源,內(nèi)核必須維護(hù)符號(hào)表內(nèi)核必須維護(hù)符號(hào)表,并,并在裝入和卸載模塊時(shí)修改符號(hào)表;在裝入和卸載模塊時(shí)修改符號(hào)表;模塊會(huì)要求利用其它模塊的功能,所以,模塊會(huì)要求利用其它模塊的功能,所以,內(nèi)核要維護(hù)模塊之間的內(nèi)核要維護(hù)模塊之間的依賴性。依賴性。Linux內(nèi)核模塊與應(yīng)用程序的區(qū)別內(nèi)核模塊與應(yīng)用程序的區(qū)別 C C語(yǔ)言程序語(yǔ)言程序 LinuxLinux內(nèi)核模塊內(nèi)核模塊

5、運(yùn)行運(yùn)行 用戶空間用戶空間 內(nèi)核空間內(nèi)核空間入口入口 main() main() module_init()module_init()指定指定; ;出口出口 無(wú)無(wú) module_exit()module_exit()指定指定; ; 連接連接 ld insmodld insmod運(yùn)行運(yùn)行 直接運(yùn)行直接運(yùn)行 insmodinsmod7設(shè)備分類:設(shè)備分類: 字符設(shè)備字符設(shè)備 以字節(jié)為單位逐個(gè)進(jìn)行以字節(jié)為單位逐個(gè)進(jìn)行I/O操作操作 字符設(shè)備中的緩存是可有可無(wú)字符設(shè)備中的緩存是可有可無(wú) 不支持隨機(jī)訪問(wèn)不支持隨機(jī)訪問(wèn) 如串口設(shè)備等如串口設(shè)備等 塊設(shè)備塊設(shè)備 塊設(shè)備的存取是通過(guò)塊設(shè)備的存取是通過(guò)buffer

6、、cache來(lái)進(jìn)行來(lái)進(jìn)行 可以進(jìn)行隨機(jī)訪問(wèn)可以進(jìn)行隨機(jī)訪問(wèn) 例如例如IDE硬盤(pán)設(shè)備硬盤(pán)設(shè)備 可以支持可安裝文件系統(tǒng)可以支持可安裝文件系統(tǒng) 網(wǎng)絡(luò)設(shè)備網(wǎng)絡(luò)設(shè)備 通過(guò)通過(guò)BSD套接口訪問(wèn)套接口訪問(wèn)設(shè)備文件設(shè)備文件 Linux抽象了對(duì)抽象了對(duì)硬件硬件的處理,所有的硬件設(shè)備都可以作的處理,所有的硬件設(shè)備都可以作為為普通文件普通文件一樣來(lái)看待。一樣來(lái)看待。 可以可以使用和操作文件使用和操作文件相同的、標(biāo)準(zhǔn)的相同的、標(biāo)準(zhǔn)的系統(tǒng)調(diào)用接口系統(tǒng)調(diào)用接口來(lái)來(lái)完成打開(kāi)、關(guān)閉、讀寫(xiě)和完成打開(kāi)、關(guān)閉、讀寫(xiě)和I/O控制操作控制操作 字符設(shè)備和塊設(shè)備是通過(guò)文件節(jié)點(diǎn)訪問(wèn)的。在字符設(shè)備和塊設(shè)備是通過(guò)文件節(jié)點(diǎn)訪問(wèn)的。在Linux的

7、的文件系統(tǒng)中,可以找到(或者使用文件系統(tǒng)中,可以找到(或者使用mknod創(chuàng)建)設(shè)備創(chuàng)建)設(shè)備對(duì)應(yīng)的文件名,稱這種文件為設(shè)備文件對(duì)應(yīng)的文件名,稱這種文件為設(shè)備文件。主設(shè)備號(hào)和次設(shè)備號(hào)主設(shè)備號(hào)和次設(shè)備號(hào) 主設(shè)備號(hào)主設(shè)備號(hào):標(biāo)識(shí)該設(shè)備的種類,也標(biāo)識(shí)了該設(shè)備所使用的:標(biāo)識(shí)該設(shè)備的種類,也標(biāo)識(shí)了該設(shè)備所使用的驅(qū)動(dòng)程序:驅(qū)動(dòng)程序: 主設(shè)備號(hào)的范圍只能是主設(shè)備號(hào)的范圍只能是1-255 Linux內(nèi)核支持動(dòng)態(tài)分配主設(shè)備號(hào)內(nèi)核支持動(dòng)態(tài)分配主設(shè)備號(hào) 次設(shè)備號(hào)次設(shè)備號(hào):標(biāo)識(shí)使用同一設(shè)備驅(qū)動(dòng)程序的不同硬件設(shè)備。:標(biāo)識(shí)使用同一設(shè)備驅(qū)動(dòng)程序的不同硬件設(shè)備。 同一個(gè)驅(qū)動(dòng)程序可以管理多個(gè)設(shè)備,它們依靠次設(shè)備號(hào)來(lái)同一個(gè)驅(qū)動(dòng)程序

8、可以管理多個(gè)設(shè)備,它們依靠次設(shè)備號(hào)來(lái)區(qū)別。次設(shè)備號(hào)只在驅(qū)動(dòng)程序內(nèi)部使用,系統(tǒng)內(nèi)核直接把區(qū)別。次設(shè)備號(hào)只在驅(qū)動(dòng)程序內(nèi)部使用,系統(tǒng)內(nèi)核直接把次設(shè)備號(hào)傳遞給驅(qū)動(dòng)程序,由驅(qū)動(dòng)程序去管理。次設(shè)備號(hào)傳遞給驅(qū)動(dòng)程序,由驅(qū)動(dòng)程序去管理。6.2 字符設(shè)備驅(qū)動(dòng)程序框架字符設(shè)備驅(qū)動(dòng)程序框架基于基于linux2.6.38Linux設(shè)備驅(qū)動(dòng)程序大致可分為如下幾個(gè)部分:設(shè)備驅(qū)動(dòng)程序大致可分為如下幾個(gè)部分: 驅(qū)動(dòng)程序的注冊(cè)與注銷、驅(qū)動(dòng)程序的注冊(cè)與注銷、 設(shè)備的打開(kāi)與釋放、設(shè)備的打開(kāi)與釋放、 設(shè)備的讀寫(xiě)操作、設(shè)備的讀寫(xiě)操作、 設(shè)備的控制操作、設(shè)備的控制操作、 設(shè)備的中斷和輪詢處理。設(shè)備的中斷和輪詢處理。10驅(qū)動(dòng)程序驅(qū)動(dòng)程序使

9、用的使用的2個(gè)重要結(jié)構(gòu)個(gè)重要結(jié)構(gòu) struct file文件描述結(jié)構(gòu)文件描述結(jié)構(gòu) struct file_operations文件操作結(jié)構(gòu)文件操作結(jié)構(gòu) struct miscdevice混雜設(shè)備結(jié)構(gòu)混雜設(shè)備結(jié)構(gòu) struct dev設(shè)備結(jié)構(gòu)設(shè)備結(jié)構(gòu)struct filestruct file數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)結(jié)構(gòu) 定義位于定義位于include/fs.h struct file結(jié)構(gòu)與驅(qū)動(dòng)相關(guān)的成員結(jié)構(gòu)與驅(qū)動(dòng)相關(guān)的成員 mode_t f_mode標(biāo)識(shí)標(biāo)識(shí)文件的讀寫(xiě)權(quán)限文件的讀寫(xiě)權(quán)限 loff_t f_pos當(dāng)前當(dāng)前讀寫(xiě)位置讀寫(xiě)位置 unsigned int_f_flag文件文件標(biāo)志,主要進(jìn)行阻塞標(biāo)志,

10、主要進(jìn)行阻塞/非阻塞型非阻塞型操作操作 struct file_operation * f_op 文件文件操作的結(jié)構(gòu)指針操作的結(jié)構(gòu)指針 void * private_data驅(qū)動(dòng)程序驅(qū)動(dòng)程序一般將它指向已經(jīng)分配的數(shù)據(jù)一般將它指向已經(jīng)分配的數(shù)據(jù) struct dentry* f_dentry文件文件對(duì)應(yīng)的目錄項(xiàng)結(jié)構(gòu)對(duì)應(yīng)的目錄項(xiàng)結(jié)構(gòu)設(shè)備驅(qū)動(dòng)程序設(shè)備驅(qū)動(dòng)程序接口接口static struct file_operations demo_fops = owner: THIS_MODULE,write: demo_write,read: demo_read,ioctl: demo_ioctl,open:

11、demo_open,release: demo_release,;設(shè)備驅(qū)動(dòng)程序接口(設(shè)備驅(qū)動(dòng)程序接口( struct file_operations ) 設(shè)備驅(qū)動(dòng)程序設(shè)備驅(qū)動(dòng)程序接口是指接口是指struct file_operations ,它,它的定義位于的定義位于include/linux/fs.h中。中。 在嵌入式系統(tǒng)的開(kāi)發(fā)中,通常只要實(shí)現(xiàn)如下幾個(gè)接在嵌入式系統(tǒng)的開(kāi)發(fā)中,通常只要實(shí)現(xiàn)如下幾個(gè)接口函數(shù)就能完成系統(tǒng)所需要的口函數(shù)就能完成系統(tǒng)所需要的功能:功能: init 加載加載驅(qū)動(dòng)程序時(shí),內(nèi)核自動(dòng)調(diào)用驅(qū)動(dòng)程序時(shí),內(nèi)核自動(dòng)調(diào)用 read 從從設(shè)備中讀取數(shù)據(jù)設(shè)備中讀取數(shù)據(jù) write 向向字符

12、設(shè)備中寫(xiě)數(shù)據(jù)字符設(shè)備中寫(xiě)數(shù)據(jù) ioctl 控制設(shè)備控制設(shè)備,實(shí)現(xiàn)除讀寫(xiě)操作以外的其他控制命令,實(shí)現(xiàn)除讀寫(xiě)操作以外的其他控制命令 open 打開(kāi)打開(kāi)設(shè)備并進(jìn)行初始化設(shè)備并進(jìn)行初始化 release 關(guān)閉關(guān)閉設(shè)備并釋放資源設(shè)備并釋放資源 exit 卸載卸載驅(qū)動(dòng)程序時(shí),內(nèi)核自動(dòng)調(diào)用驅(qū)動(dòng)程序時(shí),內(nèi)核自動(dòng)調(diào)用 驅(qū)動(dòng)程序注冊(cè)過(guò)程(動(dòng)態(tài)分配主設(shè)備號(hào))驅(qū)動(dòng)程序注冊(cè)過(guò)程(動(dòng)態(tài)分配主設(shè)備號(hào)) insmod module_name ;加載驅(qū)動(dòng)程序,運(yùn)行加載驅(qū)動(dòng)程序,運(yùn)行init函數(shù)函數(shù)(register_chrdev(dev_Major, “module_name”, * fs ) 查看查看/proc/device

13、s mknod /dev/module_name c/b 主設(shè)備號(hào)主設(shè)備號(hào) 次設(shè)備號(hào)次設(shè)備號(hào) rmmod module_name ;卸載驅(qū)動(dòng),運(yùn)行卸載驅(qū)動(dòng),運(yùn)行 exit函數(shù)(函數(shù)(unregister_chrdev(dev_Major, “module_name”, * fs )) 用戶程序調(diào)用用戶程序調(diào)用 open(“/dev/module_name”, mode) ;O_RDWR ioctl() write() read() close()混雜設(shè)備結(jié)構(gòu):混雜設(shè)備結(jié)構(gòu):struct miscdevice在在Linux驅(qū)動(dòng)中把無(wú)法歸類的五花八門(mén)的設(shè)備定驅(qū)動(dòng)中把無(wú)法歸類的五花八門(mén)的設(shè)備定義為混

14、雜設(shè)備義為混雜設(shè)備(用用miscdevice結(jié)構(gòu)體表述結(jié)構(gòu)體表述)。miscdevice共享一個(gè)主設(shè)備號(hào)共享一個(gè)主設(shè)備號(hào)MISC_MAJOR(即即10),但次設(shè)備號(hào)不同。所有的,但次設(shè)備號(hào)不同。所有的miscdevice設(shè)設(shè)備形成了一個(gè)鏈表,對(duì)設(shè)備訪問(wèn)時(shí)內(nèi)核根據(jù)次備形成了一個(gè)鏈表,對(duì)設(shè)備訪問(wèn)時(shí)內(nèi)核根據(jù)次設(shè)備號(hào)查找對(duì)應(yīng)的設(shè)備號(hào)查找對(duì)應(yīng)的miscdevice設(shè)備,然后調(diào)用設(shè)備,然后調(diào)用其其file_operations結(jié)構(gòu)中注冊(cè)的文件操作接口進(jìn)結(jié)構(gòu)中注冊(cè)的文件操作接口進(jìn)行操作。行操作。17struct miscdevice內(nèi)部結(jié)構(gòu)內(nèi)部結(jié)構(gòu)186.3 字符設(shè)備舉例字符設(shè)備舉例例例1:LED驅(qū)動(dòng)程序。

15、驅(qū)動(dòng)程序。191、結(jié)構(gòu)、結(jié)構(gòu)#define DEVICE_NAME gd_leds/設(shè)備名稱設(shè)備名稱struct dev struct miscdevice *miscp;struct dev *devp;static struct file_operations dev_fops = .owner= THIS_MODULE,.unlocked_ioctl= mini6410_leds_ioctl,;20static struct miscdevice misc = .minor = MISC_DYNAMIC_MINOR,/動(dòng)態(tài)申請(qǐng)?jiān)O(shè)備號(hào)動(dòng)態(tài)申請(qǐng)?jiān)O(shè)備號(hào).name = DEVICE_NAME,/

16、設(shè)備名稱設(shè)備名稱.fops = &dev_fops,;212、ioctl()函數(shù)函數(shù)static long mini6410_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)switch(cmd) unsigned tmp;case 0:case 1: if (arg 4) return EINVAL;tmp = ioread8(void *)S3C64XX_GPKDAT);/讀讀K口口Tmp &= (1 (4 + arg);tmp |= ( (!cmd) (4 + arg) );iowrite8(tmp, (void

17、*)S3C64XX_GPKDAT);/寫(xiě)寫(xiě)K口口Return 0;default:return EINVAL;223、模塊初始化函數(shù)、模塊初始化函數(shù)static int _init dev_init(void)int ret;unsigned tmp; /設(shè)置設(shè)置K口口47為輸出為輸出 tmp = readl(void *)S3C64XX_GPKCON);tmp = (tmp & (0 xffffU16)|(0 x1111U16);writel(tmp, (void *)S3C64XX_GPKCON); /設(shè)置設(shè)置K口口47為高電平(為高電平(LED滅)滅)tmp = ioread8(void

18、 *)S3C64XX_GPKDAT);tmp |= (0 xF miscp = &misc; ret = misc_register(devp-miscp);/注冊(cè)設(shè)備注冊(cè)設(shè)備 printk (DEVICE_NAME”tinitializedn”); return ret;234、模塊退出函數(shù)、模塊退出函數(shù)static void _exit dev_exit(void)misc_deregister(devp-miscp);/釋放設(shè)備釋放設(shè)備kfree(devp);245、模塊說(shuō)明宏、模塊說(shuō)明宏module_init(dev_init);module_exit(dev_exit);MODULE

19、_LICENSE(GPL);MODULE_AUTHOR(GuangZhouUniversity.);256、將驅(qū)動(dòng)程序、將驅(qū)動(dòng)程序gd_leds.c放在放在linux字符設(shè)備驅(qū)字符設(shè)備驅(qū)動(dòng)程序目錄。動(dòng)程序目錄。26一般編譯一般編譯2.6版本的驅(qū)動(dòng)模塊需要把驅(qū)動(dòng)代碼加入內(nèi)核代版本的驅(qū)動(dòng)模塊需要把驅(qū)動(dòng)代碼加入內(nèi)核代碼樹(shù),并做相應(yīng)的配置。碼樹(shù),并做相應(yīng)的配置。7、編輯配置文件、編輯配置文件Kconfig,加入驅(qū)動(dòng)選項(xiàng)。,加入驅(qū)動(dòng)選項(xiàng)。打開(kāi)打開(kāi)linux-2.6.38/drivers/char/Kconfig文件,添加如圖所示:文件,添加如圖所示:278、配置、配置在在linux-2.6.38目錄位置

20、運(yùn)行一下目錄位置運(yùn)行一下make menuconfig就可以在就可以在Device Drivers 的的 Character devices 菜單中看到剛才所添加的選項(xiàng)了。菜單中看到剛才所添加的選項(xiàng)了。按下空格鍵將會(huì)選擇為按下空格鍵將會(huì)選擇為,此意為要把該選項(xiàng)編譯為模塊方式;再,此意為要把該選項(xiàng)編譯為模塊方式;再按下空格會(huì)變?yōu)榘聪驴崭駮?huì)變?yōu)?,意為要把該選項(xiàng)編譯到內(nèi)核中,在此我們選擇,意為要把該選項(xiàng)編譯到內(nèi)核中,在此我們選擇。289、在、在Makefile中把內(nèi)核配置選項(xiàng)和真正的源代碼聯(lián)系起來(lái),打開(kāi)中把內(nèi)核配置選項(xiàng)和真正的源代碼聯(lián)系起來(lái),打開(kāi)linux-2.6.38/drivers/char/Makefile并添加:并添加:obj-$(CONFIG_OUR_LEDS_DRIVER)+= our_leds_dr

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論