android深度探索 HAL及驱动开发 第八章
第八章 讀書筆記
本章主要講蜂鳴器的驅(qū)動(dòng),蜂鳴器是S3cC6410開發(fā)板上帶的一個(gè)硬件設(shè)備,本節(jié)將介紹蜂鳴器的實(shí)現(xiàn)原理,并實(shí)現(xiàn)一個(gè)完整的蜂鳴器驅(qū)動(dòng)。本節(jié)講介紹把linux驅(qū)動(dòng)分成多個(gè)文件的方式。這些文件中的數(shù)據(jù)結(jié)構(gòu)、函數(shù)的代碼也可以被多個(gè)不同的驅(qū)動(dòng)使用,所以這也是代碼重用 的重要方法。Linux代碼的重用?重用=靜態(tài)重用(將要重用的代碼放到其他的文件的頭文件中聲明)+動(dòng)態(tài)重用(使用另外一個(gè)Linux驅(qū)動(dòng)中的資源,例如函數(shù)、變量、宏等)
1、編譯是由多個(gè)文件組成的Linux驅(qū)動(dòng)(靜態(tài)重用)
對(duì)于復(fù)雜的Linux驅(qū)動(dòng),需要使用多個(gè)源代碼文件存放不同的功能代碼,這樣做有利于代碼分類和管理,那么就不得不編譯多個(gè)源代碼文件,最終生成.ko文件或編譯進(jìn)Linux內(nèi)核
下面,就介紹將3個(gè).c文件分別編譯為3個(gè).o文件,并將這3個(gè).o文件鏈接(link)成一個(gè).ko文件——靜態(tài)重用
假設(shè)C語言源代碼文件有main.c、fun.c、product.c、product.h,其中main.c是Linux驅(qū)動(dòng)的主程序,在fun.c和product.c、product.h中定義和實(shí)現(xiàn)了在main.c中使用的函數(shù),在main.c中通過extern關(guān)鍵字使用fun.c中的函數(shù),通過包含product.h文件使用product.c文件中的函數(shù)
最關(guān)鍵一步就是編寫Makefile文件
#Makefile
obj-m := multi_file_driver(文件所在目錄).o
multi_file_driver-y := main.o fun.o product.o
總之,c或c++ 語言中編譯多個(gè)源代碼文件時(shí),如果a.c使用了b.c文件中的函數(shù),需要在a.c文件中使用extern預(yù)先定義b.c中的函數(shù),extern的作用是告訴編譯器該函數(shù)的函數(shù)名、參數(shù)個(gè)數(shù)、參數(shù)類型、返回值類型,等到將a.o和b.o鏈接成可執(zhí)行文件或程序庫時(shí),編譯器再到b.o中尋找函數(shù)的具體實(shí)現(xiàn)。除此之外,還可以使用b.h文件定義b.c中的函數(shù),然后在a.c中包含b.h文件。
2、Linux驅(qū)動(dòng)模塊的依賴(動(dòng)態(tài)重用)
在一個(gè)驅(qū)動(dòng)模塊里使用另一個(gè)驅(qū)動(dòng)模塊里的被導(dǎo)出的符號(hào)(常量、變量、函數(shù)等)
接下來學(xué)習(xí)了強(qiáng)行卸載linux驅(qū)動(dòng),只能卸載由于卸載異常情況而導(dǎo)致的linux驅(qū)動(dòng)模塊無法卸載的情況。情況1:初始化函數(shù)崩潰 2:卸載函數(shù)被阻塞
?
蜂鳴器驅(qū)動(dòng)是一個(gè)重點(diǎn),通過相應(yīng)的寄存器來控制蜂鳴器的打開和關(guān)閉,并且在實(shí)驗(yàn)蜂鳴器驅(qū)動(dòng)時(shí),將打開和關(guān)閉蜂蜜器的函數(shù)放到另外的C源代碼文件中。PWM驅(qū)動(dòng)由三個(gè)文件組成:PWM.C、PWM—fun.h、pwm-fun.c、其中pwm.c是驅(qū)動(dòng)主程序。
本章主要講了Linux代碼的重用與強(qiáng)行卸載Linux驅(qū)動(dòng)。
強(qiáng)行卸載Linux驅(qū)動(dòng)
情況1:初始化函數(shù)崩潰
由于Linux驅(qū)動(dòng)模塊的初始化函數(shù)進(jìn)行了某些操作而崩潰,從而導(dǎo)致初始化函數(shù)無法正常返回,這種情況變現(xiàn)是當(dāng)前Linux驅(qū)動(dòng)模塊沒用被任何其他的Linux驅(qū)動(dòng)模塊使用,但卻顯示已經(jīng)被應(yīng)用了一次
這種情況關(guān)鍵是引用計(jì)數(shù)器的值和引用者不一致。只需要將當(dāng)前的Linux驅(qū)動(dòng)模塊的引用計(jì)數(shù)器清零即可,修改計(jì)數(shù)器可以使用下面兩個(gè)函數(shù)
//是module指向的Linux驅(qū)動(dòng)模塊的引用計(jì)數(shù)器加1,成功返回1,失敗返回0
static inline int try_module_get(struct module *module);
//是module指向的Linux驅(qū)動(dòng)模塊的引用計(jì)數(shù)器減1
extern void module_put(struct module *module);
情況2:卸載函數(shù)被阻塞
在使用rmmod命令卸載Linux驅(qū)動(dòng)時(shí),系統(tǒng)會(huì)調(diào)用卸載函數(shù),只有卸載函數(shù)成功返回時(shí),Linux驅(qū)動(dòng)才會(huì)被卸載,如果卸載函數(shù)被阻塞,rmmod命令也會(huì)被阻塞,也就是說永遠(yuǎn)不會(huì)執(zhí)行到卸載Linux驅(qū)動(dòng)模塊的代碼,這種情況的表現(xiàn)是一執(zhí)行rmmod命令就會(huì)停在那不動(dòng)了,永遠(yuǎn)也不會(huì)返回到系統(tǒng)的操作提示符
這種情況的問題根源就是卸載函數(shù),只要將原來的卸載函數(shù)替換成一個(gè)空的卸載函數(shù)即可
總之,兩者情況都要解決一個(gè)不可回避的問題,就是要獲取表示要卸載的Linux驅(qū)動(dòng)模塊的module結(jié)構(gòu)體指針。
轉(zhuǎn)載于:https://www.cnblogs.com/haihaizhazha/p/5626985.html
總結(jié)
以上是生活随笔為你收集整理的android深度探索 HAL及驱动开发 第八章的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蓝牙耳机性能测试软件,操作方便吗 蓝牙耳
- 下一篇: 机票预订系统活动图_软件工程(第五版)-