第九章 硬件抽象層:HAL

  1. 爲什麼要在Android中加入HAL

Goggle爲Android 加入HAL主要有如下目的:

統一硬件的調用接口。由於HAL有標準的調用接口,所以可以利用HAL屏蔽Linux驅動複雜、不統一的接口。

解決了GPL版權問題。由於 Linux 內核基於GPL協議,而Android基於Apache Licence 2 . 0協議。

針對一些特殊的要求。對於有些硬件,可能需要訪問一些用戶空間的資源,或在內核空間不方便完成的工作以及特殊需求。

  1. android HAL架構 
  1. 爲LED驅動增加HAL
    1. 編寫一款支持 HAL 的 Linux 驅動程序的步驟:

第 1 步: 編寫 Linux 驅動;第 2 步:編寫 HAL Library;第 3 步:編寫 Service Library

  1. 精簡 LED 驅動

基本原理是隻從指定存器讀取或寫入5個字節.第 1 個字節用於指定讀寫的動作以及寄存器類型.後 4 個字節是讀寫的實際的數據(因爲LED驅動只涉及操作一個int類型數據的寄存器 ,因此使用4個字節來表示一個int類型的數據〉。 在與LED驅動交互時,只要向設備文件(/dev/s3c64IO_leds_hal) 讀取或發送 5 個字節的數據,就可以讀寫指定的寄存器。

  1. 測試讀寫寄存器操作

在編寫 Linux 驅動以及與驅動相關的程序的過程中應分段測試每一部分程序。

使用下面的命令執行相應目錄中的build.sh腳本文件,即可測試LED代碼的準確性:sh build.sh

  1. :編寫誦點LED驅動的HAL模塊;

編寫 HAL模塊的步驟和原理如下:

第l步:定義結構體和宏:編寫 HAL 模塊需要使用到 3 個非常重要的結構體( hw_module_t 、 hw_device_t 和hw _ module_ method_ t), 在第 l 步需要定義兩個新的結構體, 這兩個結構體的第 l 個變量的數據類型必須是 hw_module_t和 bw_device_t。 除此之外, 還需要爲HAL模塊定義一個ID. 實際上在這 l 步就是編寫leds_hal.h 頭文件的代碼。

第 2 步:編寫 HAL模塊的 open 函數:

  • open 函數是 HAL 模塊的入口點。該函數主要做如下 3 項工作:初始化 hw device_t 的子結構體。打開設備文件。初始化寄存器。

第3 步:定義 hw_module_methods_ t 結構體變量

第4 步: 定義 HAL_MODULE_INFO_SYM 變量

第5步:編寫 HAL模塊的 close 函數

第 6步:編寫控制 LED 的函數

  1. 編寫調用 HAL 模塊的 Service

調用 HAL 模塊涉及一個非常重要的 hw_get_ module 函數。該函數可以通過在 leds_hal.h 中定義的 LED_HARDWARE_MODULE_ID 宏查找LED HAL 模塊,並獲得 led_module_t 結構體。然後調用led _module_ t.hw _ module.methods.open 函數來初始化 LED 驅動, 並通過 open 函數返回 led_control_device_t 結構體。在 led_control_device_ t 結構體中包含了在 HAL 模塊中定義的控制 LED 驅動的函數指針(set_on 和 set_off)。

  1. HAL模塊的存放路徑和命名規則:

HAL 棋塊庫文件的存放路徑有兩個: /system/lib/hw 和/vendor/lib/hw。 hw_get_module 函數會先從/system/lib/hw 目錄根據庫文件命名規則尋找庫文件。如果/system/lib/hw 目錄中未找到庫文 件, hw_get_ module 會按同樣的規則在/vendor/lib/hw 目錄中尋找.

  HAL 模塊庫文件的命名規則是 ID.suffix.so。其中 ID 通過 hw_get_ module 函數的 id 參數指 定。 suffix (後綴〉通過屬性文件指定。

  hw _get_module 會在 Android 系統的屬性文件中根據 variant_keys 數組中定義的 4 個 key 依次查找 suffix. 如果未找到 suffix, 使用默認的 suffix (default)。

實際上, Android 系統的屬性文件具有如下4 個:

 /default.prop;/system/build.prop; /system/default.prop; /data/local.prop.

  1. 編寫調用 Service 的 Java 庫

可以將調用 Service程序庫的 Java 類單獨封裝在jar文件中,這樣做任何的 Android 應用程序中只要引用了這個jar文件就可以像調用普通Java 類一樣訪問 LED 驅動了.

  1. 測試 LED 驅動

本節實現的測試程序將通過調用 LedHalService.setOn 和 LedHalService.setOff方法控制 LED.