Linux驅動程序設計課件_第1頁
Linux驅動程序設計課件_第2頁
Linux驅動程序設計課件_第3頁
Linux驅動程序設計課件_第4頁
Linux驅動程序設計課件_第5頁
已閱讀5頁,還剩43頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、教學內容第一章 嵌入式系統(tǒng)概述第二章 學習板硬件及開發(fā)環(huán)境的建立第三章 構建嵌入式Linux系統(tǒng)第四章 嵌入式Linux設備驅動第五章 嵌入式Linux串口和網(wǎng)絡編程第六章 嵌入式Linux圖形編程Sunday, July 31, 2022 1第四章 嵌入式Linux驅動程序4.1 嵌入式Linux設備驅動簡介4.2 設備的分類及特點4.3 構造和運行驅動程序模塊Sunday, July 31, 2022 2課程目標掌握嵌入式Linux設備驅動程序的基本原理、架構和設計方法字符設備驅動塊設備驅動網(wǎng)絡設備驅動掌握Linux設備驅動開發(fā)中常用的機制和內核資源中斷頂/底半部處理內核定時器和延時操作并

2、發(fā)控制在內核中的應用內存管理和分配阻塞型I/O和非阻塞型I/OSunday, July 31, 2022 3本章目標了解Linux設備驅動程序的基礎知識 掌握Linux驅動模塊的構造和裝載方法 Sunday, July 31, 2022 4本章結構設備驅動程序簡介 Linux驅動程序概述 設備驅動的Hello World模塊內核驅動模塊和應用程序對比 編譯和裝載驅動模塊 構造和運行模塊 設備的分類和特點 字符設備網(wǎng)絡設備塊設備Sunday, July 31, 2022 5驅動程序的作用應用程序驅動程序操作系統(tǒng)硬件設備writeioctlreadioctl為什么要學嵌入式Linux驅動程序開發(fā)?

3、高需求內核代碼的大部分新芯片、新設備高門檻需要具有硬件知識需要了解內核基礎知識需要了解內核中的并發(fā)控制和同步復雜的軟件結構框架高回報Sunday, July 31, 2022 74-1設備驅動程序簡介驅動程序的特點操控硬件,是應用程序和硬件設備之間的一個接口隱藏硬件細節(jié),提高應用軟件的可移植性提供安全性開發(fā)模式內核態(tài)驅動用戶態(tài)驅動提供機制,而不是提供策略機制:驅動程序能實現(xiàn)什么功能策略:用戶如何使用這些功能Sunday, July 31, 2022 8內核態(tài)和用戶態(tài)大多數(shù)OS(包括Linux)把內核和運行在其上的應用程序分為兩個層次管理,即用戶態(tài)和內核態(tài)內核態(tài)有較高的權限,可以控制處理器內存的

4、映射和分配方式等等對應于ARM的svc模式 用戶態(tài):只能運行系統(tǒng)上的應用程序對應于ARM的usr模式內核態(tài)與用戶態(tài)切換:可通過軟件中斷實現(xiàn)內核態(tài)和用戶態(tài)驅動程序作為系統(tǒng)內核的一部分,其工作在內核態(tài),而應用程序工作在用戶態(tài),即不能直接通過指針,把用戶空間的數(shù)據(jù)地址傳遞給內核(MMU映射地址不一樣)。需要經(jīng)過轉換,把用戶態(tài)“看到的空間”轉換成內核態(tài)可訪問的地址。Linux系統(tǒng)提供了一系列方便的函數(shù)實現(xiàn)這種轉換,如:_get_user、_put_user、_copy_from_user、_copy_to_user4-2設備的分類和特點設備分類字符設備(char device)塊設備(block de

5、vice)網(wǎng)絡設備(network device)Sunday, July 31, 2022 114-2設備的分類和特點字符設備特點像字節(jié)流一樣來存取的設備( 如同文件 )通過/dev下的文件系統(tǒng)結點來訪問。通常至少需要實現(xiàn) open, close, read, 和 write 等系統(tǒng)調用只能順序訪問數(shù)據(jù)通道,不能前后移動訪問指針。特例:比如framebuffer設備就是這樣的設備,應用程序可以使用mmap或lseek訪問圖像的各個區(qū)域Sunday, July 31, 2022 12Linux內核結構Linux內核結構應用程序、庫、內核、驅動程序的關系open read write ioctl

