第九章

HAL ( Hardware Abstraction Layer,硬件抽象层,〉是建立在Linux 驱动之上的一套程序库。这套程序库并不属于Linux 内核, 而是属于Linux 内核层之上的应用层。Google 为Android 增加HAL 的主要目的除了尽量避免应用程序直接访问Linux 驱动外,还有一个重要原因,那就是保护“私人财产”。

在传统的、Linux.系统中Linux驱动一般有两种类型的代码:访问硬件寄存器的代码和业务逻辑代码。对于访问硬件寄存器的代码,并没有什么秘密可言,因为这都是调用的Linux 内核的标准函数〈如ioread32 、iowrite32 等)进行的标准操作. 而Linux 驱动的业务逻辑部分对击有些企业或个人并不想将源代码公开。

Google 为了满足这些不想开源的Linux 驱动作者的要求工在android层次结构中的系统运行库层增加了一个HAL。

Google 为android加入HAL主要有如下的目的:

统一硬件的调用接口。由于HAL 有标准的调用接口,所以可以利用HAL:屏蔽Linux 驱动复杂,不统一的接口。

解决了GPL(版权问题。由于Linux 内核基于GPL协议,而Android 基于Apache Licence 2 .0 协议.因此Google 玩了个“穿越”将原本位于Linux驱动中的敏感代码向上移了一个层次。这样这些敏感代码就摆脱了GPL 协议的束缚,那些不想开源的Linux驱动作者也就没必要开源了。

针对一些特殊的要求。对于有些硬件,可能需要访问→些用户空间的资源,或在内核空间不方便完成的工作以及特殊需求。在这种情况下,可以利用位于用户空间的HAL 代码来辅助Linux驱动完成一些工作。

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

第1 步编写Linux 驱动

第2 步:编写HAL Library

第3 步:编写Service Library

编写HAL 模块的步骤和原理如下。

第l步:定义结构体和宏

编写HAL 模块需要使用到3 个非常重要的结构体( hw_module_t 、hw_device_t 和 hw _ module_ methodle _t),在第l 步需要定义两个新的结构体,这两个结构体的第l 个变量的数据类型必须是hw_module_t 和bw_device_t。除此之外, 还需要为HAL 模块定义一个ID. 实际上在这l步就是编写leds hal.h 头文件的代码。

第2 步L 编写HAL 模块的open 函数

 open 函数是HAL 模块的入口点。该函数主要做如下3 项工作

初始化hw device t 的子结构体。

打开设备文件。

初始化寄存器。

第3 步:定义hw_module_methods_ t 结构体变量

第4 步: 定义HAL_MODULE_INFO_SYM 变量

第5 步:编写HAL 模块的close 函数

第6 步 :编写控制LED 的函数

android.系统中使用Linux 驱动有两种方式。一种是通过传统的方式直接与Linux 驱动交互。另外一种是Android特有的,就是通过HAL模块。HAL模块本质上就是通过Linux 共享库(.so)与Linux驱动交互,然后应用程序再访问Linux.共享库。早期的HAL模块由应用程序直接按访问Linux共享库的方式调用。而高版本的Android 系统为HAL增加了Stub ;换句话说还就是为每一个HAL共享库指定一个ID,再利用这个ID 配合一定的规则找到Linux共享库,这样Linux 共享库更换文件名,移动位置都很方便(因为HAL 共享库的路径和文件名都不是定死的), Google 也建议使用Stub 的方式编写HAL 模块。

 

 

原文地址:https://www.cnblogs.com/j4120/p/5639966.html