




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、Linux設備驅動設備驅動廣州嵌入式軟件公共技術支持中心梁老師2007年07月設備驅動概述設備驅動概述l操作系統是通過各種驅動程序來駕馭硬件設備,它為操作系統是通過各種驅動程序來駕馭硬件設備,它為用戶屏蔽了各種各樣的設備用戶屏蔽了各種各樣的設備,硬件設備的抽象。硬件設備的抽象。l設備驅動程序設備驅動程序: :處理和管理硬件控制器的軟件。處理和管理硬件控制器的軟件。l設備驅動程序是操作系統內核和機器硬件之間的接口。設備驅動程序是操作系統內核和機器硬件之間的接口。設備驅動概述設備驅動概述l設備由兩部分組成,一個是被稱為控制器的電器部分,設備由兩部分組成,一個是被稱為控制器的電器部分,另一個是機械部
2、分。另一個是機械部分。 l一組寄存器組被賦予到各個控制器。一組寄存器組被賦予到各個控制器。I/O端口包含端口包含4組寄組寄存器,即狀態寄存器,控制寄存器,數據輸入寄存器,存器,即狀態寄存器,控制寄存器,數據輸入寄存器,數據輸出寄存器。數據輸出寄存器。狀態寄存器擁有可以被狀態寄存器擁有可以被CPU讀取的讀取的(狀態狀態)位,用來位,用來 指示當前命令是否執行完畢,或者字節是否可以被指示當前命令是否執行完畢,或者字節是否可以被讀出或寫入,以及任何錯誤提示。讀出或寫入,以及任何錯誤提示??刂萍拇嫫鲃t用于啟動一條命令(指令)或者改變控制寄存器則用于啟動一條命令(指令)或者改變設備的設備的(工作工作)模
3、式。模式。數據輸入寄存器用于獲取輸入的數據。數據輸入寄存器用于獲取輸入的數據。數據輸出寄存器則向數據輸出寄存器則向CPU發送結果。發送結果。l處理器和設備之間的基本界面是控制和狀態寄存器。處理器和設備之間的基本界面是控制和狀態寄存器。 設備驅動概述設備驅動概述l寄存器擁有在寄存器擁有在I/O空間明確定義的地址范圍。空間明確定義的地址范圍。l通常這些地址在啟動時被分配。通常這些地址在啟動時被分配。如果設備是靜態加載的如果設備是靜態加載的,各個設備的地址范圍可能被預各個設備的地址范圍可能被預分配。這意味內核包含了已存在設備的驅動分配。這意味內核包含了已存在設備的驅動 程序。通程序。通過運行過運行“
4、cat /proc/ioports” 命令檢查其所使用的地命令檢查其所使用的地址范圍。第一列輸出顯示了端口的范圍而第二列則是址范圍。第一列輸出顯示了端口的范圍而第二列則是擁用這些端口的設備。擁用這些端口的設備。 設備驅動概述設備驅動概述l設備驅動的概念是非常抽象的并且處于一臺計算設備驅動的概念是非常抽象的并且處于一臺計算上所運行軟件的最低層。上所運行軟件的最低層。l由于直接到設備的硬件特性的限由于直接到設備的硬件特性的限 制。每個設備驅制。每個設備驅動都只管理一種單一類型的設備。動都只管理一種單一類型的設備。l如果一個應用如果一個應用 程序向設備提出(操作)要求。內程序向設備提出(操作)要求。
5、內核會聯系到對應的設備驅動,設備驅動接著向特核會聯系到對應的設備驅動,設備驅動接著向特定的設備發出命令。定的設備發出命令。l設備驅設備驅 動是一個函數集合:包含了許多調用入口,動是一個函數集合:包含了許多調用入口,類似于類似于open,close,read,write,ioctl,llseek 等。等。設備驅動概述設備驅動概述lLinuxLinux操作系統把設備操作系統把設備納入文件系統的范疇納入文件系統的范疇來管理。來管理。l文件操作是對設備操作的組織和抽象。設備操作則是文件操作是對設備操作的組織和抽象。設備操作則是對文件操作的最終實現。對文件操作的最終實現。 l每個設備都對應一個文件名每個
6、設備都對應一個文件名,在內核中也就對應一個,在內核中也就對應一個索引節點。索引節點。 l對文件操作的系統調用大都適用于設備文件。對文件操作的系統調用大都適用于設備文件。 l從應用程序的角度看,設備文件邏輯上的空間是一個從應用程序的角度看,設備文件邏輯上的空間是一個線性空間(起始地址為線性空間(起始地址為0 0,每讀取一個字節加,每讀取一個字節加1 1)。從)。從這個邏輯空間到具體設備物理空間(如磁盤的磁道、這個邏輯空間到具體設備物理空間(如磁盤的磁道、扇區)的映射則是由內核提供,并被劃分為扇區)的映射則是由內核提供,并被劃分為文件操作文件操作和和設備驅動設備驅動兩個層次。兩個層次。設備驅動概述
7、設備驅動概述lLinuxLinux將設備分成兩大類。將設備分成兩大類。一類像鍵盤那樣以字符(字節)為單位,逐個字符一類像鍵盤那樣以字符(字節)為單位,逐個字符進行輸入輸出的設備,稱為進行輸入輸出的設備,稱為字符設備字符設備。一類是像磁盤那樣以塊或扇區為單位,成塊進行輸一類是像磁盤那樣以塊或扇區為單位,成塊進行輸入輸出的設備,稱為入輸出的設備,稱為塊設備塊設備。文件系統通常都建立在塊設備上。文件系統通常都建立在塊設備上。設備驅動概述設備驅動概述l文件操作和設備驅動是對一個具體的設備操作的不同層文件操作和設備驅動是對一個具體的設備操作的不同層次。從這種觀點出發,從概念上可以把一個系統劃分為次。從這
8、種觀點出發,從概念上可以把一個系統劃分為應用、文件系統和設備驅動三個層次。應用、文件系統和設備驅動三個層次。將請求加入請求隊列 請求提交操作readsys_readfile- f_op- readdo_generic_file_read用戶空間函數內核系統調用文件系統讀操作通用文件系統讀操作readsys_readfile-f_op-readdo_generic_file_read用戶空間函數內核系統調用文件系統讀操作submit_bhsubmit_bhadd_requstadd_requst設備驅動概述設備驅動概述設備驅動概述設備驅動概述l要使一項設備可以被應用程序訪問,首先要在系統中要使一
9、項設備可以被應用程序訪問,首先要在系統中建立一個代表此設備的設備文件,這是通過系統調用建立一個代表此設備的設備文件,這是通過系統調用mknode()mknode()實現的。此外,更重要的是在設備驅動層要實現的。此外,更重要的是在設備驅動層要有這種設備的驅動程序。有這種設備的驅動程序。設備驅動概述設備驅動概述l設備文件:設備文件:任何設備都被當作路徑任何設備都被當作路徑/dev 的設備文件處理,并通的設備文件處理,并通過這些設備文件提供訪問硬件的方法。過這些設備文件提供訪問硬件的方法。每個設備文件除了設備名外,還有類型、主設備號、每個設備文件除了設備名外,還有類型、主設備號、次設備號這三個屬性。
10、次設備號這三個屬性。設備文件是通過設備文件是通過mknodmknod系統調用創建的。其原型為:系統調用創建的。其原型為:mknod(const char mknod(const char * * filename, int mode, dev_t filename, int mode, dev_t dev)dev)mknod /dev/led0 c 253 0 mknod /dev/led0 c 253 0 設備驅動概述設備驅動概述l主設備號和次設備號:主設備號和次設備號:主設備號標識設備對應的驅動程序。一般主設備號標識設備對應的驅動程序。一般“一個主一個主設備號對應一個驅動程序設備號對應一個
11、驅動程序”次設備號用于確定設備文件所指的設備。次設備號用于確定設備文件所指的設備??赏ㄟ^可通過ls l “設備文件名設備文件名”命令查看設備的主次設命令查看設備的主次設備號,以及設備的類型。備號,以及設備的類型。設備驅動概述設備驅動概述l主設備號和次設備號的內部表達:主設備號和次設備號的內部表達:Dev_t類型用于保存設備號,稱為設備編號。類型用于保存設備號,稱為設備編號。/linux/types.h文件中定義。文件中定義。目前設備編號目前設備編號dev_t是一個是一個32位的整數,其中位的整數,其中12位位表示主設備號,表示主設備號,20位表示次設備號。位表示次設備號。通過設備編號獲取主次設
12、備號:通過設備編號獲取主次設備號:MAJOR(dev_t dev);MINOR(dev_t dev);通過主次設備號合成設備編號:通過主次設備號合成設備編號:MKDEV(int major, int minor);Dev_t格式以后可能會發生變化,但只要使用這些格式以后可能會發生變化,但只要使用這些宏,就可保證設備驅動程序的正確性。宏,就可保證設備驅動程序的正確性。一些重要的數據結構一些重要的數據結構l大部分驅動程序涉及三個重要的內核數據結構:大部分驅動程序涉及三個重要的內核數據結構:文件操作文件操作file_operations結構體結構體文件對象文件對象file結構體結構體索引節點索引節點
13、inode結構體結構體一些重要的數據結構一些重要的數據結構l文件操作結構體文件操作結構體file_operations結構體結構體file_operations在頭文件在頭文件 linux/fs.h中定義,中定義,用來存儲驅動內核模塊提供的用來存儲驅動內核模塊提供的對設備進行各種操作對設備進行各種操作的函數的指針的函數的指針。結構體的每個域都對應著驅動模塊用來處理某個被結構體的每個域都對應著驅動模塊用來處理某個被請求的事務的函數的地址。請求的事務的函數的地址。struct file_operations struct module *owner; loff_t(*llseek) (struct
14、 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, loff_t *);。 一些重要的數據結構一些重要的數據結構lfile_operations重要的成員重要的成員Struct module *owner ,指向擁有該結構體的模,指向擁有該結構體的模塊的指針。塊的指針。方法方法llseek用來修改文件的當前讀寫位置,把新位用來修改文件的當前讀寫位置,把新位
15、置作為返回值返回。置作為返回值返回。方法方法read用來從設備中讀取數據。非負返回值表示用來從設備中讀取數據。非負返回值表示成功讀取的直接數。成功讀取的直接數。方法方法write向設備發送數據。向設備發送數據。方法方法ioctl提供一種執行設備特定命令的方法。提供一種執行設備特定命令的方法。一些重要的數據結構一些重要的數據結構lfile_operations重要的成員重要的成員驅動內核模塊是不需要實現每個函數的。相對應的驅動內核模塊是不需要實現每個函數的。相對應的file_operations的項就為的項就為 NULL。Gcc的語法擴展,使得可以定義該結構體:的語法擴展,使得可以定義該結構體:
16、struct file_operations fops = read: device_read, write: device_write, open: device_open, release: device_release ; 這種語法清晰,沒有顯示聲明的結構體成員都被這種語法清晰,沒有顯示聲明的結構體成員都被gcc初始化為初始化為NULL。 一些重要的數據結構一些重要的數據結構lfile_operations重要的成員重要的成員標準標準C的標記化結構體的初始化方法:的標記化結構體的初始化方法:struct file_operations fops = .read = device_read
17、,.write = device_write, .open = device_open, .release = device_release; 推薦使用該方法,提高移植性,方法允許對結構體成員進行重推薦使用該方法,提高移植性,方法允許對結構體成員進行重新排列。新排列。沒有顯示聲明的結構體成員同樣都被沒有顯示聲明的結構體成員同樣都被gcc初始化為初始化為NULL。指向結構體指向結構體file_operations的指針通常命名為的指針通常命名為fops。 一些重要的數據結構一些重要的數據結構l文件對象文件對象file結構體結構體文件對象文件對象file代表著一個打開的文件代表著一個打開的文件。進
18、程通過文進程通過文件描述符件描述符fdfd與已打開文件的與已打開文件的filefile結構相聯系。進程結構相聯系。進程通過它對文件的線性邏輯空間進行操作。例如:通過它對文件的線性邏輯空間進行操作。例如:file-f_op-read();file-f_op-read();Struct file Struct file 在在中定義。中定義。指向結構體指向結構體struct file的指針通常命名為的指針通常命名為filp,或者,或者file。建議使用文件指針。建議使用文件指針filp。一些重要的數據結構一些重要的數據結構l文件對象文件對象file結構體的成員結構體的成員Struct file_op
19、erations *f_op;與文件相關的操作結構體指針。與文件相關的操作與文件相關的操作結構體指針。與文件相關的操作是在打開文件的時候確定下來的,也就是確定該指是在打開文件的時候確定下來的,也就是確定該指針的值。可在需要的時候,改變指針所指向的文件針的值??稍谛枰臅r候,改變指針所指向的文件操作結構體。用操作結構體。用C語言實現面向對象編程的方法重語言實現面向對象編程的方法重載。載。其他成員可先忽略,后面具體實例分析。因為設備其他成員可先忽略,后面具體實例分析。因為設備驅動模塊并不自己直接填充結構體驅動模塊并不自己直接填充結構體 file,只是使用,只是使用file中的數據。中的數據。 一些
20、重要的數據結構一些重要的數據結構l索引節點索引節點inode結構結構文件打開,在內存建立副本后,由文件打開,在內存建立副本后,由唯一的索引節點唯一的索引節點inode描述。描述。與與file結構不同。結構不同。file結構是進程使用的結構,進程每打開一個文結構是進程使用的結構,進程每打開一個文件,就建立一個件,就建立一個file結構。不同的進程打開同一結構。不同的進程打開同一個文件,建立不同的個文件,建立不同的file結構。結構。Inode結構是內核使用的結構,文件在內存建立結構是內核使用的結構,文件在內存建立副本,就建立一個副本,就建立一個inode結構來描述。結構來描述。一個文件一個文件在
21、內存里面只有一個在內存里面只有一個inode結構對應。結構對應。一些重要的數據結構一些重要的數據結構l索引節點索引節點inode結構結構Inode結構包含大量描述文件信息的成員變量。結構包含大量描述文件信息的成員變量。但是對于描述設備文件的但是對于描述設備文件的inode,跟設備驅動有關,跟設備驅動有關的成員只有兩個。的成員只有兩個。Dev_t i_rdev; 包含真正的設備編號。包含真正的設備編號。Struct cdev *i_cdev; 指向指向cdev結構體的指針。結構體的指針。cdev是表示字符設備的內核數據結構。是表示字符設備的內核數據結構。從從inode中獲得主設備號和次設備號的宏
22、:中獲得主設備號和次設備號的宏:Unsigned int iminor(struct inode *inode);Unsigned int imajor(struct inode *inode);驅動程序中的內存分配驅動程序中的內存分配l在在Linux內核模式下,不能使用用戶態的內核模式下,不能使用用戶態的malloc()和和free()函數申請和釋放內存。函數申請和釋放內存。l內核編程最常用的內存申請和釋放函數為內核編程最常用的內存申請和釋放函數為kmalloc()和和kfree(),其原型為:,其原型為:include/linux/kernel.hvoid void * *kmalloc(
23、unsigned int len, int priority);kmalloc(unsigned int len, int priority);void kfree(void void kfree(void * *_ptr);_ptr);priority參數參數:通常設置為通常設置為GFP_KERNEL,可能會引起睡眠,可能會引起睡眠.如果在中斷服務程序里申請內存則要用如果在中斷服務程序里申請內存則要用GFP_ATOMIC參數,參數,在中斷中是不允許睡眠的。在中斷中是不允許睡眠的。初始化和卸載函數初始化和卸載函數l驅動程序是內核的一部分,因此我們需要給其添驅動程序是內核的一部分,因此我們需要給
24、其添加模塊初始化函數,該函數用來完成對所控設備加模塊初始化函數,該函數用來完成對所控設備的初始化工作,并調用的初始化工作,并調用register_chrdev() 函數函數注冊字符設備注冊字符設備.int register_chrdev(unsigned int major, const char *name, struct file_operations *fops);major 是給定的主設備號。為0代表什么?name 是驅動的名字(將出現在 /proc/devices), fops 是設備驅動的file_operations 結構。register_chrdev 將給設備分配 0 - 2
25、55 的次設備號, 并且為每一個建立一個缺省的 cdev 結構。l與模塊初始化函數對應的就是模塊卸載函數,需與模塊初始化函數對應的就是模塊卸載函數,需要調用要調用register_chrdev()的的反函數反函數設備操作函數集的定義設備操作函數集的定義lfile_operations結構體,驅動程序只是利用其中結構體,驅動程序只是利用其中的一部分。的一部分。l對于字符設備來說,要提供的主要入口有:對于字符設備來說,要提供的主要入口有:open ()、release ()、read ()、write ()、ioctl ()等。等。設備操作函數集的定義設備操作函數集的定義lopen()函數函數對設
26、備特殊文件進行對設備特殊文件進行open()系統調用時,將調用驅動系統調用時,將調用驅動程序的程序的open () 函數:函數:int (int (* *open)(struct inode open)(struct inode * * ,struct file ,struct file * *););參數參數inode為設備特殊文件的為設備特殊文件的inode (索引結點索引結點) 結結構的指針,構的指針,參數參數file是指向這一設備的文件結構的指針。是指向這一設備的文件結構的指針。open()的主要任務是確定硬件處在就緒狀態、驗證次的主要任務是確定硬件處在就緒狀態、驗證次設備號的合法性設
27、備號的合法性(次設備號可以用次設備號可以用MINOR(inode- i - rdev) 取得取得)、控制使用設備的進程數、根據執行情況、控制使用設備的進程數、根據執行情況返回狀態碼返回狀態碼(0表示成功,負數表示存在錯誤表示成功,負數表示存在錯誤) 等;等;設備操作函數集的定義設備操作函數集的定義lrelease()函數函數當最后一個打開設備的用戶進程執行當最后一個打開設備的用戶進程執行close ()系統調系統調用時,內核將調用驅動程序的用時,內核將調用驅動程序的release () 函數:函數:void (void (* *release) (struct inode release) (
28、struct inode * * ,struct file ,struct file * *) ;) ;release 函數的主要任務是清理未結束的輸入函數的主要任務是清理未結束的輸入/輸出操輸出操作、釋放資源、用戶自定義排他標志的復位等作、釋放資源、用戶自定義排他標志的復位等.設備操作函數集的定義設備操作函數集的定義lread()函數函數lRead的任務的任務, 就是從設備拷貝數據到用戶空間。就是從設備拷貝數據到用戶空間。當對設備特殊文件進行當對設備特殊文件進行read() 系統調用時,將調用驅系統調用時,將調用驅動程序動程序read() 函數:函數:ssize_t read(struct
29、file *filp, char _user *buff, size_t count, loff_t *offp);filp 是文件對象指針, count 是請求的傳輸數據大小. buff 參數對write來說是指向持有被寫入數據的緩存, 對read則是放入新數據的空緩存. offp 是指向一個“long offset type”的指針, 它指出用戶正在存取的文件位置. 返回值是“signed size type”類型;設備操作函數集的定義設備操作函數集的定義lwrite( ) 函數函數Write的任務,則從用戶空間拷貝數據到設備。的任務,則從用戶空間拷貝數據到設備。當設備特殊文件進行當設備特
30、殊文件進行write () 系統調用時,將調用驅系統調用時,將調用驅動程序的動程序的write () 函數:函數:ssize_t write(struct file *filp, const char _user *buff, size_t count, loff_t *offp);filp 是文件對象指針, count 是請求的傳輸數據大小. buff 參數對write來說是指向持有被寫入數據的緩存, 對read則是放入新數據的空緩存. offp 是指向一個“long offset type”的指針, 它指出用戶正在存取的文件位置. 返回值是“signed size type”類型;設備操作
31、函數集的定義設備操作函數集的定義lread 和和 write 方法的方法的 buff 參數是用戶空間指針,參數是用戶空間指針,不能被內核代碼直接解引用。不能被內核代碼直接解引用。_user字符串只是字符串只是形式上的說明,表明是用戶空間地址。形式上的說明,表明是用戶空間地址。l驅動必須能夠存取用戶空間緩存以完成它的工作。驅動必須能夠存取用戶空間緩存以完成它的工作。內核如何解決這個問題?內核如何解決這個問題?為安全起見,內核提供專用的函數來完成對用戶空間為安全起見,內核提供專用的函數來完成對用戶空間的存取。這些專用函數在的存取。這些專用函數在中聲明。unsigned long copy_to_u
32、ser(void _user *to,const void *from,unsigned long count);unsigned long copy_from_user(void *to,const void _user *from,unsigned long count);大多數讀寫函數都會調用這兩個函數,用于跟應用程序空間交流大多數讀寫函數都會調用這兩個函數,用于跟應用程序空間交流信息。信息。Read和和Write方法方法l典型的典型的Read函數對參數的使用。函數對參數的使用。S3C2410 的I/O 介紹lS3C2410 有117 個復用功能輸入輸出端口引腳,這些引腳是:lPortA
33、(GPA):32 個輸入/輸出端口lPortB(GPB):11 個輸入/輸出端口lPortC(GPC):16 個輸入/輸出端口lPortD(GPD):16 個輸入/輸出端口lPortE(GPE):16 個輸入/輸出端口lPortF(GPF):8 個輸入/輸出端口lPortG(GPG):16 個輸入/輸出端口lPortH(GPH):11 個輸入/輸出端口S3C2410 的I/O 介紹l端口控制說明l端口配置寄存器(GPACONGPHCON)大部分的引腳是復用的,所以必須對于每個引腳要求定義一個功能,端口配置寄存器定義了每個引腳的功能。l端口數據寄存器(GPADATGPHDAT)如果端口配置成輸出
34、端口,數據能夠被寫到端口數據寄存器的對應位,然后通過管腳輸出。如果端口配置成輸入端口,能從端口數據寄存器對應的位中讀出管腳上的電平l端口上拉寄存器(GPBUPGPHUP)端口上拉寄存器控制著每個端口組的上拉寄存器的使能或禁止,當對應位為0,這個引腳的上拉寄存器是允許的,當為1 時,上拉寄存器是禁止的。MIZI提供的提供的S3C2410.Hl使用一個使用一個32位的數來表示端口的使用情況。位的數來表示端口的使用情況。l模式模式 |上拉上拉 |端口端口 | 端口引腳端口引腳lMODE | PULLUP | PORT | OFSl不需要自己手動組合,通過宏定義以及不需要自己手動組合,通過宏定義以及S
35、HIFT和和MASK組合。見程序組合。見程序MIZI提供的提供的S3C2410.Hl端口的表示端口的表示l#define PORTA_OFS0l#define PORTB_OFS1l#define PORTC_OFS2l#define PORTD_OFS3l#define PORTE_OFS4l#define PORTF_OFS5l#define PORTG_OFS6l#define PORTH_OFS7MIZI提供的提供的S3C2410.Hl端口引腳的表示端口引腳的表示l#define GPIO_A0MAKE_GPIO_NUM(PORTA_OFS, 0)l#define GPIO_A1MAK
36、E_GPIO_NUM(PORTA_OFS, 1)l#define GPIO_A2MAKE_GPIO_NUM(PORTA_OFS, 2)l#define GPIO_A3MAKE_GPIO_NUM(PORTA_OFS, 3)l。l#define MAKE_GPIO_NUM(p, o)(p GPIO_PORT_SHIFTT) | (o GPIO_OFS_SHIFT)MIZI提供的提供的S3C2410.Hlset_gpio_ctrl(x) l功能:配置端口引腳的功能,設置功能:配置端口引腳的功能,設置IO口控制寄存口控制寄存器和上拉寄存器器和上拉寄存器l用法:用法:set_gpio_ctrl(模式模式
37、|上拉上拉?|IO腳腳) l模式模式|是否上拉是否上拉|IO腳腳,在,在S3C2410.h中都有其定義中都有其定義好的名字。好的名字。l set_gpio_ctrl(GPIO_E11 | GPIO_PULLUP_DIS |GPIO_MODE_OUT);MIZI提供的提供的S3C2410.Hlwrite_gpio_bit(x, v) l功能:把端口功能:把端口 對應的端口數據寄存器對應的端口數據寄存器x位設置為位設置為vlwrite_gpio_bit(GPIO_E11, 0); lread_gpio_bit(x) l功能:把端口數據寄存器功能:把端口數據寄存器x位的狀態位的狀態 讀入,函數讀入,
38、函數返回值既是其狀態返回值既是其狀態lread_gpio_bit(GPIO_G11); MIZI提供的提供的S3C2410.Hlwrite_gpio_reg(x, v) l功能:把端口數據寄存器功能:把端口數據寄存器x 設置為設置為v lread_gpio_reg(x) l功能:讀取端口數據寄存器功能:讀取端口數據寄存器x,函數返回值既是,函數返回值既是其數據其數據 l按驅動的框架寫好驅動,實現初始化、卸載函數,按驅動的框架寫好驅動,實現初始化、卸載函數,以及以及file_opertation操作集。操作集。l對于對于led使用的使用的gpio函數,內核沒有輸出作為公函數,內核沒有輸出作為公開
39、符號,所以需要手動修改內核代碼,代碼放在開符號,所以需要手動修改內核代碼,代碼放在arch/arm/march-s3c2410/gpio.c,輸出符號:,輸出符號:EXPORT_SYMBOL(s3c2410_gpio_setpin);EXPORT_SYMBOL(s3c2410_gpio_cfgpin);EXPORT_SYMBOL(s3c2410_gpio_pullup);l編寫驅動模塊的編寫驅動模塊的Makefile。l交叉編譯驅動模塊交叉編譯驅動模塊lNFS加載驅動模塊,進行測試。加載驅動模塊,進行測試。嵌入式鍵盤驅動廣州嵌入式軟件公共技術支持中心廣州嵌入式軟件公共技術支持中心梁老師2007
40、年7月注冊中斷服務例程注冊中斷服務例程 l中斷線是一個寶貴且常常有限的資源中斷線是一個寶貴且常常有限的資源, , 特別當它特別當它們只有們只有1515個時。內核維護一個中斷線的注冊表。個時。內核維護一個中斷線的注冊表。l要使用中斷線,就要進行中斷線的申請,也就是要使用中斷線,就要進行中斷線的申請,也就是IRQ(Interrupt ReQuirement)IRQ(Interrupt ReQuirement),因此我們也常把,因此我們也常把申請一條中斷線稱為申請一個申請一條中斷線稱為申請一個IRQIRQ或者是申請一或者是申請一個中斷號。個中斷號。lIRQIRQ線是從線是從0 0開始順序編號的;第一
41、條開始順序編號的;第一條IRQIRQ線通常線通常表示成表示成IRQ0IRQ0。IRQnIRQn的缺省向量是的缺省向量是n+32n+32。注冊中斷服務例程注冊中斷服務例程 l并不是每個設備都可以向中斷線上發中斷信號的,并不是每個設備都可以向中斷線上發中斷信號的,只有對某一條確定的中斷線擁有了控制權,才可只有對某一條確定的中斷線擁有了控制權,才可以向這條中斷線上發送信號。以向這條中斷線上發送信號。l計算機的外部設備越來越多,所以計算機的外部設備越來越多,所以15條中斷線已條中斷線已經不夠用了,中斷線是非常寶貴的資源。經不夠用了,中斷線是非常寶貴的資源。l只有當設備需要中斷的時候才申請占用一個只有當
42、設備需要中斷的時候才申請占用一個IRQ,或者是在申請或者是在申請IRQ時采用共享中斷的方式,這樣時采用共享中斷的方式,這樣可以讓更多的設備使用中斷。可以讓更多的設備使用中斷。注冊中斷服務例程注冊中斷服務例程 l在在 實現中斷注冊接口實現中斷注冊接口:int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),unsigned long flags,const char *dev_name, void *dev_id);void free_irq(unsigned int irq,
43、 void *dev_id);lrequest_irq 的返回值是的返回值是 0 指示申請成功,為負指示申請成功,為負值時表示錯誤碼。函數返回值時表示錯誤碼。函數返回 -EBUSY 表示已經有表示已經有另一個驅動占用了所要申請的中斷線。另一個驅動占用了所要申請的中斷線。注冊中斷服務例程注冊中斷服務例程 lrequest_irq的參數說明:的參數說明:unsigned int irq, 要申請的中斷號。要申請的中斷號。對某些設備,如傳統對某些設備,如傳統PC設備上的系統時鐘或鍵盤,設備上的系統時鐘或鍵盤,這個值通常是預先確定的。這個值通常是預先確定的。而對于大多數其它設備來說,這個值要么可以通過
44、而對于大多數其它設備來說,這個值要么可以通過探測獲取,要么可以動態確定。探測獲取,要么可以動態確定。irqreturn_t (*handler)(int, void *, struct pt_regs *),要安裝的中斷處理函數指針。后面介紹。注冊中斷服務例程注冊中斷服務例程 lrequest_irq的參數說明:的參數說明:unsigned long flags,與中斷管理相關的位掩碼選項。const char *dev_name, 用在 /proc/interrupts 中顯示中斷的擁有者。void *dev_id這個指針用于共享的中斷線。做為驅動程序的私有數據區(可用來識別那個設備產生的中
45、斷)。不使用共享中斷線方式時,可設置為NULL。注冊中斷服務例程注冊中斷服務例程 lflags參數的詳細說明:參數的詳細說明:Flags的每個位有不同含義SA_INTERRUPT當該位被設置時, 表示這是一個“快速”中斷??焖僦袛嗵幚砝踢\行時,屏蔽中斷。SA_SHIRQ這個位表示中斷可以在設備間共享。proc 文件系統中的中斷信息文件系統中的中斷信息l/proc/interrupts反映系統的中斷信息反映系統的中斷信息第一列是 IRQ 號給出每個中斷線發生中斷的次數。給出每個中斷線發生中斷的次數。給出處理中斷的可編程中斷控制器。給出處理中斷的可編程中斷控制器。給出在該中斷號上注冊中斷處理例程
46、的設備名稱。給出在該中斷號上注冊中斷處理例程的設備名稱。實現中斷處理例程實現中斷處理例程l首先中斷處理例程也是普通的首先中斷處理例程也是普通的C程序。程序。l特別之處:特別之處:在中斷時間內運行,不能向用戶空間發送或者接收數在中斷時間內運行,不能向用戶空間發送或者接收數據。據。不能做任何導致休眠的操作。不能做任何導致休眠的操作。不能調用不能調用schedule函數。函數。無論快速還是慢速中斷處理例程,都應該設計成執行無論快速還是慢速中斷處理例程,都應該設計成執行時間盡可能短。時間盡可能短。實現中斷處理例程實現中斷處理例程l中斷處理函數的參數和返回值中斷處理函數的參數和返回值irqreturn_
47、t (*handler)(int, void *, struct pt_regs *)irqreturn_t short_interrupt(int irq, void *dev_id, struct pt_regs *regs)Irq 中斷號中斷號Dev_id 驅動程序可用的數據區,通常可傳遞指向描述設備的數驅動程序可用的數據區,通??蓚鬟f指向描述設備的數據結構指針。據結構指針。struct pt_regs *regs,保存了處理器進入中斷代碼之前的,保存了處理器進入中斷代碼之前的cpu寄存器的值。一般驅動可不要。寄存器的值。一般驅動可不要。矩陣式鍵盤原理矩陣式鍵盤原理l矩陣式鍵盤一般適用于
48、按鍵數量較多的場合,它由行線矩陣式鍵盤一般適用于按鍵數量較多的場合,它由行線和列線組成,按鍵位于行、列的交叉點上。和列線組成,按鍵位于行、列的交叉點上。l如圖所示,一個如圖所示,一個44的行、列結構可以構成一個有的行、列結構可以構成一個有16個個按鍵的鍵盤。按鍵的鍵盤。矩陣式鍵盤原理矩陣式鍵盤原理l按鍵設置在行、列交叉點上,行、列分別連接到按鍵設置在行、列交叉點上,行、列分別連接到按鍵開關的兩端。行線通過上拉電阻接到十按鍵開關的兩端。行線通過上拉電阻接到十5 V上。上。l平時無按鍵動作時,行線處于高電平狀態平時無按鍵動作時,行線處于高電平狀態;而當有而當有健按下時,行線電平狀態將由通過此按鍵的
49、列線健按下時,行線電平狀態將由通過此按鍵的列線電平決定電平決定:列線電平如果為低,行線電平為低列線電平如果為低,行線電平為低;列列線電平如果為高,則行線電平亦為高。這一點是線電平如果為高,則行線電平亦為高。這一點是識別矩陣式鍵盤是否被按下的關鍵所在。識別矩陣式鍵盤是否被按下的關鍵所在。矩陣式鍵盤原理矩陣式鍵盤原理l矩陣鍵盤按鍵的識別方法分兩步進行矩陣鍵盤按鍵的識別方法分兩步進行:l識別鍵盤哪一行的鍵被按下。讓所有列線均為識別鍵盤哪一行的鍵被按下。讓所有列線均為低電平,檢查各行線電平是否為低。如果有行線低電平,檢查各行線電平是否為低。如果有行線為低,則說明該行有鍵被按下,否則說明無鍵被為低,則說明該行有鍵被按下,否則說明無鍵被按下。按下。l如果某行有鍵被按下,識別鍵盤哪一
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030中國吹塑機行業市場發展分析與發展趨勢及投資風險研究報告
- 2025-2030中國古董行業市場深度調研及競爭格局與投資前景研究報告
- 教育培訓課程設計優化措施
- 2025-2030中國雙目鏡行業市場發展趨勢與前景展望戰略研究報告
- 2025-2030中國原聲吉他橋行業市場發展趨勢與前景展望戰略研究報告
- 2025-2030中國危險場所LED燈行業市場發展趨勢與前景展望戰略研究報告
- 2025-2030中國卡爾費休水分測定儀行業市場發展趨勢與前景展望戰略研究報告
- 2025-2030中國醫藥包裝機械行業市場發展趨勢與前景展望戰略研究報告
- 2025-2030中國化糞池卡車行業市場發展趨勢與前景展望戰略研究報告
- 2025-2030中國包裝材料行業市場發展分析及發展趨勢與投資戰略研究報告
- 高三數學復習備考策略
- 六、七年級走進文言文譯文
- 幼兒園中班美術《瘋狂的頭發》課件
- 半月板損傷的護理查房
- 滬教版初中數學初二數學上冊《二次根式的運算》教學設計
- 糧庫出租合同書本
- 皮膚科治療知情同意書
- 2022年桂林臨桂區教師招聘考試真題
- 【基于STM32智能門鎖系統的設計10000字(論文)】
- 液壓支架外文翻譯
- 我的家鄉煙臺課件
評論
0/150
提交評論