6、 調用其他庫函數(shù)稱為系統(tǒng)調用,執(zhí)行swi指令進入內核系統(tǒng)調用的異常處理 其他功能物理設備控制器物理設備應用程序 庫其他庫函數(shù)的實現(xiàn) 內核open read write ioctl 驅動程序4層軟件關系說明(1)應用程序使用庫函數(shù)提供的open函數(shù)打開設備文件(2)庫根據(jù)open函數(shù)傳入的參數(shù)執(zhí)行“swi”指令,引起CPU異常,進入內核(3)內核的異常處理函數(shù)根據(jù)這些參數(shù)找到相應的驅動程序,返回一個文件描述符給庫,進而返回給應用程序(4)應用程序得到文件描述符后,使用庫提供的write或ioclt函數(shù)發(fā)出控制命令(5)庫根據(jù)write或ioclt函數(shù)傳入的參數(shù)執(zhí)行“swi”指令,這條指令會引起C

7、PU異常,再次進入內核(6)內核的異常處理函數(shù)根據(jù)參數(shù)調用驅動程序的相關函數(shù),控制硬件4-2設備的分類和特點塊設備特點塊設備通過位于 /dev 目錄的文件系統(tǒng)結點來存取塊設備和字符設備的區(qū)別僅僅在于內核內部管理數(shù)據(jù)的方式塊設備有專門的接口,塊設備的接口必須支持掛裝(mount)文件系統(tǒng)。應用程序一般通過文件系統(tǒng)來訪問塊設備上的內容Sunday, July 31, 2022 174-2設備的分類和特點網(wǎng)絡設備特點通過單獨的網(wǎng)絡接口來訪問任何一個網(wǎng)絡事務都通過一個網(wǎng)絡接口訪問,即一個能夠和其他主機交換數(shù)據(jù)的設備。網(wǎng)卡軟件設備:環(huán)回接口(loopback)內核調用一套和數(shù)據(jù)包傳輸相關的函數(shù)Sunda

8、y, July 31, 2022 184-3 構造和運行模塊驅動程序加入內核的方法把所有需要的功能都編譯到內核中生成的內核鏡像(Image)文件會很大 如果我們要在現(xiàn)有的內核中新增或刪除功能,將不得不重新編譯和裝載內核。 ?Sunday, July 31, 2022 194-3 驅動程序加入內核的方法 Linux提供了機制被稱為模塊(Module)的機制 提供了對許多模塊支持, 包括但不限于, 設備驅動每個模塊由目標代碼組成( 沒有連接成一個完整可執(zhí)行程序 )insmod 將模塊動態(tài)加載到正在運行內核rmmod 程序移除模塊Sunday, July 31, 2022 204.3.1 設備驅動的

9、Hello World模塊#include #include MODULE_LICENSE(Dual BSD/GPL);static int _init hello_init(void) printk(KERN_ALERT Hello worldn); return 0;static void _exit hello_exit(void) printk(KERN_ALERT Hello world exitn);module_init(hello_init);module_exit(hello_exit); 自由許可證模塊卸載宏用法類似于printf,但它有優(yōu)先級(比如KERN_ALERT)模

10、塊初始化宏宏,告訴內核這兩個函數(shù)只會在加載和卸載模塊時使用Sunday, July 31, 2022 21打印調試printk指示日志級別的宏 KERN_EMERG 用于緊急事件消息,一般是系統(tǒng)崩潰前提示 KERN_ALERT 用于需要立即采取動作 KERN_CRIT 臨界狀態(tài),通常涉及到嚴重的硬件或軟件操作失敗 KERN_ERR 用于報告錯誤狀態(tài),設備驅動程序會經(jīng)常使用其來報告來自硬件的問題 KERN_WARNING 用于對可能出現(xiàn)的問題進行警告 KERN_NOTICE 用于有必要進行提示的正常情況 KERN_INFO 提示性信息 KERN_DEBUG 用于調試信息打印調試printk每個宏

11、表示一個中的整數(shù)(07),數(shù)值越小,優(yōu)先級越高未指定優(yōu)先級在內核2.6版本中就是KENR_WARNING簡單的內核模塊編譯(內核2.4)編譯內核模塊 #gcc O -DMODULE -D_KERNEL_ -c hello.c -I /usr/src/linux/include (x86 or ARM ? ) 生成hello.o加載內核模塊:insmod #insmod hello.o #dmesg Hello,world查看內核中使用的模塊 #lsmod | grep hello卸載內核模塊:rmmod #rmmod hello.o #dmesg Goodbye world簡單的內核模塊編譯(

