HAL stub
每种硬件都对应了一个HAL模块,实现HAL,需要满足HAL的相关规则,规则定义在源码hardward目录下,头文件hardward.h,C文件hardward.c。
1、重要结构体:
hardward.h中定义了三个重要的结构体:
struct hw_module_t; struct hw_module_methods_t; struct hw_device_t;
a、结构体hw_module_t代表hal模块 ,hal模块需自定义一个结构体,并且该struct包含hw_module_t结构体,且模块的tag必须为HARDWARE_MODULE_TAG,表示hal模块的结构体。
b、结构体hw_module_methods_t代表模块的操作方法列表,它内部只有一个函数指针open,用来打开该模块下的设备
c、结构体hw_device_t代表该模块下的设备,hal模块需要自定义一个结构体,且必须包含 hw_device_t。
d、最后这个模块定义好之后还必须导出符号HAL_MODULE_INFO_SYM,指向这个模块,HAL_MODULE_INFO_SYM定义在hardware.h中值为“HMI”
2、上层如何与hal进行通信:
通过HAL_MODULE_INFO_SYM,google hal与qcom hal部分进行绑定,上层也通过HAL_MODULE_INFO_SYM获取到hal层的相关接口,获取到hal模块使用hw_get_module函数。
3、实现加减的简单hal实现
在hardware/libhardware/include/hardware目录下建立lethe.h:
在该头文件中我们自定义设备结构体,在该设备结构体中声明add和subtract函数。
#include <stdint.h> #include <stdbool.h> #include <sys/cdefs.h> #include <sys/types.h> #include <cutils/native_handle.h> #include <hardware/hardware.h> #include <hardware/gralloc.h> // hal模块名 #define LETHE_HARDWARE_MODULE_ID "lethe" // hal版本号 #define LETHE_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(0, 1) #define HARDWARE_LETHE "lethe" // 自定义hal模块结构体 typedef struct lethe_module { struct hw_module_t common; // 第一个变量必须为hw_module_t } lethe_module_t; // 自定义hal设备结构体 typedef struct lethe_device { struct hw_device_t common; // 加法函数 int (*add)(const struct lethe_device *dev, int a, int b, int *total); // 减法函数 int (*subtract)(const struct lethe_device *dev, int a, int b, int *total); } lethe_device_t; static inline int lethe_open_test(const struct hw_module_t *module, lethe_device_t **device) { return module->methods->open(module, HARDWARE_LETHE, (struct hw_device_t **)device); }
在hardware/libhardware目录下新建lethe文件夹:
在lethe.c文件中主要导入符号HAL_MODULE_INFO_SYM,用来指向自定义模块,编写模块相关函数接口:
#include <malloc.h> #include <stdint.h> #include <string.h> #include <log/log.h> #include <hardware/lethe.h> #include <hardware/hardware.h> static int add(const struct lethe_device *dev, int a, int b, int *total) { if (!dev) { return -1; } *total = a + b; return 0; } static int subtract(const struct lethe_device *dev, int a, int b, int *total) { if (!dev) { return -1; } *total = a - b; return 0; } static int lethe_close(hw_device_t *dev) { if(dev) { free(dev); return 0; } else { return -1; } } //打开设备函数 static int lethe_open(const hw_module_t* module,const char __unused *id, hw_device_t** device) { if (device == NULL) { ALOGE("NULL device on open"); return -1; } lethe_device_t *dev = malloc(sizeof(lethe_device_t)); memset(dev, 0, sizeof(lethe_device_t)); dev->common.tag = HARDWARE_DEVICE_TAG; dev->common.version = LETHE_MODULE_API_VERSION_1_0; dev->common.module = (struct hw_module_t*) module; dev->common.close = lethe_close; dev->add = add; dev->subtract = subtract; *device = &(dev->common); return 0; } static struct hw_module_methods_t lethe_module_methods = { .open = lethe_open, }; //导出符号HAL_MODULE_INFO_SYM,指向自定义模块 lethe_module_t HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, .module_api_version = LETHE_MODULE_API_VERSION_1_0, .hal_api_version = HARDWARE_HAL_API_VERSION, .id = LETHE_HARDWARE_MODULE_ID, .name = "lethe hal", .author = "lethe", .methods = &lethe_module_methods, }, };
编写Android.bp文件就可以生成自己的hal库:
cc_library_shared { //共享库,.so结尾 relative_install_path: "hw", proprietary: true, srcs: ["lethe.c"], header_libs: ["libhardware_headers"], shared_libs: ["liblog"], }
Lethetest.cpp用来测试hal:
#include <hardware/hardware.h> #include <hardware/lethe.h> #include <log/log.h> int main() { lethe_device_t* lethe_device = NULL; const lethe_module_t *module = NULL; // 用来获取lethe模块 int ret = hw_get_module(LETHE_HARDWARE_MODULE_ID, (const struct hw_module_t** )&module); if (!ret) { ret = lethe_open_test((const struct hw_module_t*)module, &lethe_device); } if (ret < 0) { ALOGE("get lethe hal failed ......"); return -1; } int total = 0; lethe_device->add(lethe_device, 5, 3, &total); ALOGE("[lethe]======== add 5 + 3 = %d", total); lethe_device->add(lethe_device, 5, 3, &total); ALOGE("[lethe]======== subtract 5 - 3 = %d", total); }
执行./lethe_test进行hal测试,测试结果如下:
[lethe]======== add 5 + 3 = 8 [lethe]======== add 5 - 3 = 2