2015武大-终端-第二天上午3android hal技术_第1页
2015武大-终端-第二天上午3android hal技术_第2页
2015武大-终端-第二天上午3android hal技术_第3页
2015武大-终端-第二天上午3android hal技术_第4页
2015武大-终端-第二天上午3android hal技术_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

武汉大学谷歌联合实验室Android

HAL技术内容提纲

}

HAL

概念}

HAL

简介及现状分析}

HAL内容}

新旧HAL对比分析}

实际HAL_legacy和HAL举例(cont.)}

Android

HAL

架构}

HAL使用方法}

Copybit

HALHAL

概念}

Android

HAL(Hardware

Abstract

Layer硬件抽象层)是Google因应厂商「希望不公开源码」的要求下,所推出的新观念,其架构如下图。HAL存在的原因}

1、

并不是所有的硬件设备都有标准的linux

kerne

l的接口。}

2、

Kernel

driver涉及到GPL的版权。某些设备

制造商并不原因公开硬件驱动,所以才去HAL

方式绕过GPL。}

3、

针对某些硬件,Android有一些特殊的需求。HAL

简介及现状分析}

现有HAL架构由Patrick

Brady

(Google)

在2008

Google

I/O演讲中提出,从上面架构图我们知道

,HAL

的目的是为了把

Android

framework

Linux

kernel

完整「隔开」。让

Android

不至

过度依赖

Linux

kernel,有点「kernel

independent」的意思。}

因为各厂商需要开发不开源代码的驱动程序模

组要求下所规划的架构与概念要求下所規劃的

架構與觀念}

但是目前的HAL架构抽象程度还不足}

需要变动框架来整合HAL模组HAL内容}

}

HAL

主要的实作储存于以下目录:

1.

libhardware_legacy/

-

旧的架构、采取链接库模块的观念进行

2.

libhardware/

-

新架构、调整为

HAL

stub

的观念

3.

ril/

-

Radio

Interface

Layer

4.msm7k

QUAL平台相关主要包含一下一些模块:

Gps

Vibrator

Wifi

Uevent

Copybit

Audio

Camera

Lights

Ril

Overlay

……旧的HAL

架构(libhardware_legacy)}

}

}

libhardware_legacy

作法,是传统的「module」方式,也就是将

*.so

文件当做「shared

library」来使用,在runtime(JNI

部份)以

direct

function

call

使用

HAL

module。通过直接函数调用的方式,来操作驱动程序。当然,应用程序也可以不需要通过

JNI

的方式进行,直接加载

*.so

檔(dlopen)的做法调用*.so

里的符号(symbol)也是一种方式。总而言之是没有经过封装,上层可以直接操作硬件。新的HAL

架构(libhardware)}

现在的

libhardware

架构,就有「stub」的味道了。HAL

stub是一种代理人(proxy)的概念,stub

虽然仍是以

*.so檔的形式存在,但

HAL

已经将

*.so

档隐藏起来了。Stub

HAL「提供」操作函数(operations),而

runtime

则是向

HAL

取得特定模块(stub)的

operations,再

callback

这些操作函数。这种以

indirect

function

call

的架构,让HAL

stub

变成是一种「包含」关系,即

HAL

里包含了许许多多的

stub(代理人)。Runtime只要说明「类型」,即

module

ID,就可以取得操作函数。对于目前的HAL,可以认为Android定义了HAL层结构框架,通过几个接口访问硬件从而统一了调用方式。JNI

在HAL架构中的位置目前HAL的解决方案}

}

旧的(legeacy)HAL

在hardware目录的libhardware_legacy

我们称为HAL

module新的HAL

在hardware的libhardware下

称之为HAL

stubHAL_legacy和HAL的对比}

}

HAL_legacy:旧式的HAL是一个模块,采用共享库形式,在编译时会调用到。由于采用functioncall形式调用,因此可被多个进程使用,但会被mapping到多个进程空间中,造成浪费,同时需要考虑代码能否安全重入的问题(thread

safe)。HAL:新式的HAL采用HAL

module和HAL

stub结合形式,HAL

stub不是一个share

library,编译时上层只拥有访问HAL

stub的函数指针,并不需要HAL