12、內核2.6)obj-m := led_drv.oKDIR:=/home/at9200/kernel/linux-2.6.38/PWD :=$(shell pwd)all: make -C $(KDIR) M=$(PWD) modulesclean: make -C $(KDIR) M=$(PWD) cleanMakefile文件內容簡單的內核模塊編譯(內核2.6)obj-m := led_drv.o表示編譯后生成led_drv.ko模塊$(KDIR) 指定了target內核源碼的路徑,“M=”表示這是個外部模塊,M=$(PWD) 指定了該模塊文件所在的路徑。簡單的內核模塊編譯(內核2.6)如果

13、是多個源文件編譯出一個模塊,假設模塊名是test.ko,那么源文件名不能有test.cobj-m := test.otest-objs := file1.o file2.o file3.oKDIR := /home/at9200/kernel/linux-2.6.38/PWD := $(shell pwd)all: make -C $(KDIR) M=$(PWD) modulesclean: make -C $(KDIR) M=$(PWD) clean4.3.1 設備驅動的Hello World模塊Linux內核模塊的程序結構module_init()-模塊加載函數(shù)(必須) 通過insmod或

14、modprobe命令加載內核模塊時,模塊的加載函數(shù)會自動被內核執(zhí)行,完成模塊的相關初始化工作module_exit()-模塊卸載函數(shù)(必須) 當通過rmmod命令卸載某模塊時,模塊的卸載函數(shù)會自動被內核執(zhí)行,完成與模塊裝載函數(shù)相反的功能Sunday, July 31, 2022 284-3-1 設備驅動的Hello World模塊MODULE_LICENSE()-模塊許可證聲明(必須)模塊許可證(LICENSE)聲明描述內核模塊的許可權限如果不聲明LICENSE,模塊被加載時,將收到內核被污染(kernel tainted)的警告包括:“GPL”、 “GPL v2”、 “GPL and add

15、itional rights”、 “Dual BSD/GPL”、“Dual MPI/GPL”、 “Proprietary” Sunday, July 31, 2022 294-3-1 設備驅動的Hello World模塊模塊加載函數(shù)static int _init initialization_function(void) /* 初始化代碼 */module_init(initialization_function); 應當聲明成靜態(tài)的(static), 因為它們不會在特定文件之外可見表明該函數(shù)只是在初始化時使用。模塊加載器在模塊加載后會丟掉這個初始化函數(shù), 這樣可將該函數(shù)占用的內存釋放出來,

16、以作他用。 原型:#define _init _attribute_ (_section_(“.init.text”)定義會在模塊目標代碼中增加一個特殊的段, 用于說明內核模塊初始化函數(shù)所在的位置。沒有這個定義, 初始化函數(shù)不會被調用。Sunday, July 31, 2022 304-3-1 設備驅動的Hello World模塊模塊卸載函數(shù) static void _exit cleanup_function(void) /* 釋放資源 */ module_exit(cleanup_function); 在模塊被移除前注銷接口并釋放所有所占用的系統(tǒng)資源標識這個代碼是只用于模塊卸載( 通過使編

17、譯器把它放在特殊的 ELF 段)原型:#define _exit _attribute_ (_section_(“.exit.text”)Sunday, July 31, 2022 314.3.1 設備驅動的Hello World模塊#include #include MODULE_LICENSE(Dual BSD/GPL);static int _init hello_init(void) printk(KERN_ALERT Hello worldn); return 0;static void _exit hello_exit(void) printk(KERN_ALERT Hello w

18、orld exitn);module_init(hello_init);module_exit(hello_exit); Sunday, July 31, 2022 324-3-1 設備驅動的Hello World模塊module_param()-模塊參數(shù)(可選)模塊參數(shù)是模塊被加載的時候可以被傳遞給它的值,它本身對應模塊內部的全局變量。Sunday, July 31, 2022 334-3-1 設備驅動的Hello World模塊EXPORT_SYMBOL()-模塊導出符號(可選)內核模塊可以導出符號(symbol,對應于函數(shù)或變量)到內核其他模塊可以使用本模塊中的變量或函數(shù)其他一些聲明MO

19、DULE_XXXXX()-模塊聲明(可選) Sunday, July 31, 2022 344.3.1 設備驅動的Hello World模塊#include #include MODULE_LICENSE(Dual BSD/GPL);static char *whom = world;static int howmany = 1;static int hello_init(void)int i; for(i=0;ihowmany;i+) printk(KERN_ALERT Hello %sn,whom); return 0;static void hello_exit(void) printk

