Re: [问题] AOSP 的 source code

楼主: gn00618777 (非常念旧)   2016-07-08 19:56:59
※ 引述《mshockwave (夏克维夫)》之铭言:
: 首先我也非常感动有人研究 AOSP HAL
: 我当初掉进 AOSP 的坑也是从 HAL 开始
: ※ 引述《gn00618777 (非常念旧)》之铭言:
: : 在asop内
: : mydroid/hardware/libhardware/hardware.c 内的 hw_get_module function
: : 原型是
: : hw_get_module(const *id, hw_module_t **)
: : 但在许多 android service 中会呼叫,并带入参数(如:
: : camera_module_t、sensor_module_t)
: : 在 service 内宣告一个 sensor_module_t 的变量 mSensorModule
: : 呼叫 hw_get_module( * , (hw_module_t**)&mSensorModule);
: : mSensorModule 结构里有包含 hw_module_t 的型态,mSensorModule
: : 被强制作 hw_module_t 型态转换有什么用意吗?
: 从结论来说 你可以见识到 google 工程师 c/c++ 的怪物等级:
: 你可以观察一下 像 sensors_module_t, camera_module_t 这些 struct
: 他们有个共同特征:第一个 struct field 一定是 hw_module_t 型态
: 例如 sensors_module_t 他第一个 struct field 就是 "struct hw_module_t common;"
: 而假如 sensors_module_t 和 hw_module_t 长这样:
: struct hw_module_t {
: int id;
: const char* name;
: }
: struct sensors_module_t{
: struct hw_module_t common;
: int foo;
: int bar;
: }
: 那其实在内存中你可以把它想成他会"摊开"成这样:
: struct sensors_module_t {
: int id;
: const char* name;
: int foo;
: int bar
: }
: 所以假如你有一个 sensors_module_t 型态的变量 sensorMod
: 那你依然可以呼叫 ((hw_module_t*)&sensorMod)->name
: 没错 老师说 struct 的 memory layout 不一定会一个 field 接着一个
: 可能会因 alignment 而有所调整 但因为 hw_module_t 必定是在第一个 field
: (这是类似约定的规定 google没写出来是因为这件事只要给硬件厂知道就好)
: 所以不用担心 alignment 问题
: 这种手法看起来是不是很熟悉? 没错 他们就是用 C 来模拟 C++ 的继承
: 为什么不直接用 C++? 疴...因为很多硬件工程师只会写C (X)
: 因为 C 许多性质都比较适合写底层的 code (O)
: : 最后 mSensorModule 可以拿来呼叫mSensorModule->get_sensor_list() function
: : mSensorModule不是已经被转换成 hw_module_t型态了? 他为啥可以呼叫
: : sensors_module_t型态里面的 get_sensor_list fucntion?
: : 谢谢指教..
: 其实 hw_get_module 的流程挺简单的:
: 丢给他你想要的硬件后 他会解析名称然后用 dlopen 加载适当的 .so file
: 也就是该硬件的实作 share library
: 而每个实作的硬件 shared library
: 礼面一定会有个变量 HAL_MODULE_INFO_SYM (这也是约定的)
: 像 sensor 的就在这边: http://goo.gl/186qAC
: 那个变量其实就是 XXX_module_t 的实作 在前面 dlopen 后会用 dlsym 去得到它
: 所以虽然你在 hw_get_module 那边已经把 mSensorModule 转型成 hw_module_t**
: 但重点就在这边:hw_module_t** 是指标的指标 也就是 dereference 第一次后
: 会是个 pointer, 在 C 语言中这种"输出型变量"很常见 所以显而易见的
: 这边就是输出个 hw_module_t* 这样的话因为是个指标 你就可以做一大堆奇怪的事了
: 说得更明确一点:sensors_module_t 的"实体" 在 share library 里面
: 所以就算你转成 hw_module_t* 但 sensors_module_t 的实体位址不会变啊
: 你依然存取得到他 以及呼叫他的函式
感谢m大的解说
dlsym 回传 symble 为 HMI 的位址,而这个位址是 struct AL_MODULE_INFO_SYM 的位址
他把他做一个强制转换为 hw_module_t 型态的指标,对传进来的 *pHmi 做赋值
*pHmi 当然就是传进来的 hw_module_t 位址,现在被赋值后,就指向
struct HAL_MODULE_INFO_SYM 的 common filed 位址了,也就是 hw_module_t
而 hw_module_t 的位址就是 struct AL_MODULE_INFO_SYM 的第一个,当然最后
最上面就可以呼叫 struct HAL_MODULE_INFO_SYM 内 get_sensor_list function
这有点像是一个阵列,它的阵列名称是第一个元素的位址,也是这个阵列起始位址的概
念。
我的理解是这样 @@"
有错请指教囉,谢谢。

Links booklink

Contact Us: admin [ a t ] ucptt.com