我們將通過裝置檔案/dev/hello來連線硬體抽象層模組和linux核心驅動程式模組。
二. 進入到在hardware/libhardware/include/hardware目錄,新建hello.h檔案:
user-name@machine-name:~/android$ cd hardware/libhardware/include/hardware
user-name@machine-name:~/android/hardware/libhardware/include/hardware$ vi hello.h
hello.h檔案的內容如下:
[cpp]view plain
copy
#ifndef android_hello_inte***ce_h
#define android_hello_inte***ce_h
#include
__begin_decls
/*定義模組id*/
#define hello_hardware_module_id "hello"
/*硬體模組結構體*/
struct
hello_module_t ;
/*硬體介面結構體*/
struct
hello_device_t ;
__end_decls
#endif
這裡按照android硬體抽象層規範的要求,分別定義模組id、模組結構體以及硬體介面結構體。在硬體介面結構體中,fd表示裝置檔案描述符,對應我們將要處理的裝置檔案"/dev/hello",set_val和get_val為該hal對上提供的函式介面。
三. 進入到hardware/libhardware/modules目錄,新建hello目錄,並新增hello.c檔案。 hello.c的內容較多,我們分段來看。
首先是包含相關標頭檔案和定義相關結構:
[cpp]view plain
copy
#define log_tag "hellostub"
#include
#include
#include
#include
#include
#include
#define device_name "/dev/hello"
#define module_name "hello"
#define module_author "[email protected]"
/*裝置開啟和關閉介面*/
static
inthello_device_open(
const
struct
hw_module_t* module,
const
char
* name,
struct
hw_device_t** device);
static
inthello_device_close(
struct
hw_device_t* device);
/*裝置訪問介面*/
static
inthello_set_val(
struct
hello_device_t* dev,
intval);
static
inthello_get_val(
struct
hello_device_t* dev,
int* val);
/*模組方法表*/
static
struct
hw_module_methods_t hello_module_methods = ;
/*模組例項變數*/
struct
hello_module_t hal_module_info_sym =
};
這裡,例項變數名必須為hal_module_info_sym,tag也必須為hardware_module_tag,這是android硬體抽象層規範規定的。
定義hello_device_open函式:
[cpp]view plain
copy
static
inthello_device_open(
const
struct
hw_module_t* module,
const
char
* name,
struct
hw_device_t** device)
memset(dev, 0, sizeof
(struct
hello_device_t));
dev->common.tag = hardware_device_tag;
dev->common.version = 0;
dev->common.module = (hw_module_t*)module;
dev->common.close = hello_device_close;
dev->set_val = hello_set_val;dev->get_val = hello_get_val;
if((dev->fd = open(device_name, o_rdwr)) == -1)
*device = &(dev->common);
logi("hello stub: open /dev/hello successfully."
);
return
0;
}
hello stub: failed to open /dev/hello -- permission denied.
解決辦法是類似於linux的udev規則,開啟android源**工程目錄下,進入到system/core/rootdir目錄,裡面有乙個名為ueventd.rc檔案,往裡面新增一行:
/dev/hello 0666 root root
定義hello_device_close、hello_set_val和hello_get_val這三個函式:
[cpp]view plain
copy
static
inthello_device_close(
struct
hw_device_t* device)
return
0;
} static
inthello_set_val(
struct
hello_device_t* dev,
intval)
static
inthello_get_val(
struct
hello_device_t* dev,
int* val)
read(dev->fd, val, sizeof
(*val));
logi("hello stub: get value %d from device"
, *val);
return
0;
}
四. 繼續在hello目錄下新建android.mk檔案:
local_path := $(call my-dir)
include $(clear_vars)
local_module_tags := optional
local_prelink_module := false
local_module_path := $(target_out_shared_libraries)/hw
local_shared_libraries := liblog
local_src_files := hello.c
local_module := hello.default
include $(build_shared_library)
注意,local_module的定義規則,hello後面跟有default,hello.default能夠保證我們的模組總能被硬象抽象層載入到。
五. 編譯:
user-name@machine-name:~/android$ mmm hardware/libhardware/modules/hello
編譯成功後,就可以在out/target/product/generic/system/lib/hw目錄下看到hello.default.so檔案了。
六. 重新打包android系統映象system.img:
user-name@machine-name:~/android$ make snod
重新打包後,system.img就包含我們定義的硬體抽象層模組hello.default了。
Android HAL層開發框架介紹
android hal層即硬體抽象層是google響應廠家 希望不公開原始碼 的要求推出的概念 1,源 和目標位置 源 hardware libhardware目錄,該目錄的目錄結構如下 hardware libhardware hardware.c編譯成libhardware.so,目標位置為 s...
Android HAL層庫載入原理
android hal層庫載入原理 android hal層的由來 由於市面做移動晶元的廠商很多,大部分廠商考慮到自己硬體的設計架構 安全 專利等方面原因,不願意公開自己的這方面 也出於不同廠商硬體架構不太一樣,適配開發難度周期長,google在kernel之上加了乙個hal層,只要各個廠商實現an...
裝置驅動層
驅動層一般由硬體抽象層 hal 板級支援包 bsp 和驅動程式組成,是嵌入式系統中不可或缺的重要部分。它的作用是為上層程式提供外部裝置的操作介面,並且實現裝置的驅動程式。上層程式可以不管操作的裝置內部實現,只需要呼叫驅動的介面即可。硬體抽象層 hal 嵌入式系統通常包含三個部分 嵌入式應用程式 嵌入...