20、(KERN_ALERT Hello world exitn);module_init(hello_init);module_exit(hello_exit);module_param(howmany, int, S_IRUGO);module_param(whom, charp, S_IRUGO); module_param(參數(shù)名, 參數(shù)類型,參數(shù)讀/寫權限) Sunday, July 31, 2022 354-3-1 設備驅動的Hello World模塊module_param(參數(shù)名,參數(shù)類型,參數(shù)讀/寫權限) 內核支持的模塊參數(shù)類型包括: byte、short、ushort、int、u

21、int、long、ulong、charp(字符指針)、bool以u開頭的為無符號值。 static char *whom = world; static int howmany = 1; module_param(howmany, int, S_IRUGO); module_param(whom, charp, S_IRUGO); Sunday, July 31, 2022 364-3-1 設備驅動的Hello World模塊模塊也可以擁有參數(shù)數(shù)組形式為“module_param_array(數(shù)組名,數(shù)組類型,數(shù)組長,參數(shù)讀/寫權限)”。運行insmod或modprobe命令時,應使用逗號分隔

22、輸入的數(shù)組元素裝載模塊時改變參數(shù):可通過insmod或modprobeinsmod hello_ext.ko howmany=5 whom=Students modprobe也可以從它的配置文件(/etc/modprobe.conf)讀取參數(shù)的值Sunday, July 31, 2022 374.3.1 設備驅動的Hello World模塊模塊導出符號EXPORT_SYMBOL(name);EXPORT_SYMBOL_GPL(name); _GPL 版本的宏定義的導出符號只能對 GPL 許可的模塊可用注: 符號必須在模塊文件的全局部分導出, 不能在函數(shù)中導出 Sunday, July 31,

23、2022 384.3.1 設備驅動的Hello World模塊/hello.c#include #include MODULE_LICENSE(GPL);MODULE_AUTHOR(David Xie);MODULE_DESCRIPTION(Hello World Module);MODULE_ALIAS(a simplest module); extern int add_integar(int a,int b); extern int sub_integar(int a,int b); static int _init hello_init() int res_add = add_inte

24、gar(1,2); printk(“res_add=%dn”,res_add); return 0; static void _exit hello_exit() int res_sub = sub_integar(2,1); printk(“res_sub=%dn”,res_sub); module_init(hello_init);module_exit(hello_exit); / calculate.c#include #include MODULE_LICENSE(GPL); int add_integar(int a,int b) return a+b; int sub_integ

25、ar(int a,int b) return a-b; static int _init sym_init() return 0; static void _exit sym_exit(); module_init(sym_init);module_exit(sym_exit); EXPORT_SYMBOL(add_integar); EXPORT_SYMBOL(sub_integar); Sunday, July 31, 2022 394-3-1 設備驅動的Hello World模塊模塊聲明與描述 MODULE_AUTHOR(author); -聲明模塊的作者 MODULE_DESCRIPT

26、ION(description); -聲明模塊的描述MODULE_VERSION(version_string); -聲明模塊的版本 MODULE_DEVICE_TABLE(table_info); -聲明模塊的設備表MODULE_ALIAS(alternate_name); -聲明模塊的別名Sunday, July 31, 2022 404-3-1 設備驅動的Hello World模塊模塊的使用計數(shù) Linux2.4內核 MOD_INC_USE_COUNT(加一計數(shù)) MOD_DEC_USE_COUNT(減一計數(shù))Linux2.6內核中int try_module_get(struct mo

27、dule *module);void module_put(struct module *module);在Linux2.6內核下,對于設備驅動工程師而言,很少需要親自調用try_module_get()和module_put(),因為模塊的計數(shù)管理由內核里更底層的代碼(如總線驅動或是此類設備共用的核心模塊)來實現(xiàn),從而簡化了設備驅動的開發(fā)Sunday, July 31, 2022 414-3-2 內核驅動模塊與應用程序對比應用程序是一個進程編程從主函數(shù)main()開始主函數(shù)main返回即是進程結束驅動程序是一系列內核函數(shù)驅動程序向內核添加了一些函數(shù),是內核的一部分Open()Release(

28、)Read()Write()這些函數(shù)由內核在適當?shù)臅r候來調用這些函數(shù)可以用來完成硬件訪問等操作Sunday, July 31, 2022 424-3-3 編譯和裝載驅動模塊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 *, size_t,

29、 loff_t *);int (*readdir) (struct file *, void *, filldir_t);unsigned int (*poll) (struct file *, struct poll_table_struct *);long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);long (*compat_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 *, struct file *);int (*fsync) (struct file *, int datasync);int (*aio_fsync) (struct kiocb *, int datasync);int (*fasync) (int, struct file *, int);int (*lock) (struct file *,

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論