浅谈HAL
参考:http://blog.csdn.net/mr_raptor/article/details/8074549
代码实现:http://blog.csdn.net/mr_raptor/article/details/8082360
HAL:
至于为什么使用HAL,简单说为了死守自家的代码(个人利益,不让人抄袭)。
直观点说HAL是一个c中的interface,就是说用一个structure中的pointer一直向下指,最终指向一个设备(/dev/led)。
具体流程:
也就是说:
1。app(应用层)代码
2. serveice(framework层,此层是给应用层提供服务的)
3. JNI(java不能访问C/CPP,所以就得使用这个楼,jni中的C/CPP文件编译后就生成一个.so文件(libled_runtime.so),jni还会引用hal中头文件来获取hal中一些函数or变量)
4. HAL(jni中会调用hal中的interface,hal中的代码编译后也会生成一个.so文件(led.default.so))
5. device & driver(硬件设备)
HAL 代码结构:
HAL stub的框架比较简单,三个结构体、两个常量、一个函数,简称321架构。
@hardware/libhardware/include/hardware/hardware.h
@hardware/libhardware/hardware.c
1. 三个结构体
0) 三个结构体指的是:hw_module_t, hw_module_methods_t,hw_device_t
1) led_module_t继承hw_module_t,也就是说led_module_t结构体中有hw_module_t成员变量。每个某块都需要继承hw_module_t。
2) 每一个模块都有各自独特的函数,led_device_t中的setON之类的。led_device_open中定义led_device_t
重新整理一下的话:
2. 两个变量
#define HAL_MODULE_INFO_SYM HMI
#define HAL_MODULE_INFO_SYM_AS_STR "HMI"
这个就是led_module_t 的名字罢了,就是为了统一,就是HAL Stub的固定名字。
注册时有用会加载HMI地址。
3. 一个函数
int hw_get_module(const char *id, const struct hw_module_t **module);
通过module id(led.default.so中的led)获取hw_module_t。
4. HALStub是怎么注册的
在前面中HAL编译后会生成led.default.so,
其中led是硬件ID。可参考hardware.c文件,此文件中进行注册。
1)hardware.c中会查找有没有*.prop.so或*.default.so文件,
2)有的话就进行注册,打开此文件,在so代码里有定义的函数名或变量名为HMI,
dlsym返回其地址hmi,将该地址转化成hw_module_t类型,即,硬件对象。