Android深度探索(卷1)HAL與驅動開發學習筆記(6)linux
第六章 第一個Linux驅動程序 統計單詞個數函數
Linux系統將每個驅動都映射成一個文件.這些文件稱爲設備文件或驅動文件,都保存在/dev目錄中。這種設計理念使得與Linux驅動進行交互就像與普通文件進行交互同樣容易。雖然C語言裏沒有事件的概念,但卻有與事件相似的概念,這就是回調(c a l l b a c k)函數。所以,編寫Lin u x驅動最重要的一步就是編寫陰調函數,不然與設備文件交互的數據將沒法獲得處理。學習
6.1編寫Linux驅動的步驟測試
* 上面8步中的前5步是關於如何編寫Lin u x驅動程J字的,經過後3步可使L i n u x驅動正常工做。ui
6.2 編寫L i n u驅動程序前的準備工做spa
本例的L i n u x驅動源代碼並未與li n u x內核源代碼放在一塊兒,而是單獨放在一個目錄。* 首先使用下面的命令創建存放Li n u x驅動程序的目錄。設計
# mkdir -p/root/drivers/ch06/word_count日誌
# cd /root/drivers/ch0 6/word_count事件
* 而後,使用下面的命令創建驅動源代碼文件(word count.c)內存
# echo ’’>word_count.c
最後編寫一個M a k e f i l e文件,
# echo ‘obj-m := word_count.o ’ > Makefile
6.3 編寫L i n u x驅動程序的骨架(初始化和退出驅動)
代碼中使用了p r i n t k函數。該函數用於輸出日誌信息printk函數與p r i n t f函數的用法相似。linux系統將內存分爲了用戶空間和內核空間,這兩個空間的程序不能直接訪問。p r i n t f函數運行在用戶空間,p r i n t k函數運行在覈空間。所以,屬於內核程序的L i n u x驅動是不能直接訪問p r i n t f函數的。運行在這兩塊內存中的程序之間交互的-方法不少。其中,設備文件就是一種主要的交互方式,若是用戶空間的程序要訪問內核空間,只要作一個能夠訪問內核空間的驅動程序,而後用戶空間的程序經過設備文件與驅動程序進行交互便可.那麼,如何在linux驅動程序中動態分配內存空間呢?解決相似的問題也很簡單。既然L i n u x驅動沒法直接調用運行在用戶空間的函數,那麼,在L i n u x內核中就必需要提供替代品。能夠進入<Li n u x內核源代碼>/i n c l u d e目錄,該目錄的各個子目錄中…包含了大量的C語言頭文件,這些頭文件中定義資源就是運行在用戶空間的程序的替代品。
6.4. 安裝查看和卸載Linux驅動
* 安裝Linux驅動
# ismod word_count.ko
* 查看word_count 是否安裝成功
# lsmod I grep word_count
* 卸載Linux驅動
# remmod word_count
* 查看Linux驅動的輸出信息
# dmesg | grep word_cound | tail -n 2
6.5 指定與驅動相關的信息
通常須要爲L i n u x驅動程序,指定以下信息。
模塊做者:使用MODULE_AUTHOR宏指定。
模塊描述:使用MODULE_DESCRIPTION宏指定。
模塊別名:使用MODULE_ALIAS宏指定。
開源協議:使用MODULE_LICENSE宏指定。
代碼以下(通常放在word_count.c最後):
MODULE_AUTHOR(「lining」);
MODULE_DESCRIPTION(「statistics of word count .」);
MODULE_ALIAS(「word count module .」);
MODULE_LICENSE(「GPL」);
6.6 註冊和註銷設備文件
爲w o r d_c o u n t驅動創建一個設備文件,該設備文件的名稱是w o r d c o unt,位於/d e v目錄中。設備文件與普通文件不一樣,不能使用I O函數創建,須要使用m i s c_r egister函數創建設備文件,使用m i s c_d e r e g i s t e r函數註銷(移除〉設備文件。
* 編寫中的注意事項
1.設備文件由主設備號和次設備號描述。而使用m i s c _ r e g i s t e r函數只能設置次設備號。主設備號統一設爲10。主設備號爲1 0的設備是L i n µ x系統中擁有共同特性的簡單字符設備。這類設備稱爲m i s c設備。
2. miscdevice.name變量的值就是設備文件的名稱。在本例中設備文件名稱爲w o r d c o u n t .
3. 如果成功註冊了設備文件,m i s c _ _ r e g i s t e r函數返回非0的整數,若是註冊設備文件失敗返回0。
4. w o r d_c o u n t . c中的全部函數、變量都聲明成了s t a t i c。C語言中用s t a t i c聲明函數、變量等資源,系統會將這些函數和變量單獨放在內存的某一個區域,直到程序徹底退出,不然這些資源不會被釋放, L i n u x驅動一旦裝載,除非手動卸載或關機,驅動會一直駐留內存,所以這些函數和變量資源會一直在內存中。也就是說屢次調用這些資源不用再進行壓棧,出棧操做了,有利於提升驅動的運行效率。
6.7 指定回調函數
6.8測試Linux驅動的多種方法
1.使用Ubuntu Linux測試Linux驅動
2.A n d r o i d模擬器上經過原生(Native )C程序測試L i n u x驅動
* 用於Andr o i d模擬的g o l d f i s h內核默認不容許動態裝載L i n u x驅動模塊,所以須要在編譯L i n u x內核以前執行以下命令配置L i n u x內核。
# cd kernel goldfish
# make menuconfig
* 執行上面的命令後,按空格鍵將第二頂「Enable loadable module s u p p ort」選中前面是(*),而後按回車鍵選入子菜單,選中前3項,不然L i n u x驅動模快仍然沒法安裝和卸載。當退出設置菜單時保持設置。最後從新編譯Linux內核,成功編譯內核後, A n d r o i d模擬器可使用新生成的zImage內核文件動態裝載L i n u x驅動模塊。
*在執行build.h腳本文件完成對w o r ld_c o u n t驅動的編譯、上傳和安裝的工做,而後進入A n d r o i d模擬器的終端,使用e c h o和d mesg命令能夠演出w o r d _ c o u n t驅動和查看測試時結果。
* 爲了使編譯步驟儘量簡單使用Android設 置 編 譯 參 數 , 並 使 用 make命令進行編譯。首先在root/driver/ch06/word_count目錄中創建一個A n d r o i d . m k文件,並輸入以下的內容。
LOCAL PATH:= $ (call my -dir)
include $(CLEAR VARS)
#指定要編譯的源代碼文件
LOCAL _SRC _FILES := test _word_count .c
#指定模塊名,也是編譯後生成的可執行文件名
LOCAL_MODULE:= test_word_cunt
LOCAL _MODU LE _T AGS:= optional
include $(BUILD_EXECUTABLE)
A r i dro i d . m k文件中有以下兩個地方須要說明一下.
LO C AL _MODULE_TAGS.
表示當前工程(A n d roi d .mk文件所在的目錄)在什麼模式下編譯。若是設爲optional,表示不考慮模式,也就是說,在任何膜式下都會編譯。該變量能夠設置的值有us er、use r d e b u g、e ng、 o p t i o n a l其中eng是默認值。
include $(BUILD_EXEC UT ABLE) .
BUILD _EXECUTABLE表示創建可執行的文件。可執行文件路徑是<A n d r o i d源代碼目錄〉
3.使用Android ADK設置Linux驅動
4.使用JAVA代碼直接操做設備文件來測試Linux驅動
5.使用S3C6410開發板測試Linux驅動
6.將驅動編譯進Linux內核進行測試