程序员的知识教程库

网站首页 > 教程分享 正文

Android HAL层入門(android hal层开发)

henian88 2024-10-28 15:49:28 教程分享 2 ℃ 0 评论

笔者从事的是Android上层应用开发,对于HAL层平时工作接触不多,想来整理一下加深一下印象

本文不会讨论具体的实现,只是对HAL的概念做一个简单的梳理,适合Android上层应用开发人员。

HAL诞生原因

HAL层中文翻译是硬件抽象层,顾名思义是对Linux内核驱动程序的封装,向上提供接口,屏蔽低层的实现细节。硬件抽象层运行在用户空间,Linux内核驱动程序运行在内核空间。这样设计的原因是什么呢?

Linux内核源码版权遵循GNU License,必须公开源码。而Android源码版权遵循Apache License,可以不公开源码。为了维护手机厂商的利益,谷歌把对硬件的支持分成硬件抽象层和内核驱动层,内核驱动层只提供简单的访问硬件逻辑,例如读写硬件寄存器的通道,至于从硬件中读到了什么值或者写了什么值到硬件中的逻辑,都放在硬件抽象层中去了。这样的话,内核空间的驱动程序对硬件的支持其实是不完整的,即使把Linux内核移植到其它机器上去时,由于缺乏硬件抽象层的支持,硬件就完全不能用了,这样的话手机厂商公开kernel的源码也不必担心商业秘密外露,这也是为什么说Android是开放系统而不是开源系统的原因。

HAL层处于Android系统层级的位置

应用层(Application)->框架层(Framework)->外部库及Android运行时(External Libraries & Android Runtime)->硬件抽象层(HAL)->Linux内核(Linux Kernel)

从图中可以看出来,HAL从上而下涉及到android系统的硬件驱动层、运行时库及框架层等/

HAL层采用模块的形式来管理硬件的访问接口。每个硬件抽象模块都对应一个动态链接库。这些动态链接库的命名要满足一定的规范。

HAL模块的加载

前面讲过每个硬件抽象模块都对应一个动态链接库,这个是厂商提供的,存放在默认的路径下;HAL在需要的时候会去匹配和加载动态链接库。那么HAL是如何找到某个硬件模块对应的正确的共享库呢?

首先,每个模块对应的动态链接库的名字是遵循HAL的命名规范的。以GPS模块为例,典型的共享库名字如下:gps.mt6753.so

[gps]:是硬件抽象模块唯一的id编号

[mt6753]:是平台名,从属性系统中获取。

HAL加载抽象模块的时候,会按照顺序从以下4个属性名称中获取variant的值:

ro.hardware

ro.product.board

ro.board.platform

ro.arch

若值存在,则使用该值作为variant的值,否则就使用xxx.default.so作为默认的抽象模块文件来加载硬件抽象层

同样共享库的存放路径也是有规范的,必须放在/system/lib/hw 或者 /vendor/lib/hw 这2个路径下的其中一个。HAL在加载所需的共享库的时候会先去vendor下寻找,找不到的话再去/system/lib/hw下找。

(模块文件名字规范以及路径规范定义均来自于hardware/libhardware/hardware.c这支文件)

在Android下访问HAL大致有以下两种方式:

(1)Android的app可以直接通过service调用.so格式的jni

(2)经过Manager调用service

上面两种方法应该说是各有优缺点,第一种方法简单高效,但不正规。第二种方法实现起来比较复杂,但更符合目前的Android框架。第二种方法中,LegManager和LedService(java)在两个进程中,需要通过进程通讯的方式来通讯。在现在的android框架中,这两种方式都存在,比如对于lights,是直接透过LightsService调用JNI,而对于sensor,中间则是通过SensorsManager来调用JNI的。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表