




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、Linux設(shè)備驅(qū)動設(shè)備驅(qū)動廣州嵌入式軟件公共技術(shù)支持中心梁老師2007年07月設(shè)備驅(qū)動概述設(shè)備驅(qū)動概述l操作系統(tǒng)是通過各種驅(qū)動程序來駕馭硬件設(shè)備,它為操作系統(tǒng)是通過各種驅(qū)動程序來駕馭硬件設(shè)備,它為用戶屏蔽了各種各樣的設(shè)備用戶屏蔽了各種各樣的設(shè)備,硬件設(shè)備的抽象。硬件設(shè)備的抽象。l設(shè)備驅(qū)動程序設(shè)備驅(qū)動程序: :處理和管理硬件控制器的軟件。處理和管理硬件控制器的軟件。l設(shè)備驅(qū)動程序是操作系統(tǒng)內(nèi)核和機器硬件之間的接口。設(shè)備驅(qū)動程序是操作系統(tǒng)內(nèi)核和機器硬件之間的接口。設(shè)備驅(qū)動概述設(shè)備驅(qū)動概述l設(shè)備由兩局部組成,一個是被稱為控制器的電器局部,設(shè)備由兩局部組成,一個是被稱為控制器的電器局部,另一個是機械局
2、部。另一個是機械局部。 l一組存放器組被賦予到各個控制器。一組存放器組被賦予到各個控制器。I/O端口包含端口包含4組存組存放器,即狀態(tài)存放器,控制存放器,數(shù)據(jù)輸入存放器,放器,即狀態(tài)存放器,控制存放器,數(shù)據(jù)輸入存放器,數(shù)據(jù)輸出存放器。數(shù)據(jù)輸出存放器。l狀態(tài)存放器擁有可以被狀態(tài)存放器擁有可以被CPU讀取的讀取的(狀態(tài)狀態(tài))位,用來位,用來 指指示當前命令是否執(zhí)行完畢,或者字節(jié)是否可以被讀出示當前命令是否執(zhí)行完畢,或者字節(jié)是否可以被讀出或?qū)懭?,以及任何錯誤提示。或?qū)懭?,以及任何錯誤提示。l控制存放器那么用于啟動一條命令指令或者改變控制存放器那么用于啟動一條命令指令或者改變設(shè)備的設(shè)備的(工作工作)模
3、式。模式。l數(shù)據(jù)輸入存放器用于獲取輸入的數(shù)據(jù)。數(shù)據(jù)輸入存放器用于獲取輸入的數(shù)據(jù)。l數(shù)據(jù)輸出存放器那么向數(shù)據(jù)輸出存放器那么向CPU發(fā)送結(jié)果。發(fā)送結(jié)果。l處理器和設(shè)備之間的根本界面是控制和狀態(tài)存放器。處理器和設(shè)備之間的根本界面是控制和狀態(tài)存放器。 設(shè)備驅(qū)動概述設(shè)備驅(qū)動概述l存放器擁有在存放器擁有在I/O空間明確定義的地址范圍??臻g明確定義的地址范圍。l通常這些地址在啟動時被分配。通常這些地址在啟動時被分配。l如果設(shè)備是靜態(tài)加載的如果設(shè)備是靜態(tài)加載的,各個設(shè)備的地址范圍可能各個設(shè)備的地址范圍可能被預(yù)分配。這意味內(nèi)核包含了已存在設(shè)備的驅(qū)動被預(yù)分配。這意味內(nèi)核包含了已存在設(shè)備的驅(qū)動 程序。通過運行程序。
4、通過運行“cat /proc/ioports 命令檢查命令檢查其所使用的地址范圍。第一列輸出顯示了端口的其所使用的地址范圍。第一列輸出顯示了端口的范圍而第二列那么是擁用這些端口的設(shè)備。范圍而第二列那么是擁用這些端口的設(shè)備。 設(shè)備驅(qū)動概述設(shè)備驅(qū)動概述l設(shè)備驅(qū)動的概念是非常抽象的并且處于一臺計算設(shè)備驅(qū)動的概念是非常抽象的并且處于一臺計算上所運行軟件的最低層。上所運行軟件的最低層。l由于直接到設(shè)備的硬件特性的限由于直接到設(shè)備的硬件特性的限 制。每個設(shè)備驅(qū)制。每個設(shè)備驅(qū)動都只管理一種單一類型的設(shè)備。動都只管理一種單一類型的設(shè)備。l如果一個應(yīng)用如果一個應(yīng)用 程序向設(shè)備提出操作要求。內(nèi)程序向設(shè)備提出操作要
5、求。內(nèi)核會聯(lián)系到對應(yīng)的設(shè)備驅(qū)動,設(shè)備驅(qū)動接著向特核會聯(lián)系到對應(yīng)的設(shè)備驅(qū)動,設(shè)備驅(qū)動接著向特定的設(shè)備發(fā)出命令。定的設(shè)備發(fā)出命令。l設(shè)備驅(qū)設(shè)備驅(qū) 動是一個函數(shù)集合:包含了許多調(diào)用入口,動是一個函數(shù)集合:包含了許多調(diào)用入口,類似于類似于open,close,read,write,ioctl,llseek 等。等。設(shè)備驅(qū)動概述設(shè)備驅(qū)動概述lLinuxLinux操作系統(tǒng)把設(shè)備納入文件系統(tǒng)的范疇來管理。操作系統(tǒng)把設(shè)備納入文件系統(tǒng)的范疇來管理。l文件操作是對設(shè)備操作的組織和抽象。設(shè)備操作那么文件操作是對設(shè)備操作的組織和抽象。設(shè)備操作那么是對文件操作的最終實現(xiàn)。是對文件操作的最終實現(xiàn)。 l每個設(shè)備都對應(yīng)一個文
6、件名,在內(nèi)核中也就對應(yīng)一個每個設(shè)備都對應(yīng)一個文件名,在內(nèi)核中也就對應(yīng)一個索引節(jié)點。索引節(jié)點。 l對文件操作的系統(tǒng)調(diào)用大都適用于設(shè)備文件。對文件操作的系統(tǒng)調(diào)用大都適用于設(shè)備文件。 l從應(yīng)用程序的角度看,設(shè)備文件邏輯上的空間是一個從應(yīng)用程序的角度看,設(shè)備文件邏輯上的空間是一個線性空間起始地址為線性空間起始地址為0 0,每讀取一個字節(jié)加,每讀取一個字節(jié)加1 1。從。從這個邏輯空間到具體設(shè)備物理空間如磁盤的磁道、這個邏輯空間到具體設(shè)備物理空間如磁盤的磁道、扇區(qū)的映射那么是由內(nèi)核提供,并被劃分為文件操扇區(qū)的映射那么是由內(nèi)核提供,并被劃分為文件操作和設(shè)備驅(qū)動兩個層次。作和設(shè)備驅(qū)動兩個層次。設(shè)備驅(qū)動概述設(shè)備
7、驅(qū)動概述lLinuxLinux將設(shè)備分成兩大類。將設(shè)備分成兩大類。l一類像鍵盤那樣以字符字節(jié)為單位,逐個字符進一類像鍵盤那樣以字符字節(jié)為單位,逐個字符進行輸入輸出的設(shè)備,稱為字符設(shè)備。行輸入輸出的設(shè)備,稱為字符設(shè)備。l一類是像磁盤那樣以塊或扇區(qū)為單位,成塊進行輸入一類是像磁盤那樣以塊或扇區(qū)為單位,成塊進行輸入輸出的設(shè)備,稱為塊設(shè)備。輸出的設(shè)備,稱為塊設(shè)備。l文件系統(tǒng)通常都建立在塊設(shè)備上。文件系統(tǒng)通常都建立在塊設(shè)備上。設(shè)備驅(qū)動概述設(shè)備驅(qū)動概述l文件操作和設(shè)備驅(qū)動是對一個具體的設(shè)備操作的不同層文件操作和設(shè)備驅(qū)動是對一個具體的設(shè)備操作的不同層次。從這種觀點出發(fā),從概念上可以把一個系統(tǒng)劃分為次。從這種
8、觀點出發(fā),從概念上可以把一個系統(tǒng)劃分為應(yīng)用、文件系統(tǒng)和設(shè)備驅(qū)動三個層次。應(yīng)用、文件系統(tǒng)和設(shè)備驅(qū)動三個層次。將請求加入請求隊列 請求提交操作readsys_readfile- f_op- readdo_generic_file_read用戶空間函數(shù)內(nèi)核系統(tǒng)調(diào)用文件系統(tǒng)讀操作通用文件系統(tǒng)讀操作readsys_readfile-f_op-readdo_generic_file_read用戶空間函數(shù)內(nèi)核系統(tǒng)調(diào)用文件系統(tǒng)讀操作submit_bhsubmit_bhadd_requstadd_requst設(shè)備驅(qū)動概述設(shè)備驅(qū)動概述設(shè)備驅(qū)動概述設(shè)備驅(qū)動概述l要使一項設(shè)備可以被應(yīng)用程序訪問,首先要在系統(tǒng)中要使一項
9、設(shè)備可以被應(yīng)用程序訪問,首先要在系統(tǒng)中建立一個代表此設(shè)備的設(shè)備文件,這是通過系統(tǒng)調(diào)用建立一個代表此設(shè)備的設(shè)備文件,這是通過系統(tǒng)調(diào)用mknode()mknode()實現(xiàn)的。此外,更重要的是在設(shè)備驅(qū)動層要實現(xiàn)的。此外,更重要的是在設(shè)備驅(qū)動層要有這種設(shè)備的驅(qū)動程序。有這種設(shè)備的驅(qū)動程序。設(shè)備驅(qū)動概述設(shè)備驅(qū)動概述l設(shè)備文件:設(shè)備文件:l任何設(shè)備都被當作路徑任何設(shè)備都被當作路徑/dev /dev 的設(shè)備文件處理,并通過的設(shè)備文件處理,并通過這些設(shè)備文件提供訪問硬件的方法。這些設(shè)備文件提供訪問硬件的方法。l每個設(shè)備文件除了設(shè)備名外,還有類型、主設(shè)備號、每個設(shè)備文件除了設(shè)備名外,還有類型、主設(shè)備號、次設(shè)備號
10、這三個屬性。次設(shè)備號這三個屬性。l設(shè)備文件是通過設(shè)備文件是通過mknodmknod系統(tǒng)調(diào)用創(chuàng)立的。其原型為:系統(tǒng)調(diào)用創(chuàng)立的。其原型為:mknod(const char mknod(const char * * filename, int mode, dev_t filename, int mode, dev_t dev)dev)lmknod /dev/led0 c 253 0 mknod /dev/led0 c 253 0 設(shè)備驅(qū)動概述設(shè)備驅(qū)動概述l主設(shè)備號和次設(shè)備號:主設(shè)備號和次設(shè)備號:l主設(shè)備號標識設(shè)備對應(yīng)的驅(qū)動程序。一般主設(shè)備號標識設(shè)備對應(yīng)的驅(qū)動程序。一般“一個主設(shè)一個主設(shè)備號對應(yīng)一個驅(qū)
11、動程序備號對應(yīng)一個驅(qū)動程序l次設(shè)備號用于確定設(shè)備文件所指的設(shè)備。次設(shè)備號用于確定設(shè)備文件所指的設(shè)備。l可通過可通過ls l “l(fā)s l “設(shè)備文件名命令查看設(shè)備的主次設(shè)設(shè)備文件名命令查看設(shè)備的主次設(shè)備號,以及設(shè)備的類型。備號,以及設(shè)備的類型。設(shè)備驅(qū)動概述設(shè)備驅(qū)動概述l主設(shè)備號和次設(shè)備號的內(nèi)部表達:主設(shè)備號和次設(shè)備號的內(nèi)部表達:Dev_t類型用于保存設(shè)備號,稱為設(shè)備編號。類型用于保存設(shè)備號,稱為設(shè)備編號。/linux/types.h文件中定義。文件中定義。目前設(shè)備編號目前設(shè)備編號dev_t是一個是一個32位的整數(shù),其中位的整數(shù),其中12位位表示主設(shè)備號,表示主設(shè)備號,20位表示次設(shè)備號。位表示次
12、設(shè)備號。通過設(shè)備編號獲取主次設(shè)備號:通過設(shè)備編號獲取主次設(shè)備號:MAJOR(dev_t dev);MINOR(dev_t dev);通過主次設(shè)備號合成設(shè)備編號:通過主次設(shè)備號合成設(shè)備編號:MKDEV(int major, int minor);Dev_t格式以后可能會發(fā)生變化,但只要使用這些格式以后可能會發(fā)生變化,但只要使用這些宏,就可保證設(shè)備驅(qū)動程序的正確性。宏,就可保證設(shè)備驅(qū)動程序的正確性。一些重要的數(shù)據(jù)結(jié)構(gòu)一些重要的數(shù)據(jù)結(jié)構(gòu)l大局部驅(qū)動程序涉及三個重要的內(nèi)核數(shù)據(jù)結(jié)構(gòu):大局部驅(qū)動程序涉及三個重要的內(nèi)核數(shù)據(jù)結(jié)構(gòu):l文件操作文件操作file_operationsfile_operations結(jié)
13、構(gòu)體結(jié)構(gòu)體l文件對象文件對象filefile結(jié)構(gòu)體結(jié)構(gòu)體l索引節(jié)點索引節(jié)點inodeinode結(jié)構(gòu)體結(jié)構(gòu)體一些重要的數(shù)據(jù)結(jié)構(gòu)一些重要的數(shù)據(jù)結(jié)構(gòu)l文件操作結(jié)構(gòu)體文件操作結(jié)構(gòu)體file_operations結(jié)構(gòu)體結(jié)構(gòu)體file_operations在頭文件在頭文件 linux/fs.h中定義,中定義,用來存儲驅(qū)動內(nèi)核模塊提供的用來存儲驅(qū)動內(nèi)核模塊提供的對設(shè)備進行各種操作對設(shè)備進行各種操作的函數(shù)的指針的函數(shù)的指針。結(jié)構(gòu)體的每個域都對應(yīng)著驅(qū)動模塊用來處理某個被結(jié)構(gòu)體的每個域都對應(yīng)著驅(qū)動模塊用來處理某個被請求的事務(wù)的函數(shù)的地址。請求的事務(wù)的函數(shù)的地址。struct file_operations str
14、uct 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, loff_t *);。 一些重要的數(shù)據(jù)結(jié)構(gòu)一些重要的數(shù)據(jù)結(jié)構(gòu)lfile_operations重要的成員重要的成員Struct module *owner ,指向擁有該結(jié)構(gòu)體的模,指向擁有該結(jié)構(gòu)體的模塊的指針。塊的指針。方法
15、方法llseek用來修改文件的當前讀寫位置,把新位用來修改文件的當前讀寫位置,把新位置作為返回值返回。置作為返回值返回。方法方法read用來從設(shè)備中讀取數(shù)據(jù)。非負返回值表示用來從設(shè)備中讀取數(shù)據(jù)。非負返回值表示成功讀取的直接數(shù)。成功讀取的直接數(shù)。方法方法write向設(shè)備發(fā)送數(shù)據(jù)。向設(shè)備發(fā)送數(shù)據(jù)。方法方法ioctl提供一種執(zhí)行設(shè)備特定命令的方法。提供一種執(zhí)行設(shè)備特定命令的方法。一些重要的數(shù)據(jù)結(jié)構(gòu)一些重要的數(shù)據(jù)結(jié)構(gòu)lfile_operations重要的成員重要的成員驅(qū)動內(nèi)核模塊是不需要實現(xiàn)每個函數(shù)的。相對應(yīng)的驅(qū)動內(nèi)核模塊是不需要實現(xiàn)每個函數(shù)的。相對應(yīng)的file_operations的項就為的項就為
16、NULL。Gcc的語法擴展,使得可以定義該結(jié)構(gòu)體:的語法擴展,使得可以定義該結(jié)構(gòu)體:struct file_operations fops = read: device_read, write: device_write, open: device_open, release: device_release ; 這種語法清晰,沒有顯示聲明的結(jié)構(gòu)體成員都被這種語法清晰,沒有顯示聲明的結(jié)構(gòu)體成員都被gcc初始化為初始化為NULL。 一些重要的數(shù)據(jù)結(jié)構(gòu)一些重要的數(shù)據(jù)結(jié)構(gòu)lfile_operations重要的成員重要的成員標準標準C的標記化結(jié)構(gòu)體的初始化方法:的標記化結(jié)構(gòu)體的初始化方法:struct
17、file_operations fops = .read = device_read,.write = device_write, .open = device_open, .release = device_release; 推薦使用該方法,提高移植性,方法允許對結(jié)構(gòu)體成員進行重推薦使用該方法,提高移植性,方法允許對結(jié)構(gòu)體成員進行重新排列。新排列。沒有顯示聲明的結(jié)構(gòu)體成員同樣都被沒有顯示聲明的結(jié)構(gòu)體成員同樣都被gcc初始化為初始化為NULL。指向結(jié)構(gòu)體指向結(jié)構(gòu)體file_operations的指針通常命名為的指針通常命名為fops。 一些重要的數(shù)據(jù)結(jié)構(gòu)一些重要的數(shù)據(jù)結(jié)構(gòu)l文件對象文件對象fi
18、le結(jié)構(gòu)體結(jié)構(gòu)體l文件對象文件對象file代表著一個翻開的文件。進程通過文件描代表著一個翻開的文件。進程通過文件描述符述符fd與已翻開文件的與已翻開文件的file結(jié)構(gòu)相聯(lián)系。進程通過它對結(jié)構(gòu)相聯(lián)系。進程通過它對文件的線性邏輯空間進行操作。例如:文件的線性邏輯空間進行操作。例如:file-f_op-read();lStruct file 在在中定義。中定義。l指向結(jié)構(gòu)體指向結(jié)構(gòu)體struct file的指針通常命名為的指針通常命名為filp,或者,或者file。建議使用文件指針建議使用文件指針filp。一些重要的數(shù)據(jù)結(jié)構(gòu)一些重要的數(shù)據(jù)結(jié)構(gòu)l文件對象文件對象file結(jié)構(gòu)體的成員結(jié)構(gòu)體的成員lStr
19、uct file_operations *f_op;l與文件相關(guān)的操作結(jié)構(gòu)體指針。與文件相關(guān)與文件相關(guān)的操作結(jié)構(gòu)體指針。與文件相關(guān)的操作是在翻開文件的時候確定下來的,也就的操作是在翻開文件的時候確定下來的,也就是確定該指針的值??稍谛枰臅r候,改變指是確定該指針的值??稍谛枰臅r候,改變指針所指向的文件操作結(jié)構(gòu)體。用針所指向的文件操作結(jié)構(gòu)體。用C語言實現(xiàn)面語言實現(xiàn)面向?qū)ο缶幊痰姆椒ㄖ剌d。向?qū)ο缶幊痰姆椒ㄖ剌d。l其他成員可先忽略,后面具體實例分析。因為其他成員可先忽略,后面具體實例分析。因為設(shè)備驅(qū)動模塊并不自己直接填充結(jié)構(gòu)體設(shè)備驅(qū)動模塊并不自己直接填充結(jié)構(gòu)體 file,只是使用只是使用file中
20、的數(shù)據(jù)。中的數(shù)據(jù)。 一些重要的數(shù)據(jù)結(jié)構(gòu)一些重要的數(shù)據(jù)結(jié)構(gòu)l索引節(jié)點索引節(jié)點inode結(jié)構(gòu)結(jié)構(gòu)l文件翻開,在內(nèi)存建立副本后,由唯一的索引文件翻開,在內(nèi)存建立副本后,由唯一的索引節(jié)點節(jié)點inode描述。描述。l與與file結(jié)構(gòu)不同。結(jié)構(gòu)不同。lfile結(jié)構(gòu)是進程使用的結(jié)構(gòu),進程每翻開一個文結(jié)構(gòu)是進程使用的結(jié)構(gòu),進程每翻開一個文件,就建立一個件,就建立一個file結(jié)構(gòu)。不同的進程翻開同一結(jié)構(gòu)。不同的進程翻開同一個文件,建立不同的個文件,建立不同的file結(jié)構(gòu)。結(jié)構(gòu)。lInode結(jié)構(gòu)是內(nèi)核使用的結(jié)構(gòu),文件在內(nèi)存建結(jié)構(gòu)是內(nèi)核使用的結(jié)構(gòu),文件在內(nèi)存建立副本,就建立一個立副本,就建立一個inode結(jié)構(gòu)來描述
21、。一個結(jié)構(gòu)來描述。一個文件在內(nèi)存里面只有一個文件在內(nèi)存里面只有一個inode結(jié)構(gòu)對應(yīng)。結(jié)構(gòu)對應(yīng)。一些重要的數(shù)據(jù)結(jié)構(gòu)一些重要的數(shù)據(jù)結(jié)構(gòu)l索引節(jié)點索引節(jié)點inode結(jié)構(gòu)結(jié)構(gòu)Inode結(jié)構(gòu)包含大量描述文件信息的成員變量。結(jié)構(gòu)包含大量描述文件信息的成員變量。但是對于描述設(shè)備文件的但是對于描述設(shè)備文件的inode,跟設(shè)備驅(qū)動有關(guān),跟設(shè)備驅(qū)動有關(guān)的成員只有兩個。的成員只有兩個。Dev_t i_rdev; 包含真正的設(shè)備編號。包含真正的設(shè)備編號。Struct cdev *i_cdev; 指向指向cdev結(jié)構(gòu)體的指針。結(jié)構(gòu)體的指針。cdev是表示字符設(shè)備的內(nèi)核數(shù)據(jù)結(jié)構(gòu)。是表示字符設(shè)備的內(nèi)核數(shù)據(jù)結(jié)構(gòu)。從從ino
22、de中獲得主設(shè)備號和次設(shè)備號的宏:中獲得主設(shè)備號和次設(shè)備號的宏:Unsigned int iminor(struct inode *inode);Unsigned int imajor(struct inode *inode);驅(qū)動程序中的內(nèi)存分配驅(qū)動程序中的內(nèi)存分配l在在Linux內(nèi)核模式下,不能使用用戶態(tài)的內(nèi)核模式下,不能使用用戶態(tài)的malloc()和和free()函數(shù)申請和釋放內(nèi)存。函數(shù)申請和釋放內(nèi)存。l內(nèi)核編程最常用的內(nèi)存申請和釋放函數(shù)為內(nèi)核編程最常用的內(nèi)存申請和釋放函數(shù)為kmalloc()和和kfree(),其原型為:,其原型為:linclude/linux/kernel.hlvoi
23、d *kmalloc(unsigned int len, int priority);lvoid kfree(void *_ptr);lpriority參數(shù)參數(shù):l通常設(shè)置為通常設(shè)置為GFP_KERNEL,可能會引起睡眠,可能會引起睡眠.l如果在中斷效勞程序里申請內(nèi)存那么要用如果在中斷效勞程序里申請內(nèi)存那么要用GFP_ATOMIC參數(shù),在中斷中是不允許睡眠的。參數(shù),在中斷中是不允許睡眠的。初始化和卸載函數(shù)初始化和卸載函數(shù)l驅(qū)動程序是內(nèi)核的一局部,因此我們需要給其添驅(qū)動程序是內(nèi)核的一局部,因此我們需要給其添加模塊初始化函數(shù),該函數(shù)用來完成對所控設(shè)備加模塊初始化函數(shù),該函數(shù)用來完成對所控設(shè)備的初始
24、化工作,并調(diào)用的初始化工作,并調(diào)用register_chrdev() 函數(shù)函數(shù)注冊字符設(shè)備注冊字符設(shè)備.lint register_chrdev(unsigned int major, const char *name, struct file_operations *fops);lmajor 是給定的主設(shè)備號。為是給定的主設(shè)備號。為0代表什么?代表什么?lname 是驅(qū)動的名字是驅(qū)動的名字(將出現(xiàn)在將出現(xiàn)在 /proc/devices), lfops 是設(shè)備驅(qū)動的是設(shè)備驅(qū)動的file_operations 結(jié)構(gòu)。結(jié)構(gòu)。lregister_chrdev 將給設(shè)備分配將給設(shè)備分配 0 - 255
25、 的次設(shè)的次設(shè)備號備號, 并且為每一個建立一個缺省的并且為每一個建立一個缺省的 cdev 結(jié)構(gòu)。結(jié)構(gòu)。l與模塊初始化函數(shù)對應(yīng)的就是模塊卸載函數(shù),需與模塊初始化函數(shù)對應(yīng)的就是模塊卸載函數(shù),需要調(diào)用要調(diào)用register_chrdev()的的反函數(shù)反函數(shù)設(shè)備操作函數(shù)集的定義設(shè)備操作函數(shù)集的定義lfile_operations結(jié)構(gòu)體,驅(qū)動程序只是利用其中結(jié)構(gòu)體,驅(qū)動程序只是利用其中的一局部。的一局部。l對于字符設(shè)備來說,要提供的主要入口有:對于字符設(shè)備來說,要提供的主要入口有:open ()、release ()、read ()、write ()、ioctl ()等。等。設(shè)備操作函數(shù)集的定義設(shè)備操作
26、函數(shù)集的定義lopen()函數(shù)函數(shù)對設(shè)備特殊文件進行對設(shè)備特殊文件進行open()系統(tǒng)調(diào)用時,將調(diào)用驅(qū)動系統(tǒng)調(diào)用時,將調(diào)用驅(qū)動程序的程序的open () 函數(shù):函數(shù):int (int (* *open)(struct inode open)(struct inode * * ,struct file ,struct file * *););參數(shù)參數(shù)inode為設(shè)備特殊文件的為設(shè)備特殊文件的inode (索引結(jié)點索引結(jié)點) 結(jié)結(jié)構(gòu)的指針,構(gòu)的指針,參數(shù)參數(shù)file是指向這一設(shè)備的文件結(jié)構(gòu)的指針。是指向這一設(shè)備的文件結(jié)構(gòu)的指針。open()的主要任務(wù)是確定硬件處在就緒狀態(tài)、驗證次的主要任務(wù)是確定硬
27、件處在就緒狀態(tài)、驗證次設(shè)備號的合法性設(shè)備號的合法性(次設(shè)備號可以用次設(shè)備號可以用MINOR(inode- i - rdev) 取得取得)、控制使用設(shè)備的進程數(shù)、根據(jù)執(zhí)行情況、控制使用設(shè)備的進程數(shù)、根據(jù)執(zhí)行情況返回狀態(tài)碼返回狀態(tài)碼(0表示成功,負數(shù)表示存在錯誤表示成功,負數(shù)表示存在錯誤) 等;等;設(shè)備操作函數(shù)集的定義設(shè)備操作函數(shù)集的定義lrelease()函數(shù)函數(shù)l當最后一個翻開設(shè)備的用戶進程執(zhí)行當最后一個翻開設(shè)備的用戶進程執(zhí)行close ()系系統(tǒng)調(diào)用時,內(nèi)核將調(diào)用驅(qū)動程序的統(tǒng)調(diào)用時,內(nèi)核將調(diào)用驅(qū)動程序的release () 函函數(shù):數(shù):lvoid (*release) (struct ino
28、de * ,struct file *) ;lrelease 函數(shù)的主要任務(wù)是清理未結(jié)束的輸入函數(shù)的主要任務(wù)是清理未結(jié)束的輸入/輸輸出操作、釋放資源、用戶自定義排他標志的復位出操作、釋放資源、用戶自定義排他標志的復位等等.設(shè)備操作函數(shù)集的定義設(shè)備操作函數(shù)集的定義lread()函數(shù)函數(shù)lRead的任務(wù)的任務(wù), 就是從設(shè)備拷貝數(shù)據(jù)到用戶空間。就是從設(shè)備拷貝數(shù)據(jù)到用戶空間。l當對設(shè)備特殊文件進行當對設(shè)備特殊文件進行read() 系統(tǒng)調(diào)用時,將調(diào)系統(tǒng)調(diào)用時,將調(diào)用驅(qū)動程序用驅(qū)動程序read() 函數(shù):函數(shù):lssize_t read(struct file *filp, char _user *buf
29、f, size_t count, loff_t *offp);lfilp 是文件對象指針是文件對象指針, lcount 是請求的傳輸數(shù)據(jù)大小是請求的傳輸數(shù)據(jù)大小. lbuff 參數(shù)對參數(shù)對write來說是指向持有被寫入數(shù)據(jù)的來說是指向持有被寫入數(shù)據(jù)的緩存緩存, 對對read那么是放入新數(shù)據(jù)的空緩存那么是放入新數(shù)據(jù)的空緩存. loffp 是指向一個是指向一個“l(fā)ong offset type的指針的指針, 它它指出用戶正在存取的文件位置指出用戶正在存取的文件位置. l返回值是返回值是“signed size type類型類型;設(shè)備操作函數(shù)集的定義設(shè)備操作函數(shù)集的定義lwrite( ) 函數(shù)函數(shù)l
30、Write的任務(wù),那么從用戶空間拷貝數(shù)據(jù)到設(shè)備。的任務(wù),那么從用戶空間拷貝數(shù)據(jù)到設(shè)備。l當設(shè)備特殊文件進行當設(shè)備特殊文件進行write () 系統(tǒng)調(diào)用時,將調(diào)系統(tǒng)調(diào)用時,將調(diào)用驅(qū)動程序的用驅(qū)動程序的write () 函數(shù):函數(shù):lssize_t write(struct file *filp, const char _user *buff, size_t count, loff_t *offp);lfilp 是文件對象指針是文件對象指針, lcount 是請求的傳輸數(shù)據(jù)大小是請求的傳輸數(shù)據(jù)大小. lbuff 參數(shù)對參數(shù)對write來說是指向持有被寫入數(shù)據(jù)的來說是指向持有被寫入數(shù)據(jù)的緩存緩存,
31、對對read那么是放入新數(shù)據(jù)的空緩存那么是放入新數(shù)據(jù)的空緩存. loffp 是指向一個是指向一個“l(fā)ong offset type的指針的指針, 它它指出用戶正在存取的文件位置指出用戶正在存取的文件位置. l返回值是返回值是“signed size type類型類型;設(shè)備操作函數(shù)集的定義設(shè)備操作函數(shù)集的定義lread 和和 write 方法的方法的 buff 參數(shù)是用戶空間指針,參數(shù)是用戶空間指針,不能被內(nèi)核代碼直接解引用。不能被內(nèi)核代碼直接解引用。_user字符串只是字符串只是形式上的說明,說明是用戶空間地址。形式上的說明,說明是用戶空間地址。l驅(qū)動必須能夠存取用戶空間緩存以完成它的工作。驅(qū)
32、動必須能夠存取用戶空間緩存以完成它的工作。內(nèi)核如何解決這個問題?內(nèi)核如何解決這個問題?l為平安起見,內(nèi)核提供專用的函數(shù)來完成對用戶為平安起見,內(nèi)核提供專用的函數(shù)來完成對用戶空間的存取。這些專用函數(shù)在空間的存取。這些專用函數(shù)在中聲明。中聲明。lunsigned long copy_to_user(void _user *to,const void *from,unsigned long count);lunsigned long copy_from_user(void *to,const void _user *from,unsigned long count);l大多數(shù)讀寫函數(shù)都會調(diào)用這兩個函
33、數(shù),用于跟應(yīng)大多數(shù)讀寫函數(shù)都會調(diào)用這兩個函數(shù),用于跟應(yīng)用程序空間交流信息。用程序空間交流信息。Read和和Write方法方法l典型的典型的Read函數(shù)對參數(shù)的使用。函數(shù)對參數(shù)的使用。S3C2410 的I/O 介紹lS3C2410 有117 個復用功能輸入輸出端口引腳,這些引腳是:lPortA(GPA):32 個輸入/輸出端口lPortB(GPB):11 個輸入/輸出端口lPortC(GPC):16 個輸入/輸出端口lPortD(GPD):16 個輸入/輸出端口lPortE(GPE):16 個輸入/輸出端口lPortF(GPF):8 個輸入/輸出端口lPortG(GPG):16 個輸入/輸出端口
34、lPortH(GPH):11 個輸入/輸出端口S3C2410 的I/O 介紹l端口控制說明l端口配置存放器GPACONGPHCONl大局部的引腳是復用的,所以必須對于每個引腳要求定義一個功能,端口配置存放器定義了每個引腳的功能。l端口數(shù)據(jù)存放器GPADATGPHDATl如果端口配置成輸出端口,數(shù)據(jù)能夠被寫到端口數(shù)據(jù)存放器的對應(yīng)位,然后通過管腳輸出。如果端口配置成輸入端口,能從端口數(shù)據(jù)存放器對應(yīng)的位中讀出管腳上的電平l端口上拉存放器GPBUPGPHUPl端口上拉存放器控制著每個端口組的上拉存放器的使能或禁止,當對應(yīng)位為0,這個引腳的上拉存放器是允許的,當為1 時,上拉存放器是禁止的。MIZI提供
35、的提供的S3C2410.Hl使用一個使用一個32位的數(shù)來表示端口的使用情況。位的數(shù)來表示端口的使用情況。l模式模式 |上拉上拉 |端口端口 | 端口引腳端口引腳lMODE | PULLUP | PORT | OFSl不需要自己手動組合,通過宏定義以及不需要自己手動組合,通過宏定義以及SHIFT和和MASK組合。見程序組合。見程序MIZI提供的提供的S3C2410.Hl端口的表示端口的表示l#define PORTA_OFS0l#define PORTB_OFS1l#define PORTC_OFS2l#define PORTD_OFS3l#define PORTE_OFS4l#define P
36、ORTF_OFS5l#define PORTG_OFS6l#define PORTH_OFS7MIZI提供的提供的S3C2410.Hl端口引腳的表示端口引腳的表示l#define GPIO_A0MAKE_GPIO_NUM(PORTA_OFS, 0)l#define GPIO_A1MAKE_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_SHIF
37、TT) | (o GPIO_OFS_SHIFT)MIZI提供的提供的S3C2410.Hlset_gpio_ctrl(x) l功能:配置端口引腳的功能,設(shè)置功能:配置端口引腳的功能,設(shè)置IO口控制存放口控制存放器和上拉存放器器和上拉存放器l用法:用法:set_gpio_ctrl(模式模式|上拉上拉?|IO腳腳) l模式模式|是否上拉是否上拉|IO腳,在腳,在S3C2410.h中都有其定義中都有其定義好的名字。好的名字。l lset_gpio_ctrl(GPIO_E11 | GPIO_PULLUP_DIS |GPIO_MODE_OUT);MIZI提供的提供的S3C2410.Hlwrite_gpio
38、_bit(x, v) l功能:把端口功能:把端口 對應(yīng)的端口數(shù)據(jù)存放器對應(yīng)的端口數(shù)據(jù)存放器x位設(shè)置為位設(shè)置為vlwrite_gpio_bit(GPIO_E11, 0); lread_gpio_bit(x) l功能:把端口數(shù)據(jù)存放器功能:把端口數(shù)據(jù)存放器x位的狀態(tài)位的狀態(tài) 讀入,函數(shù)讀入,函數(shù)返回值既是其狀態(tài)返回值既是其狀態(tài)lread_gpio_bit(GPIO_G11); MIZI提供的提供的S3C2410.Hlwrite_gpio_reg(x, v) l功能:把端口數(shù)據(jù)存放器功能:把端口數(shù)據(jù)存放器x 設(shè)置為設(shè)置為v lread_gpio_reg(x) l功能:讀取端口數(shù)據(jù)存放器功能:讀取端口
39、數(shù)據(jù)存放器x,函數(shù)返回值既是,函數(shù)返回值既是其數(shù)據(jù)其數(shù)據(jù) l按驅(qū)動的框架寫好驅(qū)動,實現(xiàn)初始化、卸載函數(shù),按驅(qū)動的框架寫好驅(qū)動,實現(xiàn)初始化、卸載函數(shù),以及以及file_opertation操作集。操作集。l對于對于led使用的使用的gpio函數(shù),內(nèi)核沒有輸出作為公函數(shù),內(nèi)核沒有輸出作為公開符號,所以需要手動修改內(nèi)核代碼,代碼放在開符號,所以需要手動修改內(nèi)核代碼,代碼放在arch/arm/march-s3c2410/gpio.c,輸出符號:,輸出符號:EXPORT_SYMBOL(s3c2410_gpio_setpin);EXPORT_SYMBOL(s3c2410_gpio_cfgpin);EXPO
40、RT_SYMBOL(s3c2410_gpio_pullup);l編寫驅(qū)動模塊的編寫驅(qū)動模塊的Makefile。l交叉編譯驅(qū)動模塊交叉編譯驅(qū)動模塊lNFS加載驅(qū)動模塊,進行測試。加載驅(qū)動模塊,進行測試。嵌入式鍵盤驅(qū)動廣州嵌入式軟件公共技術(shù)支持中心廣州嵌入式軟件公共技術(shù)支持中心梁老師2007年7月注冊中斷效勞例程注冊中斷效勞例程 l中斷線是一個珍貴且常常有限的資源中斷線是一個珍貴且常常有限的資源, , 特別當它特別當它們只有們只有1515個時。內(nèi)核維護一個中斷線的注冊表。個時。內(nèi)核維護一個中斷線的注冊表。l要使用中斷線,就要進行中斷線的申請,也就是要使用中斷線,就要進行中斷線的申請,也就是IRQ(
41、Interrupt ReQuirement)IRQ(Interrupt ReQuirement),因此我們也常把,因此我們也常把申請一條中斷線稱為申請一個申請一條中斷線稱為申請一個IRQIRQ或者是申請一或者是申請一個中斷號。個中斷號。lIRQIRQ線是從線是從0 0開始順序編號的;第一條開始順序編號的;第一條IRQIRQ線通常線通常表示成表示成IRQ0IRQ0。IRQnIRQn的缺省向量是的缺省向量是n+32n+32。注冊中斷效勞例程注冊中斷效勞例程 l并不是每個設(shè)備都可以向中斷線上發(fā)中斷信號的,并不是每個設(shè)備都可以向中斷線上發(fā)中斷信號的,只有對某一條確定的中斷線擁有了控制權(quán),才可只有對某一
42、條確定的中斷線擁有了控制權(quán),才可以向這條中斷線上發(fā)送信號。以向這條中斷線上發(fā)送信號。l計算機的外部設(shè)備越來越多,所以計算機的外部設(shè)備越來越多,所以1515條中斷線已條中斷線已經(jīng)不夠用了,中斷線是非常珍貴的資源。經(jīng)不夠用了,中斷線是非常珍貴的資源。l只有當設(shè)備需要中斷的時候才申請占用一個只有當設(shè)備需要中斷的時候才申請占用一個IRQIRQ,或者是在申請或者是在申請IRQIRQ時采用共享中斷的方式,這樣時采用共享中斷的方式,這樣可以讓更多的設(shè)備使用中斷。可以讓更多的設(shè)備使用中斷。注冊中斷效勞例程注冊中斷效勞例程 l在在 實現(xiàn)中斷注冊接口實現(xiàn)中斷注冊接口:int request_irq(unsigne
43、d 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, void *dev_id);lrequest_irq 的返回值是的返回值是 0 指示申請成功,為負指示申請成功,為負值時表示錯誤碼。函數(shù)返回值時表示錯誤碼。函數(shù)返回 -EBUSY 表示已經(jīng)有表示已經(jīng)有另一個驅(qū)動占用了所要申請的中斷線。另一個驅(qū)動占用了所要申請的中斷線。注冊中斷效勞例程注冊中斷效
44、勞例程 lrequest_irq的參數(shù)說明:的參數(shù)說明:unsigned int irq, 要申請的中斷號。要申請的中斷號。對某些設(shè)備,如傳統(tǒng)對某些設(shè)備,如傳統(tǒng)PC設(shè)備上的系統(tǒng)時鐘或鍵盤,設(shè)備上的系統(tǒng)時鐘或鍵盤,這個值通常是預(yù)先確定的。這個值通常是預(yù)先確定的。而對于大多數(shù)其它設(shè)備來說,這個值要么可以通過而對于大多數(shù)其它設(shè)備來說,這個值要么可以通過探測獲取,要么可以動態(tài)確定。探測獲取,要么可以動態(tài)確定。irqreturn_t (*handler)(int, void *, struct pt_regs *),要安裝的中斷處理函數(shù)指針。后面介紹。注冊中斷效勞例程注冊中斷效勞例程 lrequest_
45、irq的參數(shù)說明:的參數(shù)說明:lunsigned long flags,l與中斷管理相關(guān)的位掩碼選項。與中斷管理相關(guān)的位掩碼選項。lconst char *dev_name, l用在用在 /proc/interrupts 中顯示中斷的擁有者。中顯示中斷的擁有者。lvoid *dev_idl這個指針用于共享的中斷線。做為驅(qū)動程序的這個指針用于共享的中斷線。做為驅(qū)動程序的私有數(shù)據(jù)區(qū)可用來識別那個設(shè)備產(chǎn)生的中斷。私有數(shù)據(jù)區(qū)可用來識別那個設(shè)備產(chǎn)生的中斷。不使用共享中斷線方式時,可設(shè)置為不使用共享中斷線方式時,可設(shè)置為NULL。注冊中斷效勞例程注冊中斷效勞例程 lflags參數(shù)的詳細說明:lFlags的
46、每個位有不同含義lSA_INTERRUPTl當該位被設(shè)置時, 表示這是一個“快速中斷??焖僦袛嗵幚砝踢\行時,屏蔽中斷。lSA_SHIRQl這個位表示中斷可以在設(shè)備間共享。proc 文件系統(tǒng)中的中斷信息文件系統(tǒng)中的中斷信息l/proc/interrupts反映系統(tǒng)的中斷信息反映系統(tǒng)的中斷信息第一列是 IRQ 號給出每個中斷線發(fā)生中斷的次數(shù)。給出每個中斷線發(fā)生中斷的次數(shù)。給出處理中斷的可編程中斷控制器。給出處理中斷的可編程中斷控制器。給出在該中斷號上注冊中斷處理例程的設(shè)備名稱。給出在該中斷號上注冊中斷處理例程的設(shè)備名稱。實現(xiàn)中斷處理例程實現(xiàn)中斷處理例程l首先中斷處理例程也是普通的首先中斷處理例程
47、也是普通的C程序。程序。l特別之處:特別之處:在中斷時間內(nèi)運行,不能向用戶空間發(fā)送或者接收數(shù)在中斷時間內(nèi)運行,不能向用戶空間發(fā)送或者接收數(shù)據(jù)。據(jù)。不能做任何導致休眠的操作。不能做任何導致休眠的操作。不能調(diào)用不能調(diào)用schedule函數(shù)。函數(shù)。無論快速還是慢速中斷處理例程,都應(yīng)該設(shè)計成執(zhí)行無論快速還是慢速中斷處理例程,都應(yīng)該設(shè)計成執(zhí)行時間盡可能短。時間盡可能短。實現(xiàn)中斷處理例程實現(xiàn)中斷處理例程l中斷處理函數(shù)的參數(shù)和返回值中斷處理函數(shù)的參數(shù)和返回值lirqreturn_t (*handler)(int, void *, struct pt_regs *)lirqreturn_t short_int
48、errupt(int irq, void *dev_id, struct pt_regs *regs)lIrq 中斷號中斷號lDev_id 驅(qū)動程序可用的數(shù)據(jù)區(qū),通??蓚鬟f指驅(qū)動程序可用的數(shù)據(jù)區(qū),通??蓚鬟f指向描述設(shè)備的數(shù)據(jù)結(jié)構(gòu)指針。向描述設(shè)備的數(shù)據(jù)結(jié)構(gòu)指針。lstruct pt_regs *regs,保存了處理器進入中斷,保存了處理器進入中斷代碼之前的代碼之前的cpu存放器的值。一般驅(qū)動可不要。存放器的值。一般驅(qū)動可不要。矩陣式鍵盤原理矩陣式鍵盤原理l矩陣式鍵盤一般適用于按鍵數(shù)量較多的場合,它由行線矩陣式鍵盤一般適用于按鍵數(shù)量較多的場合,它由行線和列線組成,按鍵位于行、列的交叉點上。和列線組
49、成,按鍵位于行、列的交叉點上。l如下圖,一個如下圖,一個44的行、列結(jié)構(gòu)可以構(gòu)成一個有的行、列結(jié)構(gòu)可以構(gòu)成一個有16個按個按鍵的鍵盤。鍵的鍵盤。矩陣式鍵盤原理矩陣式鍵盤原理l按鍵設(shè)置在行、列交叉點上,行、列分別連接到按鍵設(shè)置在行、列交叉點上,行、列分別連接到按鍵開關(guān)的兩端。行線通過上拉電阻接到十按鍵開關(guān)的兩端。行線通過上拉電阻接到十5 V上。上。l平時無按鍵動作時,行線處于高電平狀態(tài)平時無按鍵動作時,行線處于高電平狀態(tài);而當有而當有健按下時,行線電平狀態(tài)將由通過此按鍵的列線健按下時,行線電平狀態(tài)將由通過此按鍵的列線電平?jīng)Q定電平?jīng)Q定:列線電平如果為低,行線電平為低列線電平如果為低,行線電平為低;列列線電平如果為高,那么行線電平亦為高。這一點線電平如果為高,那么行線電平亦為高。這一點是識別矩陣式鍵盤是否被按下的關(guān)鍵所在。是識別矩陣式鍵盤是否被按下的關(guān)鍵所在。矩陣式鍵盤原理矩陣式鍵盤原理l矩陣鍵盤按鍵的識別方法分兩步進行矩陣鍵盤按鍵的識別方法分兩步進行:l識別鍵盤哪一行的鍵被按下。讓所有列線均為識別鍵盤哪一行的鍵被按下。讓所有列線均為低電平,檢查各行線電平是否為低。如果有行線低電平,檢查各行線電平是否為低。如果有行線為低,那么說明該行有鍵被按下,否那么說明無為低,那么說明該行有鍵被按下,否那么說明無鍵被按下
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 工程項目代建合同
- 監(jiān)理竣工評估報告范本
- 2025江西吉安市青原區(qū)睿才人力資源有限公司招聘6人筆試參考題庫附帶答案詳解
- 合同范本之茶葉代加工合同模板
- 2025年湖南益陽市交通規(guī)劃勘測設(shè)計院有限公司招聘6人筆試參考題庫附帶答案詳解
- 2025年上半年宣城市廣德縣事業(yè)單位招考(41人)易考易錯模擬試題(共500題)試卷后附參考答案
- 2025年上半年安徽花山區(qū)事業(yè)單位招聘人選易考易錯模擬試題(共500題)試卷后附參考答案
- 2025年上半年安徽省馬鞍山市含山縣林頭鎮(zhèn)人民政府招聘派遣制人員10人易考易錯模擬試題(共500題)試卷后附參考答案
- 2025年上半年安徽省貴池區(qū)事業(yè)單位招聘擬聘(第二批)易考易錯模擬試題(共500題)試卷后附參考答案
- 2025年上半年安徽省巢湖市槐林政府民政辦招聘易考易錯模擬試題(共500題)試卷后附參考答案
- 2025年湖南大眾傳媒職業(yè)技術(shù)學院單招職業(yè)技能測試題庫學生專用
- 2025年南京旅游職業(yè)學院高職單招職業(yè)技能測試近5年??及鎱⒖碱}庫含答案解析
- 【2025年衛(wèi)生健康宣傳日】世界防治結(jié)核病日
- 和田玉知識培訓課件下載
- 新版《醫(yī)療器械經(jīng)營質(zhì)量管理規(guī)范》(2024)培訓試題及答案
- 2025年高縣縣屬國企業(yè)公開招聘工作人員高頻重點提升(共500題)附帶答案詳解
- 2025年人教版數(shù)學五年級下冊教學計劃(含進度表)
- 第7課 課題二《清潔工具與生活·創(chuàng)意清潔工具設(shè)計》(說課稿)-2023-2024學年四年級下冊綜合實踐活動浙教版
- DB11-T 1191.3-2024 實驗室危險化學品安全管理要求 第3部分:科研單位
- 醫(yī)療行業(yè)學生職業(yè)發(fā)展的路徑規(guī)劃
- 規(guī)范填寫臨時用電作業(yè)票
評論
0/150
提交評論