Android系统硬件抽象层(HAL)原理
在android开发过程中,我们经常看到HAL这个概念,这就android的硬件抽象层的(Hardwaere Abstraction Layer)缩写,它是Goolge应某些厂商不希望公开源码所添加的一个适配层,能以封闭源码的方式提供硬件驱动模块,目的就是把android framework层和linux kernel层隔离开来,使android系统不至于过度的依赖linux kernel层的实现,也就是说android framework可以不考虑linux kernel如何实现的情况下独立开发
Android HAL层位于android系统和linuxkernel之间,如下图所示:
Android java应用层(app) |
Android java框架层(framework)
|
Android本地框架层(native)
|
硬件抽象层(HAL) |
硬件抽象层实现
|
驱动层(linuxkernel) |
在移植系统或添加新的模块时都需要android的HAL层进行修改或者添加实现,android的HAL层在android的源码位置:
hardware/libhardware/
hardware/libhardware_legacy/
hardware/xxxx/
有的还位与其他位置。AndroidHAL层的实现方式有几种方式:
1,hardware模块的方式
2,C/C++继承方式
3,直接调用驱动接口方式
4,直接接口方式
下面我从这几种方式作一下简单的分析
《一》首先分析一下hardware模块方式的实现,这种方式是一种不依赖编译时绑定的实现,它可以动态的加载硬件抽象层就是说可以通过ID来动态的打开(dlopen)一个硬件模块,然后找到符号(dlsym)进行调用。
Android native framework-(根据不同的ID)àlibhardware.so-(dlopen)->/system/hw/*.so->drivers
接下来分析一下HAL这个抽象的框架,具体的代码在源码的
hardware/libhardware/hardware.c
hardware/libhardware/include/hardware/hardware.h位置
来看看hardware.h这个头文件,我们可以发现在这个头文件中主要定义的三个结构体
struct hw_device_t
struct hw_module_t
struct hw_module_methods_t
hw_device_t:表示硬件设备,存储了各种硬件设备的公共属性和方法,如果需要移植或者添加新硬件,那么都需要使用该结构进行注册,其中的tag必须初始化。结构体hw_module_t在进行加载的时候用于判断属于哪个module。
typedef struct hw_device_t {
uint32_t tag; //tag需要被初始化为HARDWARE_DEV
uint32_t version; //hw_device_t的版本号
struct hw_module_t* module; //引用这个设备属于的硬件模块
uint32_t reserved[12]; //填充保留字节
int (*close)(struct hw_device_t* device); //关闭设备
} hw_device_t;
typedef struct hw_module_t {
uint32_t tag; //tag需要被初始化为HARDWARE_MODULE_TAG
uint16_t version_major; //主版本号
uint16_t version_minor; //次版本号
const char *id; //模块标识符
const char *name; //模块名称
const char *author; //模块作者
struct hw_module_methods_t* methods; //模块方法
void* dso; //模块的dso
uint32_t reserved[32-7]; //填充字节,为以后使用
} hw_module_t;
hw_module_methods_t:该结构体用于定义操作设备的各种方法operations,这里只定义一个open方法。如果要执行打开设备等操作可以在JNI层使用“module->methods->open(module,LED_HARDWARE_MODULE_ID,(struct hw_device_t** )device);”
typedef struct hw_module_methods_t {
int (*open)(const struct hw_module_t* module, const char* id,struct hw_device_t** device); //打开设备的方法
} hw_module_methods_t;
其中struct hw_device_t表示一个硬件设备
Struct hw_module_t表示硬件模块的格式
Sttruct hw_module_methods_t表示模块的方法
(三个结构体可以看到hw_device_t包含hw_module_t, hw_module_t保含hw_module_methods_t,这是面向对象的思想的体现,呵呵呵)
在加载某个模块的时候会调用hw_get_module这个方法,这个方法就可以获得相应的HAL,代码如下所示:
int hw_get_module(const char *id, const struct hw_module_t **module)
{
int status;
int i;
const struct hw_module_t *hmi = NULL;
char prop[PATH_MAX];
char path[PATH_MAX];
/*
* Here we rely on the fact that calling dlopen multiple times on
* the same .so will simply increment a refcount (and not load
* a new copy of the library).
* We also assume that dlopen() is thread-safe.
*/
/* Loop through the configuration variants looking for a module */
for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {
if (i < HAL_VARIANT_KEYS_COUNT) {
//获取ro.hardware/ro.product.board/ro.board.platform/ro.arch等key的值。
if (property_get(variant_keys[i], prop, NULL) == 0) {
continue;
}
snprintf(path, sizeof(path), "%s/%s.%s.so",
HAL_LIBRARY_PATH, id, prop);
} else { //如果没有动态加载的动态链接库,需要加载默认的模块
snprintf(path, sizeof(path), "%s/%s.default.so",
HAL_LIBRARY_PATH, id);
}
if (access(path, R_OK)) {
continue;
}
/* we found a library matching this id/variant */
break;
}
status = -ENOENT;
if (i < HAL_VARIANT_KEYS_COUNT+1) {
/* load the module, if this fails, we're doomed, and we should not try
* to load a different variant. */
status = load(id, path, module);//调用load()函数打开动态链接库
}
return status;
}
在该方法中可以看出,android系统通过系统的属性查找硬件,根据ID和找到的路径加载相应的.so库文件在hw_get_module中有一个重要的方法
Load
static int load(const char *id,const char *path,const struct hw_module_t **pHmi)
{
int status;
void *handle;
struct hw_module_t *hmi;
/*
* load the symbols resolving undefined symbols before
* dlopen returns. Since RTLD_GLOBAL is not or'd in with
* RTLD_NOW the external symbols will not be global
*/
handle = dlopen(path, RTLD_NOW);//打开动态库
if (handle == NULL) {
char const *err_str = dlerror();
LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
status = -EINVAL;
goto done;
}
/* 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”这个导出符号,并获取其地址
if (hmi == NULL) {
LOGE("load: couldn't find symbol %s", sym);
status = -EINVAL;
goto done;
}
/* Check that the id matches */
if (strcmp(id, hmi->id) != 0) {
LOGE("load: id=%s != hmi->id=%s", id, hmi->id);
status = -EINVAL;
goto done;
}
hmi->dso = handle;
/* success */
status = 0;
done:
if (status != 0) {
hmi = NULL;
if (handle != NULL) {
dlclose(handle);
handle = NULL;
}
} else {
LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
id, path, *pHmi, handle);
}
*pHmi = hmi;
return status;
}
从上可以简单得出硬件的具体调用过程,大致是这样的
首先通过ID找到硬件模块
然后硬件模块得到methods打开设备(hw_device_t)
再后调用设备的各个方法
最后使用完毕后通过设备的close方法关闭
《二》C/C++继承方式
这种方式最典型的有CAMERA和AUDIO两个系统,这种方式是在android系统中定义了C++接口如camera中的CameraHardwareInterface.h,其中定义了操作camera的各个方法,这些方法有具体的实现者来实现,一般情况下硬件抽象层会被编译成动态或静态库,由本地框架调用或链接,具体在camera中分析
后两种方式在分析具体模块时再做具体分析
HAL层的原理就简单介绍到这里,接下来我会详细分析不同的具体的模块的实现
相关推荐
Android硬件抽象层从开发到使用有一个清晰的...这个PPT通过一个具体的实例来分析Android硬件抽象层的开发、测试和使用,它在帮助我们理解Android系统架构的同时,也能教会我们如何在Android源代码环境中开发C/C++代码。
Android硬件抽象层(HAL)模块编写JNI方法
Android GPS HAL driver porting 笔记,详细的描述了Android GPS 硬件抽象层的基本架构
理解和使用Linux的硬件抽象层HAL 理解和使用Linux的硬件抽象层HAL
Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序
Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序
STM Android 传感器硬件抽象层 ( HAL ) 为 STM 传感器定义了一个标准接口,允许 Android 不知道较低级别的驱动程序实现。HAL 库被打包成模块 (.so) 文件并由 Android 系统在适当的时候加载。有关详细信息,请参阅...
系统软件模块与硬件之间的接口是嵌入式实时系统的主要特征,是系统设计过程中的必需环节,也是影响嵌入式系统应用前景的关键问题之一。硬件抽象层(Hardware Abstraction Layer,HAL)的引入可有效解决这一问题。
硬件抽象层( HAL), 应用库( CUL) zigbee的相关库的建立概念
该系统的优势在于,通过将驱动程序编写为驱动程序之上的通用库,embedded-hal作者可以支持任意数量的目标平台(例如 Cortex-M 微控制器、AVR 微控制器、嵌入式 Linux 等)。 应用程序开发人员的优势在于,通过采用...
基于硬件抽象层HAL的NiosⅡ嵌入式处理器系统设备管理模式研究.pdf
android系统开发--HAL层开发基础
HAL是将硬件平台与应用软件隔离开来的软件层次,通过硬件抽象技术实现硬件相关和硬件无关两部分程序代码的隔离,为应用软件提供一个没有硬件特性的接口。硬件抽象层的引入不仅是系统体系结构设计方法的改进,更直接...
随着计算机软硬件技术的快速发展,出现了越来越多的便携设备和智能设备。这些设备中通常包含控制用的CPU和相应的操作系统;这类特
Android系统开发led灯hal程序,hal程序又名硬件抽象层,是android系统开发中很重要的一层。
这篇总结是通过学习android源码情景分析得来的,是学习第二章HAL层的心得笔记,我学的比较浅,自己总结的知识,从硬件驱动到硬件抽象层到硬件服务到应用等的介绍
本文主要介绍在Android 的硬件抽象层,学习Android 硬件抽象层(HAL)对理解整个Android都是有非常大的作用,有兴趣的小伙伴可以参考下
在Ubuntu Android简单介绍硬件抽象层(HAL)一文中,我们简要介绍了在Android系统为为硬件编写驱动程序的方法。简单来说,硬件驱动程序一方面分布在Linux内核中,另一方面分布在用户空间的硬件抽象层中。接着Ubuntu ...
Audio系统的移植,Audio硬件抽象层的实现方法 ALSA Audio HAL实现 8 Android的Video 输入输出系统 8.1 Video输入输出系统的综述 视频输入输出系统架构和代码路径 8.2 Overlay系统 视频输出系统的结构 8.3...
在android的HAL层用C语言编写可执行测试程序来模拟andoird的HAL层来与RIL进行socket通信为例来介绍电话模块以外的其他模块如何向Modem发送AT命令。