第九章

第九章

HAL ( Hardware Abstraction Layer,硬件抽象层 )是建立在Linux 驱动之上的一套程序库。这套程序库并不属于Linux 内核, 而是属于Linux 内核层之上的应用层。

统一硬件的调用接口。由于HAL 有标准的调用接口,所以可以利用HAL屏蔽Linux 驱动复杂、不统一的接口。解决了GPL版权问题。由于Linux 内核基于GPL协议,而Android 基于Apache Licence 2 .0 协议。因此Google 玩了个“穿越”,将原本位于Linux驱动中的敏感代码向上移了一个层次这样这些敏感代码就摆脱了GPL 协议的束缚。那些不想开源的Linux驱动作者也就没必要开源了。

针对一些特殊的要求。对于有些硬件,可能需要访问一些用户空间的资源,或在内核空间不方便完成的工作以及特殊需求。在这种情况下,可以利用位于用户空间的HAL 代码来辅助Linux驱动完成一些工作。HAL架构比较简单,其基本原理就是在Android 系统中使用程序库(.so文件)调用位于内核空间的Linux 驱动(一般通过设备文件访问)。然后沟Android 面用程序(APK 文件)可以通过NDK程序访问HAL中的程序,或直接在Android 应用程序中访问HAL中的程序库(直接使用Java代码访问)编写支持HAL 的Linux 驱动程序的步骤;

第1 步: 编写Linux 驱动;

第2 步:编写HAL Library;

第3 步:编写Service Library

在Android.系统中使用Linux 驱动有两种方式。

一种就是通过传统的方式直接与Lmux 驱动交互。

另外一种是Android特有的,就是通过HAL 模块。

HAL 模块本质上就是通过Linux 共享库(.so)与Linux驱动交互,然后应用程序再访问Linux共享库。

HAL是建立在Linux驱动之上的的程序库,他是一个应用层,它的作用保护内部私有。有一种是位于Android层次的系统运行库层,Linux中只保留与寄存器相互的代码,通过HAL进行数据的传递。

为Android加入HAL的主要目的是:

统一硬件的调用接口。

解决GPL版权问题。

资源等特殊要求。

这个是新版的Android HAL架构,与原来的区别增加了新的代码入口。他只需要用ID来定位,用Service程序库。

在LED实验中可以加入HAL,他不需要关心他们之间的交互方式,像普通的API就可以交互,将所有的逻辑从LED驱动移动到HAL模块,而先前的LED驱动只保留读写寄存器的功能。

编写一款支持HAL的Linux驱动程序的步骤:

编写Linux驱动

编写HAL Library

编写Service Library

新改进了以后的LED的build.sh的脚本可以支持多个设备,处理多个设备,而不需要每一次都去关闭Android模拟器。

在测试读写寄存器时,因为是LED接受的不是字符串,而是字节类型的数据,因此以字节形式输入在进行测试即可。

编写调用LED驱动的HAL模块

HAL规定不能直接使用hw_module_t结构体,因此在外部还要加一层结构体,要使用led函数指针,定义打开和关闭的指针。设置文件的句柄,控制LED开关的通用函数,根据它的开关输出响应的日志信息,存储发送被设置文件或者从设备接收的数据,设置第一个字节为读取GPMDAT寄存器数据的状态,读取数据,保留有关数据。使用switch…case语句调用led;打开指定的led,led_off控制led,关闭设备函数;在初始化寄存器,打开设备为其分配内存空间,先清零,在设置。

总结它的原理和步骤:

定义结构体和宏定义

编写HAL模块的open函数

定义he_module_methods结构体变量

定义HAL_MODULE_INFO_SYM变量

编写HAL模块的close函数

编写控制LED的函数

在Android系统中使用Linux驱动有两种方式:传统方式直接与Linux驱动交互,例如读取文件;还有就是HAL:本质上就是通过Linux共享库(.so)与Linux驱动交互,然后再访问Linux共享库。

posted @ 2016-06-30 23:10  安之若素2013  阅读(116)  评论(0编辑  收藏  举报