stub。上层通过HAL

module提供的统一接口获取并操作HAL

stub,so文件只会被mapping到一个进程,也不存在重复mapping和重入问题。HAL_legacy和HAL的对比(cont.)}

Module角色是被调用在Android架构里面仅作为程序库(library)用途}

StubStub又称为代理人(proxy)扮演操作供应者的概念(operations

provider)实际HAL_legacy和HAL举例实际HAL_legacy和HAL举例(cont.)}

com_android_server_SensorService.cppstatic

jintandroid_init(JNIEnv

*env,

jclass

clazz){

sensors_module_t*

module;

if

(hw_get_module(SENSORS_HARDWARE_MODULE_ID,

(const

hw_module_t**)&module)

==

0)

{if

(sensors_control_open(&module->common,

&sSensorDevice)

==

0){

const

struct

sensor_t*

list;

int

count

=

module->get_sensors_list(module,

&list);

return

count;

}

}

return

0;}实际HAL_legacy和HAL举例(cont.)}

sensors.cstruct

sensors_module_t

HAL_MODULE_INFO_SYM

=

{mon={.tag

=

HARDWARE_MODULE_TAG,.version_major

=

1,.version_minor

=

0,.id

=

SENSORS_HARDWARE_MODULE_ID,.name

=

"AK8976A

SENSORS

Module",.author

=

"The

Android

Open

Source

Project",.methods

=

&sensors_module_methods,},.get_sensors_list

=

sensors__get_sensors_list};实际HAL_legacy和HAL举例(cont.)}

com_android_server_VibratorService.cpp

static

void

vibratorOn(JNIEnv

*env,

jobject

clazz,

jlong

timeout_ms)

{

//

LOGI("vibratorOn\n");

vibrator_on(timeout_ms);

}

static

void

vibratorOff(JNIEnv

*env,

jobject

clazz)

{

//

LOGI("vibratorOff\n");

vibrator_off();

}

static

JNINativeMethod

method_table[]

=

{

{

"vibratorOn",

"(J)V",

(void*)vibratorOn

},

{

"vibratorOff",

"()V",

(void*)vibratorOff

}

};

int

register_android_server_VibratorService(JNIEnv

*env)

{

return

jniRegisterNativeMethods(env,

"com/android/server/VibratorService",

method_table,

NELEM(method_table));

}实际HAL_legacy和HAL举例(cont.)}

hardware/libhardware_legacy.git]

/

vibrator

/

vibrator.c#define

THE_DEVICE

"/sys/class/timed_output/vibrator

/enable"static

int

sendit(int

timeout_ms){

int

nwr,

ret,

fd;

char

value[20];#ifdefQEMU_HARDWARE if(qemu_check()){ returnmand("vibrator:%d", timeout_ms); }#endif fd=open(THE_DEVICE,O_RDWR); if(fd<0) returnerrno; nwr=sprintf(value,"%d\n",timeout_ms); ret=write(fd,value,nwr); close(fd); return(ret==nwr)?0:-1;}int

vibrator_on(int

timeout_ms){

/*

constant

on,

up

to

maximum

allowed

time

*/

return

sendit(timeout_ms);}int

vibrator_off(){return

sendit(0);}HAL

Stub

简介}

Hal

Stub目前没有严格的标准Interface

由各厂商决定实现细节自己决定}

以products

tree方式进行维护易于管理便于以后升级HAL

Stub

简介(cont.)}

}

}

Hal

Stub

就是

Android硬件控制模组$OUT/system/lib/hw/*.so用C进行继承struct

led_module_t

{struct

hw_module_t

common;/*

Place

attributes

here.

*//*

Place

methods

here.

*/};!!

!!!!!!!!!!!!!Android

HAL

架构Android

service介绍Android

service功能}

操作控制实际的硬件模块PowerMangerServiceSensorServiceHardwareServiceWifiService。。。。HAL

module架构}

}

}

HAL

moudle主要分为三个结构:struct

hw_module_t;struct

hw_module_methods_t;struct

hw_device_t;定义在hardware.h文件里面他们的继承关系如右图:HAL使用方法}

}

}

1.

Native

code通过hw_get_module调用获取HAL

stub:hw_get_module

