Android HAL层hardware module的设计
来源:互联网 发布:博拉网络上市最新消息 编辑:程序博客网 时间:2024/05/01 04:55
Android为了屏蔽硬件的复杂性,设计了一个HAL层,HardwareAbstarct Layer,即硬件抽象层。HAL层位于驱动和framework之间,为各个硬件厂家提供的形形色色的驱动模块规定了统一的接口。在Android里面,这些接口是用c语言描述的,而在c语言中,接口都是用函数指针来描述的。所以我们在这些接口模块中看到大量函数指针,下面的驱动去实现这些接口,并挂载到这些接口模块上。
这些接口模块本质上就是一些so库,采用动态加载的形式被framework层调用。Framwork层会在使用到某个功能时去尝试dlopen对应的so库,若这个库存在,调用它,若不存在,就认为系统不支持这个功能。完成查找这个硬件模块是否存在,以及去dlopen,dlsym该模块的初始化函数的那些逻辑放在libhardware.so中。那么,framework和hal的关系可以形象的表示为这样的模型:
Audio_interfaces中定义了HAL层的Audio模块(一些so库),比如
static const char * constaudio_interfaces[] = {
AUDIO_HARDWARE_MODULE_ID_PRIMARY,
AUDIO_HARDWARE_MODULE_ID_A2DP,
AUDIO_HARDWARE_MODULE_ID_USB,
}
AudioFlinger使用loadHwModule_l来加载audioInterfaces。实际是去加载HAL层得一些so库。用函数hw_get_module_by_class拿到module,然后用audio_hw_device_open拿到device。所有的HAL层的硬件module都是这么干的。这俩函数定义在libhardware.so中,在编译audioflinger.so时, 这个库是作为动态共享库参加链接的。
我们来看看具体过程:
static intload_audio_interface(const char *if_name, audio_hw_device_t **dev){ const hw_module_t *mod; int rc; rc =hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod); ALOGE_IF(rc, "%s couldn't load audiohw module %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID,if_name, strerror(-rc)); if (rc) { goto out; } rc = audio_hw_device_open(mod, dev); ALOGE_IF(rc, "%s couldn't open audiohw device in %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID,if_name, strerror(-rc)); if (rc) { goto out; } if ((*dev)->common.version <AUDIO_DEVICE_API_VERSION_MIN) { ALOGE("%s wrong audio hw deviceversion %04x", __func__, (*dev)->common.version); rc = BAD_VALUE; goto out; } return 0; out: *dev = NULL; return rc;}
hw_get_module_by_class是在/hardware/libhardware/hardware.c中定义的,这个文件和libhardware/include/hardware/hardware.h一起定义了hal的接口。
有两个基本的结构体:
一个是hw_module_t,定义了模块的一些id,名称,作者等描述信息,
另一个是hw_device_t,没定义太多东西,但是它的继承结构体定义了一个模块对外需要暴露的接口
再看看继承这两个结构体的audio机子的结构体,定义在audio.h (hardware\libhardware\include\hardware),这里定义了:
struct audio_module { struct hw_module_t common;}; struct audio_hw_device {struct hw_device_t common;。。。}struct audio_stream_out { };struct audio_stream {}; struct audio_stream_in {};
具体的HAL层模块通过继承这两个结构体来实现具体的业务功能。
然后调用dlopen打开so库,然后const char *sym =HAL_MODULE_INFO_SYM_AS_STR;
hmi = (struct hw_module_t *)dlsym(handle, sym);
而在hardware.h中
#defineHAL_MODULE_INFO_SYM_AS_STR "HMI"
所以是拿到名为HMI的符号
而在audio_hw.c的最后,定义了
struct audio_module HAL_MODULE_INFO_SYM= { .common = { .tag = HARDWARE_MODULE_TAG, .module_api_version =AUDIO_MODULE_API_VERSION_0_1, .hal_api_version =HARDWARE_HAL_API_VERSION, .id = AUDIO_HARDWARE_MODULE_ID, .name = "Default audio HWHAL", .author = "The Android Open SourceProject", .methods = &hal_module_methods, },};
注意libhardware/include/hardware/audio.h中,定义了
struct audio_module {
struct hw_module_t common;
};
可以认为audio_module是hw_module_t的子类。
回到load_audio_interface,这是通过hw_get_module_by_class拿到了hw_module_t
然后在调用audio_hw_device_open(mod,dev),本质上是调用module->methods->open拿到了hw_device_t的子类audio_hw_device_t。
typedef struct hw_device_t { uint32_t tag; uint32_t version; struct hw_module_t* module;#ifdef __LP64__ uint64_t reserved[12];#else uint32_t reserved[12];#endif int (*close)(struct hw_device_t* device);} hw_device_t;typedef struct audio_hw_deviceaudio_hw_device_t
而structaudio_hw_device {
struct hw_device_t common;
uint32_t (*get_supported_devices)(const structaudio_hw_device *dev);
。。。。
}
这时就拿到了audio_hw_device_t,这个结构体全是各种函数指针,这些指针都已经在调用module->methods->open时已经赋值过了。
所以此时进程拿到了so的接口。而且具有很好的灵活性
而在Load module之后,会调用module的open函数,我们看看这个module是怎么定义的
static_t struct hw_module_methods_t hal_module_methods ={ .open =adev_open,}; struct audio_module HAL_MODULE_INFO_SYM = { .common = { .tag =HARDWARE_MODULE_TAG, .module_api_version = AUDIO_MODULE_API_VERSION_0_1, .hal_api_version = HARDWARE_HAL_API_VERSION, .id =AUDIO_HARDWARE_MODULE_ID, .name ="Manta audio HW HAL", .author ="The Android Open Source Project", .methods =&hal_module_methods, },};
而open就是为audio_hw_device 赋值,而且还会赋值一些环境相关的结构体和变量,他们一起组成了audio_device.我们可以认为,audio_hw_device里的接口都是暴露给外面的接口。
struct audio_device {
structaudio_hw_device hw_device;
。。。
}
就是一个继承了hw_device_t的audio_hw_device。
- Android HAL层hardware module的设计
- Android HAL hardware module分析 以GPS module为例
- Android HAL hardware module分析 以GPS module为例
- Android HAL hardware module分析 以GPS module为例
- Android硬件抽象层HAL(Hardware abstraction layer)分析
- HAL层开发基础 && Android HAL module执行过程分析
- 转)Android HAL hardware module分析 以GPS module为例
- <7> Android HAL hardware.c f分析 Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析
- Android hardware module
- Android HAL(Hardware Abstract Layer硬件抽象层)介绍以及调用
- <6>Android HAL 架构分析之硬件抽象层 hardware.h haraware.c sensors.c
- <5>Android HAL hardware.h 源码文件分析 路径:/hardware/libhardware/include/hardware/hardware.h
- Android中wifi的HAL层
- Android的HAL(硬件抽象层)
- 总结Android HAL层的使用方法
- android关于GPS hal层的分析
- android关于GPS hal层的分析
- 总结Android HAL层的使用方法
- Isomorphic Strings
- C++之多态性与虚函数
- PLSQL连接远程ORACLE数据库中文乱码解决
- uva 10254(四柱汉诺塔)
- bank第二版
- Android HAL层hardware module的设计
- iOS 带参数函数体和不带参数函数体的实现与xcode单步调试
- 使用hydra暴力破解web登录界面
- android studio安装
- 精度: 3%+3个字 什么意思
- 黑马程序员——第六天(包)
- input清除默认样式及兼容问题的解决方法
- A星算法(VC版源码)
- 第二版银行储蓄系统