標籤:
看了本書第八章,我學習到了:
- 蜂鳴器是開發板內建的一個硬體裝置,控制蜂鳴器發聲是通過向寄存器寫入特定的值實現的。PWM驅動不同於LED 驅動,其由多個檔案組成,在編譯時間將這些檔案進行聯合編譯。
- 蜂鳴器也稱為PWM(脈衝寬度調製),基本原理是通過脈衝來控制蜂鳴器的開啟和停止。
PWM串連到了TOUT1連接埠,使用連接埠F的GPFCON寄存器進行控制。宏S3C64XX_GPFCON表示寄存器GPFCON的虛擬位址。僅用最高兩位(30、31位)控制PWM。最高兩位為
10時,開啟PWM;為00時停止PWM。用iowrite32函數為GPFCON設定不同的值。
- 實現蜂鳴器驅動:PWM驅動由pwm.c、pwm_fun.c、pwm_fun.h組成。
編譯PWM驅動的Makefile:obj-m :=pwm_driver.o pwm_driver-objs :=pwm.o pwm_file
將兩個.c檔案連結成pwm_driver.o,最後產生 .ko 檔案。執行build.sh指令檔安裝pwm
驅動,再測試pwm驅動,使其發出聲音。
- Linux驅動的代碼重用:Linux驅動分成多個檔案,這些檔案中的資料結構、函數代碼可以被多個驅動使用。
靜態重用:採用c語言方式,include檔案即可。動態重用:一個linux驅動使用另一個驅動中的函數、變數、宏等。
- 編譯是由多個檔案組成的linux驅動。c/c++語言編譯多個源碼檔案時,若1.c使用了2.c的函數,需要在1.c中用extern預先定義1.c的函數,extern只在編譯階段起作用,可省略;或使用2.h定義2.c的函數,然後在1.c中include”2.h”。若linux驅動僅有一個原始碼檔案,Makefile檔案中obj-m的值可以和源碼檔案同名。
- 代碼共用的方式:模組依賴(匯出符號),即在一個驅動模組裡使用另一個驅動模組裡的被匯出的符號(常量、變數、函數)export。
depmod命令用於分析linux模組之間的依賴性,需要指定所有相關的linux模組檔案名稱(絕對路徑),在modules.dep檔案中使用“:”確定了各模組的依賴關係,之後用modprobe命令裝載linux模組。
- 強行卸載驅動:
① 初始化函數崩潰時:引用計數器的值和引用者不一致,只需將當前的linux驅動模組的引用計數器清零。使用兩個函數:try_module_get(struct module *module)、module_put(struct module *module)
② 卸載函數被阻塞時:問題根源是卸載函數,只需將原來的卸載函數替換成一個空的卸載函數即可。
以上兩種情況都需要擷取module結構體指標,該結構體表示了linux驅動的相關資訊。
執行 cat /proc/kallsysms | grep _this_module | grep bad_driver1擷取該驅動結構體的首地址。
由於module結構體的地址在核心空間,只能編寫linux驅動(force_kill_driver)來卸載另一個驅動。
為了實現工作自動化,編寫一個build.sh指令檔來自動尋找、截取module結構體首地址,以及自動完成其他工作。將卸載驅動的命令寫入該指令檔。執行#sh build.sh卸載指定linux驅動模組。
force_kill_driver/bad_driver目錄提供了兩個出錯的linux驅動:bad_driver1(情況一)、bad_driver2(情況二)。bad_driver目錄也提供了一個build.sh指令檔。執行該指令檔會自動編譯安裝這兩個出錯驅動。
在安裝force_kill_driver驅動來卸載這兩個出錯驅動時須先安裝,再執行兩次build.sh指令檔完成卸載工作。
Android深度探索HAL讀書筆記8