(LED_HARDWARE_MODULE_ID,

(const

hw_module_t**)&module)2.

通过继承hw_module_methods_t的callback来open设备:module->methods->open(module,

LED_HARDWARE_MODULE_ID,

(struct

hw_device_t**)device);3.

通过继承hw_device_t的callback来控制设备:sLedDevice->set_on(sLedDevice,

led);sLedDevice->set_off(sLedDevice,

led);HAL

Module

获取}

}

}

hardware.cint

hw_get_module(const

char

*id,

const

struct

hw_module_t

**module)1.

查找module

patch

if

(i

<

HAL_VARIANT_KEYS_COUNT)

{

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);

}HAL

Module

获取(cont.)}

}

2.

载入

so

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);

}3.

Open

so

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;

}HAL

Module

获取(cont.)}

4.

获取symbol/*

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);

if

(hmi

==

NULL)

{

LOGE("load:

couldn't

find

symbol

%s",

sym);

status

=

-EINVAL;

goto

done;

}HAL

Module

获取(cont.)}

hardware.h

#define

HAL_MODULE_INFO_SYM

HMI

/**

*

Name

of

the

hal_module_info

as

a

string

*/

#define

HAL_MODULE_INFO_SYM_AS_STR

"HMI"API

&

HAL

stub开发流程}

1.

开发

LedService

API}

2.

设计

LED

Stub

LedService

整合}

3.

开发设计测试程序}

4.

后续优化

(Refinement)测试code整体框架测试code整体框架(cont.)API

样例程序public

class

LedClient

extends

Activity

{@Overridepublic

void

onCreate(Bundle

savedInstanceState)

{super.onCreate(savedInstanceState);//

Call

an

API

on

the

library.LedService

ls

=

new

LedService();ls.setOn(1);TextView

tv

=

new

TextView(this);tv.setText("LED

0

is

on.");setContentView(tv);

}}HAL

stub移植步骤}

}

我们以一个简单的LED控制为例注意:目前Android使用liblight进行led,lcd背光等控制。HAL

stub移植步骤(cont.)}

led_moduel_t

定义初始化Supporting

API}

led_control_device_t

定义控制

Supporting

APIHAL

stub

定义相关结构体}

(1)定义自己的HAL结构体,编写头文件led.h,

hardware/hardware.hstruct

led_module_t

{

struct

hw_module_t

common;};struct

led_control_device_t

{

struct

hw_device_t

common;int

fd;/*

file

descriptor

of

LED

device

*/

/*

supporting

control

APIs

go

here

*/

int

(*set_on)(struct

led_control_device_t

*dev,

int32_t

led);

int

(*set_off)(struct

led_control_device_t

*dev,

int32_t

led);};HAL

stub

supporting

API}

控制的

supporting

API

HAL

stub

open

callback

里提供}

HAL

stub

open

operation

必需提供supporting

API

runtimeCallback

Open

interface}

Callback

Open

interface完成功能实现和HAL

stub注册}

}

1.

led_module_methods继承hw_module_methods_t,实现open的callback

struct

hw_module_methods_t

led_module_methods

=

{

open:

led_device_open

};2.

用HAL_MODULE_INFO_SYM实例led_module_t,这个名称不可修改tag:需要制定为

HARDWARE_MODULE_TAGid:指定为

HAL

Stub

module

IDmethods:struct

hw_module_methods_t,为

HAL

所定义的「method」

const

struct

led_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.

*/};完成功能实现和HAL

stub注册(cont.)}

3.

open是一个必须实现的callback

API,负责申请结构体空间,填充信息,注册具体操作API接口,打开Linux驱动。由于存在多重继承关系,只需对子结构体hw_device_t对象申请空间即可。

int

led_device_open(const

struct

hw_module_t*

module,

const

char*

name,

struct

hw_device_t**

device)

{

struct

led_control_device_t

*dev;

dev

=

(struct

led_control_device_t

*)malloc(sizeof(*dev));

memset(dev,

0,

sizeof(*dev));

dev->common.tag

=

HARDWARE_DEVICE_TAG;

dev->common.version

=

0;

dev->common.module

=

module;

dev->common.close

=

led_device_clo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论