android HAL層驅動對接例項

2021-06-18 18:12:41 字數 4776 閱讀 3716

我們將通過裝置檔案/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 嵌入式系統通常包含三個部分 嵌入式應用程式 嵌入...