Email me: jollen # jollen.org

more: Jollen 的 Embedded Linux 教育訓練

« November 2009 | (回到Blog入口) | January 2010 »

December 2009 歸檔

December 1, 2009

Android 的 HAL 技術, #5: 繼承 HAL 的 struct hw_module_t

撰寫 HAL stub 除了要具備系統程式(systems software)的觀念外(這是基礎),「思考方式的改變」也是重要的一堂課。

思考方式哪裡不同?

實作 HAL stub 的首要工作是「繼承 struct hw_module_t 抽象型別」。Class(類別)屬於一種抽象型號(ADT)。

首先,引入最重要的標頭檔(header file):

#include <hardware/hardware.h>

接著,再定義一個「MODULE ID」。這個 mdoule ID 將會被 HAL 層用來尋找 HAL stub。我們舉最簡單的裝置類型「LED」來做為範例:

#define LED_HARDWARE_MODULE_ID "led"
繼承 HAL 的 struct hw_module_t 抽象型別(即 base class 的概念),並取名為 struct led_module_t(即 derived class):
struct led_module_t {
   struct hw_module_t common;
};

以資料結構的角度來看,這裡的做法只是宣告了一個抽象資料型別(Abstract Data Type),以提升程式碼的結構化特性。但是,這裡需要以架構的角度來解釋,「Android HAL規定不要直接使用struct hw_module_t」,原文的意思是要我們做類別繼承。

實作繼承

在C語言裡實作繼承的方式,大致如下:

1. 宣告一個 data structure 將原始的基本結構包裝起來
2. 將原始的基本結構放在第一個 field

因此,可以思考如下:

struct led_module_t {
   struct hw_module_t common;
    
   /* Place attributes here. */
 
   /* Place methods here. */
};

唯一,這裡的實作在OO特性上,缺乏像是public與private的封裝性。但這裡的重心是,以OO的方式思考,會如何改變過去的 C 程式寫作習慣?最明顯的地方是,程式碼的寫作風格有了很大的改變

December 4, 2009

Android 的 HAL 技術, #6: 小結 HAL stub 實作步驟

在討論了不少基本概念後,在這裡小結一下 HAL stub 的實作步驟。HAL stub 的起頭是「繼承 HAL 的 struct hw_module_t」,這是 HAL stub 的設計理念,除了讓架構的條理分明外,也容易做後續擴充與維護。以下改用實用上的習慣用語,小結一下 HAL stub 實作步驟,並提供一段例。

HAL Stub 實作步驟(Implementation)

1. 設計自已的wrapper data structure

* 編寫led.h
* 定義 struct led_module_t
* 框架提供的 struct hw_module_t 必須放在第一個 field、並取名為 common
* 請參考 hardware/hardware.h

2. led_module_t的意義

宣告初始化時期(new object)的 supporting API、在 constructor 裡會使用到。

3. 定義 led_control_device_t

宣告控制時期的 supporting API、在 Manager API 裡會使用到。設計上的細節在後續文章再做整理。

4. 每個 HAL stub 都要宣告 module ID

5. 宣告 Stub operations 並實作 callback functions

Stub 的 operations 結構符號名稱須取名為 HAL_MODULE_INFO_SYM、此符號名不可更改。

範例:led.h

#include <hardware/hardware.h>
   
#include <fcntl.h>
#include <errno.h>
   
#include <cutils/log.h>
#include <cutils/atomic.h>
   
/*****************************************************************************/
   
struct led_module_t {
   struct hw_module_t common;
};
   
struct led_control_device_t {
   struct hw_device_t common;
   /* supporting control APIs go here */
   int (*set_on)(struct led_control_device_t *dev, int32_t led);
   int (*set_off)(struct led_control_device_t *dev, int32_t led);
};
   
/*****************************************************************************/
   
#define LED_HARDWARE_MODULE_ID "led"
實作上的細節在這裡不再多做說明,關於設計上的細節將另行整理。

December 26, 2009

Android 的 HAL 技術, #7: 取得 Proxy Object

延續上一則日記的介紹,在完成HAL Stub的實作後,緊接著的工作就是撰寫Native Service。

談了許多「Android Service」以及「HAL Stub」,這裡再補充一點。Android作業系統啟動時,會執行一個process稱為servicemanager。Servicemanager process負責管理、提供並保存「Android Service」。Android Service為Java層,因此接下來會透過JNI來呼叫C/C++層的Native Service。

廣義來說,Native Service也提供Runtime的功能,即Core Library層。Runtime的重要工作之一為「取得HAL Stub所提供的API」,因此這是撰寫完整Native Service的前哨站。

什麼是 Proxy Object?

Native Service呼叫HAL的hw_get_module() API取得stub物件,即HAL_MODULE_INFO_SYM。

HAL會去尋找HAL Stub檔案,HAL Stub是以*.so檔的形式存在,並佈署於/system/lib/hw目錄下。HAL會根據module ID以及”ro.product.board”去尋找相對應的*.so檔,以我們的LED範例來說,HAL會回傳回led_module_t結構的物件(an instance of led_module_t class)給Native Service。

我們把HAL回傳給Native Service的資料稱為「Stub Object」或是「Proxy Object」,即先前所提及的「代理人」觀念。Native Service透過代理人與 Linux 驅動程式溝通。這個過程的觀念如圖1所示。


圖1:取得Proxy Object

hw_get_module(),這是HAL所提供的API,也是實作HAL Stub最重要的一個API,不過另人驚奇的地方是,這也是目前AOSP裡HAL層所提供的唯一一個API。

關於 December 2009

此頁面包含了在December 2009發表於Jollen's Blog的所有日記,它們從老到新列出。

前一個存檔 November 2009

後一個存檔 January 2010

更多信息可在 主索引 頁和 歸檔 頁看到。

Top | 授權條款 | Jollen's Forum: Blog 評論、討論與搜尋
Copyright(c) 2006 www.jollen.org