Android探索与驱动开发学与思(9)

为什么要在Android中加入HAL

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

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

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

Android HAL架构

旧架构:                                新架构:                                     

然后就要编写一个支持HAL的Linux驱动程序,其步骤为:

第一步:编写Linux驱动

第二步:编写HAL Library

第三步:编写Service Library

最后基于HAL的LED驱动去掉了所有与读写寄存器规则相关的代码,只保留了创建设备文件已经与寄存器交互的代码LED驱动利用了设备文件的read和write函数来读写指定的寄存器。基本原理是只从指定寄存器读取或写入5个字节。第1个字节用于指定读写的动作以及寄存器。后4个字节是读写

编写诵点LED驱动的HAL模块;

实际上:HAL模块也是普通的linux共享库(.so文件),只不过HAL模块可以被Android系统自动装载而不是开发人员自己去装载.so文件。.

Linux驱动的 init 函数与main函数的性质类似。在装载Linux驱动的过程中系统会调用init 函数.

既然HAL模块也可以被Android系统自动调用,那个自然也拥有类似main init函数的接口。只不过这个接口不是函数, 而是一个固定名称的结构体变量HAL_MODULE_INFO_SYM.

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

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

2 :编写 HAL模块的 open 函数:

open 函数是 HAL 模块的入口点。该函数主要做如下 3 项工作:初始化 hw device_t 的子结构体。打开设备文件。初始化寄存器。

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

4 步: 定义 HAL_MODULE_INFO_SYM 变量

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

6:编写控制 LED 的函数

总结:在LED的驱动中,我们加入HAL使用程序不需要关心Linux驱动和设备文件的交互方式。编写一款支持HALlinux驱动程序的步骤:

第一步:编写linux驱动

第二步:编写 HAL Library

第三步:编写Service library

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

第一步:定义结构体和宏

        描述HAL模块的hw-module-t结构体

        描述HAL设备的HW-device-t结构体

        描述模块入口函数的hw-module-methods-t结构体

第二步:编写HAL模块的open函数

第三步:定义hw-module-methods-t结构体变量

第四步:定义HAL-module-info-sym变量

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

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

本章中我学习到了:

1.在Android.系统中使用 Linux驱动有两种方式。 一种是通过传统的方式直接与Linux驱动交互。

2.编写宏时要了解如下俩个知识点:可变参数的宏、Do{.....}while(0)

原文地址:https://www.cnblogs.com/wstone/p/5650998.html