Android深度探索(卷1)HAL與驅動開發學習筆記(6)

Android深度探索(1)HAL與驅動開發學習筆記(6linux

第六章 第一個Linux驅動程序 統計單詞個數函數

 

Linux系統將每個驅動都映射成一個文件.這些文件稱爲設備文件或驅動文件,都保存在/dev目錄中。這種設計理念使得與Linux驅動進行交互就像與普通文件進行交互同樣容易。雖然C語言裏沒有事件的概念,但卻有與事件相似的概念,這就是回調(c a l l b a c k)函數。所以,編寫Lin u x驅動最重要的一步就是編寫陰調函數,不然與設備文件交互的數據將沒法獲得處理。學習

6.1編寫Linux驅動的步驟測試

  1. 創建Linux驅動骨架
  2. 註冊和註銷設備文件
  3. 指定與驅動相關的信息
  4. 指定回調函數
  5. 編寫業務邏輯
  6. 編寫makefile 文件
  7. 編譯Linux驅動程序
  8. 安裝和卸載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 cC語言中用s t a t i c聲明函數、變量等資源,系統會將這些函數和變量單獨放在內存的某一個區域,直到程序徹底退出,不然這些資源不會被釋放, L i n u x驅動一旦裝載,除非手動卸載或關機,驅動會一直駐留內存,所以這些函數和變量資源會一直在內存中。也就是說屢次調用這些資源不用再進行壓棧,出棧操做了,有利於提升驅動的運行效率。

 

6.7 指定回調函數

  1. w o r d _ c o u n t_r e a dword_c o u n t_w r i t e函數的參數基本相同,只有第2個參數b u f稍微有差別。word _count _r e a d.函數的b u f參數類型是c h a r*,而w o r d _count _w r i t e函數的b u f參數類型是co n s t  char*;這就意味着w o r d _count _w r i t e函數中的b u f參數值沒法修改。Word_count_read函數中的b u f參數表示從設備文件讀出的數據,也就是說b u f中的數據均可能自設備文件讀出,至於能夠讀出多少數據,取決於w o r d _count _r e a d.函數的返回值。
  2. 因爲內核空間的程序不能直接訪問用戶空間中的數據,所以須要在.w o r d_c o u n t -r e a dword _c o unt_w r i t e函數中分別使用copy_to_user和c o p y _ from_user函數將數據從內核空間複製到用戶空間戒從用戶空間複製到內核空間。

 

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 od 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 eruse 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內核進行測試

相關文章
相關標籤/搜索