<Android HAL 之路> HAL 简介
2016-04-20 23:01
387 查看
HAL层概述
名称: HAL, Hardware Abstracting Layer,中文名字:硬件抽象层。作用:对Linux内核驱动程序的封装,向上提供接口,屏蔽低层的实现细节。向上衔接Android Runtime和Framework,向下衔接驱动程序
产生原因:利益,竞争
Android代码结构中,HAL层的内容主要集中在Hardware目录中,结合之前讲解Camera模块的时候提到的
system/lib/hw/camera.$(TARGET_BOARD_PLATFORM).so
HAL层的内容集成在动态库中,然后CameraService通过这个So访问其中的内容。
如何访问?
void CameraService::onFirstRef()hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t **)&rawModule)
每一个独立的HAL层的so,有一个与其对应的Id
#define CAMERA_HARDWARE_MODULE_ID “camera”
定义在hardware/libhardware/include/hardware/camera_common.h
又或者
system/lib/hw/audio.primary.$(TARGET_BOARD_PLATFORM)
frameworks/av/services/audioflinger/AudioFlinger.cpp
rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
#define AUDIO_HARDWARE_MODULE_ID “audio”
定义在
hardware/libhardware/include/hardware/audio.h
当然这里只是举个例子,Audio需要加载的模块不止这一个。
基本上每一个模块对应一个So,命名方式也是比较相似,xxx.$(TARGET_BOARD_PLATFORM),存放路径
system/lib/hw
system/lib64/hw
hw_get_module ->hw_get_module_by_class
定义在hardware/libhardware/include/hardware/hardware.h
实现在hardware/libhardware/hardware.c
int hw_get_module(const char *id, const struct hw_module_t **module) { return hw_get_module_by_class(id, NULL, module); } …… int hw_get_module_by_class(const char *class_id, const char *inst, const struct hw_module_t **module) { int i = 0; char prop[PATH_MAX] = {0}; char path[PATH_MAX] = {0}; char name[PATH_MAX] = {0}; char prop_name[PATH_MAX] = {0}; if (inst)//如果inst不为空,name= class_id.inst snprintf(name, PATH_MAX, "%s.%s", class_id, inst); else //如果为空的话,name = class_id strlcpy(name, class_id, PATH_MAX); //判断是否有配置项定义了对应的Hal层 snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name); if (property_get(prop_name, prop, NULL) > 0) { if (hw_module_exists(path, sizeof(path), name, prop) == 0) {//若存在则跳转 goto found; } } //循环查找ro.hardware,ro.product.board,ro.board.platform,ro.arch for (i=0 ; i<HAL_VARIANT_KEYS_COUNT; i++) { if (property_get(variant_keys[i], prop, NULL) == 0) { continue; } if (hw_module_exists(path, sizeof(path), name, prop) == 0) { goto found; } } /* Nothing found, try the default */ if (hw_module_exists(path, sizeof(path), name, "default") == 0) { goto found; } return -ENOENT; found: /* load the module, if this fails, we're doomed, and we should not try * to load a different variant. */ return load(class_id, path, module); }
再看看hw_module_exists这个方法
static int hw_module_exists(char *path, size_t path_len, const char *name, const char *subname) { //拼凑HAL so库的名字 /vendor/lib/hw/name.subname.so或者/vendor/lib64/hw/name.subname.so snprintf(path, path_len, "%s/%s.%s.so", HAL_LIBRARY_PATH2, name, subname); if (access(path, R_OK) == 0) return 0; //拼凑HAL so库的名字 /system/lib/hw/name.subname.so或者/system/lib64/hw/name.subname.so snprintf(path, path_len, "%s/%s.%s.so", HAL_LIBRARY_PATH1, name, subname); if (access(path, R_OK) == 0) return 0; return -ENOENT; }
以audio其中的一个so为例,在源码中找一个芯片平台高通msm8974
system/lib/hw/audio.primary.msm8974.so
顺着以上的代码很好理解,当然这个msm8974必然是可以用过循环的那几个配置项其中的一个获取,否则就是
system/lib/hw/audio.promary.default.so
如何加载
以上代码跳转到found之后return load(class_id, path, module);
static int load(const char *id, const char *path, const struct hw_module_t **pHmi) { …… //打开so,获取句柄 handle = dlopen(path, RTLD_NOW); …… /* Get the address of the struct hal_module_info. */ //获取地址空间的入口 const char *sym = HAL_MODULE_INFO_SYM_AS_STR; hmi = (struct hw_module_t *)dlsym(handle, sym); …… …… hmi->dso = handle; …… *pHmi = hmi; //赋值给传入参数 …… }
最后上层拿到的就是hw_module_t *
然后通过这个入口操作库中的内容,并且每一个HAL模块在定义自己的结构的时候也是需要按照一定的规范来执行。这个留着明天再写吧……
相关文章推荐
- <Android HAL 之路> HAL 简介
- android中fragment卡顿的原因
- android中listview滑动卡顿的原因
- android黑白屏的问题
- android启动时间慢的问题
- 如何实现android和服务器长连接
- 浅谈Android onTouchEvent 与 onInterceptTouchEvent的区别详解
- Android Fragment生命周期
- Android Studio快捷键
- android onTouch()与onTouchEvent()的区别
- Android Small插件化框架解读——Activity注册和生命周期[阿里工程师分享]
- Android复习
- Android API之android.net.wifi.WifiConfiguration
- android获取指定路径下目录文件
- Andriod中绘(画)图----Canvas的使用详解
- Learn Java for Android Development (第三版)---封面
- Android-->Realm(数据库ORM)使用体验,lambda表达式
- [android] 帧动画和补间动画
- Android 2.3.5/4.0.3/4.1PowerManager简单总结和心得体会
- Android学习(31) --对话框&单选对话框&多选对话框