android底层hal开发,Android HAL 开发 (1)

最近开始看Android的HAL开发方面的东东,发现现在国内研究这个的并不多,来自台湾的Jollen可能是走在Android HAL研究的最前沿,这也和他以前专注做嵌入式linux(openmoko)的工作经历有关,毕竟Android的application开发是基于Java的,而之前Jollen做的更多的还是C/C++开发,因此选择从HAL作为进入Android的shortcut还是很明智的,我以前也主要是做linux kernel以及基于C/C++的app开发,现在转作Android,发现它的HAL比较有意思,也是可以研究的一个很好的方向。

由于自己并没有参加Jollen的HAL整合培训,不过手头有这个培训的材料,以及从 http://code.google.com/p/mokoid/ 下载了mokoid 工程的代码,花了一段时间研究了Android的HAL,也有一些心得,下面总结一下:

首先,Android的HAL是为了一些硬件提供商提出的“保护proprietary”的驱动程序而产生的东东,简而言之,就是为了避开linux kernel的GPL license的束缚。Android把控制硬件的动作都放到了user space中,而再kernel driver里面只有最简单的读写寄存器的操作,而完全去掉了各种功能性的操作(比如控制逻辑等),这些能够体现硬件特性的操作都放到了Android的HAL层,而Android是基于Aparch的license,因此硬件厂商可以只提供二进制代码,所以说Android只是一个开放的平台,并不是一个开源的平台。

然后,Android的HAL的实现需要通过JNI(Java Native Interface),JNI简单来说就是java程序可以调用C/C++写的动态链接库,这样的话,HAL可以使用C/C++语言编写,效率更高。而Android的app可以直接调用.so,也可以通过app->app_manager->service(java)->service(jni)->HAL来调用。第二种方法看上去很复杂,但是更加符合android的框架结构。我这里也着重介绍第二种方法。基本的框架如下所示:

f1e3ec2d9a3bbc9f78d8bf6c84ee27d1.png

Mokiod工程代码树如下所示:

.

|-- apps-- 测试应用程序

|   |-- LedClient-- 直接调用service控制硬件

|   |   |-- AndroidManifest.xml

|   |   `-- src

|   |       `-- com

|   |           `-- mokoid

|   |               `-- LedClient

|   |                   `-- LedClient.java

|   `-- LedTest-- 通过manager来控制硬件

|       |-- AndroidManifest.xml

|       `-- src

|           `-- com

|               `-- mokoid

|                   `-- LedTest

|                       |-- LedSystemServer.java

|                       `-- LedTest.java

|-- frameworks-- 框架代码

|   `-- base

|       |-- core

|       |   `-- java

|       |       `-- mokoid

|       |           `-- hardware

|       |               |-- ILedService.aidl-- Android Interface Definition Language 代码,提供LedService的接口

|       |               `-- LedManager.java-- LedManager实现代码

|       `-- service

|           |-- com.mokoid.server.xml

|           |-- java

|           |   `-- com

|           |       `-- mokoid

|           |           `-- server

|           |               `-- LedService.java-- LedService的java实现代码

|           `-- jni

|               `-- com_mokoid_server_LedService.cpp-- LedService的jni实现代码

|-- hardware

`-- modules

|-- include

|   `-- mokoid

|       `-- led.h

`-- led

`-- led.c-- led实际控制硬件的代码

介绍Android的HAL的时候,我打算从底层往上层介绍。

1. Kernel Driver

这里的kernel driver相对于linux真正的driver形式上是一样的,也提供open,read,write,ioctl,mmap等接口,但是,一般来说,只通过这些代码,你并不能了解到硬件的特性,比如write接口,就可以只作成往寄存器写操作,至于如何写,为什么要写,这些工作都会再HAL层进行,而一般用户是看不到这些代码的。这也是为什么linux mainstream把android的kernel踢出去的原因,因为这些driver根本无法用在其他的linux平台上。

2. HAL层

这一层就位于kernel之上的user space了,一般来说这里需要涉及的是两个结构体:hw_module_t和hw_device_t, 第一个结构体是当这个hardware stub被load的时候(hw_get_module())提供的初始化操作,比如提供stub的open(module->methods->open())操作,而第二个结构体是提供该硬件stub具有的操作硬件的接口,再jollen的mokoid工程里,主要提供打开和关闭led的操作,相关的代码如下:

led.h

structled_module_t {

structhw_module_t common;

};

structled_control_device_t {

structhw_device_t common;

/* attributes */

intfd;

/* supporting control APIs go here */

/* 打开led操作*/

int(*set_on)(structled_control_device_t *dev, int32_t led);

/* 关闭led操作 */

int(*set_off)(structled_control_device_t *dev, int32_t led);

};

led.c

/* 打开led操作 */

intled_on(structled_control_device_t *dev, int32_t led)

{

LOGI("LED Stub: set %d on.", led);

return0;

}

/* 关闭led操作 */

intled_off(structled_control_device_t *dev, int32_t led)

{

LOGI("LED Stub: set %d off.", led);

return0;

}

/* 打开led硬件时候的操作 */

staticintled_device_open(conststructhw_module_t* module,constchar* name,

structhw_device_t** device)

{

structled_control_device_t *dev;

dev = (structled_control_device_t *)malloc(sizeof(*dev));

memset(dev, 0, sizeof(*dev));

...

/* 提供给service可用的硬件操作接口 */

dev->set_on = led_on;

dev->set_off = led_off;

*device = &dev->common;

success:

return0;

}

staticstructhw_module_methods_t led_module_methods = {

open: led_device_open

};

conststructled_module_t HAL_MODULE_INFO_SYM = {

common: {

tag: HARDWARE_MODULE_TAG,

version_major: 1,

version_minor: 0,

id: LED_HARDWARE_MODULE_ID,

name: "Sample LED Stub",

author: "The Mokoid Open Source Project",

methods: &led_module_methods,

}

/* supporting APIs go here */

};

以上代码最后会被编译成动态链接库,比如libled.so放到/system/libs/hw/, 当service调用hw_get_module(hardware/libhardware/hardware.c)时候,会在/system/libs/hw/里面寻找对应的动态链接库,然后提供给service对应的操作接口。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值