1、android层次
app层
framework层
库 | runtime(DVM)层
HAL层
linux kernel层
2、hal是什么
全称:harware abstraction layer,硬件抽象层,在库层和linux kernel层之间,包含很多模块和驱动层的模块一一对应。
Andhoidl HAL层(即Hardware Abstraction Layer)是Google开发的Android系统里 上层应用操作底层硬件屏蔽的一个软件层次,屏蔽底层细节,为上层提供统一的接口。
3、为什么需要hal
1). 并不是所有的硬件设备都有标准的Linux Kernel的接口;
2). Kernel driver涉及到GPL的版权。某些设备制造商并不愿意公开硬件驱动,所以才用HAL方式绕过GPL(这是主要原因);
3). 针对某些硬件,Android有一些特殊的需求
4、hal怎么实现
1)存在形式:以.so库文件的形式存在
2)旧框架module
定义:旧的HAL 架构(libhardware_legacy)作法,是传统的「module」方式,也就是将*.so 文件当做「shared library」来使用,在runtime(JNI 部份)以 direct function call (直接调用)使用 HALmodule,即通过直接函数调用的方式,来操作驱动程序。应用程序直接加载 *.so库(dlopen)的做法,调用 *.so里的符号(symbol),也是一种方式(即c库的so和hal层的so打包成一个so库文件)。总而言之是没有经过封装,上层可以直接操作硬件。
弊端:直接调用的方法,是将hal层.so库文件映射到app进程中,如果同时有多个app同时调用这个库,会出现代码重入现象,有两个进程同时操作硬件,导致硬件状态不确定,因此谷歌实现了一个代理人机制(让app访问硬件抽象层模块的代理人,而不是直接访问硬件抽象层的模块),引出hal层新框架
3)新框架module stub
a.新的hal架构介绍(stub代理人):
hal stub 是一种代理人(proxy)的概念,stub 虽然仍是以*. so的形式存在,但HAL 已经将*.so 隐藏起来了(hal 层的方法封装到 stub结构体中,不能直接访问,而是通过stub结构体和它的操作接口访问)。Stub向HAL「提供」操作函数(operations),而runtime 则是向 HAL 取得特定模块(stub)的 operations,再 callback这些操作函数。这种以 indirect function call 的架构,让HAL stub 变成是一种「包含」关系,即HAL里包含了许许多多的 stub(代理人)。Runtime 只要说明「类型」,即module ID,就可以取得操作函数。对于目前的HAL,可以认为Android定义了HAL层结构框架,通过几个接口访问硬件从而统一了调用方式。
b.新hal层架构stub的必备元素
分析: 一个硬件模块,在hal层中都有一个对应的stub,c库要找到对应的stub,并且通过stub来调用硬件操作方法。
必备元素:hal用一个结构体描述stub,这个结构体要包含一个唯一ID,这样c库就可以通过此ID找到stub,还要包含这个stub要实现的方法供c库调用。
获取stub module的函数:hw_get_module(id),通过id可以获取到一个hw_module_t(stub)
c.代码架构
1、struct hw_module_t 结构体,关键成员如下
/ ** Identifier of module */ const char *id;
/ ** Modules methods */ struct hw_module_methods_t* methods;
2、struct hw_module_methods_t结构体,只有一个open函数成员,那么操作硬件的其他方法(ioctl, read, wirte)要怎么向上c库层提供?
typedef struct hw_module_methods_t {
/ ** Open a specific device */
int (*open) (const struct hw_module_t* module, const char* id, struct hw_device_t ** device);}注意第三个参数hw_device_t ,是返回给c库层的结构体,因此可以将其他函数通过此结构体返回给c库层。
3、struct hw_device_t ** device结构体
1)结构体成员
uint32_t version;
struct hw_module_t* module;
int (*close) (struct hw device t* device);
2)这个结构体没有ioctl, read, wirte这些函数成员,因此需要自定义一个结构体struct led_device_t,封装这些函数,同时第一个成员包含struct hw_device_t (继承struct hw_device_t ),这样可以通过返回给上层c库的struct hw_device_t 地址访问自定义的结构体led_device_t(struct hw_device_t 指针强转成led_device_t指针,结构体第一个变量的地址就是结构体的地址),进而调用led_device_t中的ioctl, read, wirte函数。
以上是hal层架构所需要实现的结构体以及操作方法介绍,具体hal层的代码实现下篇进行说明。
1068

被折叠的 条评论
为什么被折叠?



