平台 | 内核版本 | 安卓版本 |
---|---|---|
RK3399 | Linux4.4 | Android7.1 |
文章目录
传感器 HAL 层的设计与实现
Linux
驱动一般由访问硬件代码和业务逻辑代码两部分组成。Linux
内核提供了 标准的读写硬件的方法,只需要调用 Linux
提供的标准函数即可。
而 Linux
驱动的业务逻辑对厂商或个人来说是保密的。例如,缓冲区的设置等。Google
在 Android
体系中添加一个 HAL
层的目的是为了满足不想开源的个人或者厂商的要求,该层位于系统库层和 Linux
内核层之间。对于想开源的 Linux
驱动个人或者厂商,既可 以将驱动业务逻辑放在 HAL
层,也可以放在驱动程序中。而对于不想公开 Linux
驱动代码的个人或者厂商,Linux
驱动只是一个传递数据给相关设备的角色。即 Linux
驱动中只有操作设备寄存器的代码,而没有任何的业务代码。HAL
层统一了硬件的 调用接口,HAL
层的编写需要遵循一定的规范。HA
L 层的框架如下图所示。 Android
应用程序通过 NDK
访问 HAL
的系统库,或者直接访问 HAL
中程序库,最后通过程序库访问驱动程序为其提供的设备节点实现,设备节点为程序库提供了操 作接口。
本chat
将设计并实现重力传感器驱动硬件抽象层模块部分。重力传感器的业务逻 辑放在硬件抽象层。实际上,硬件抽象层也是以 Linux
系统库的形式提供的,HAL
层的库可以被自动加载,而不是像 C
程序中需要在运行时加载。当需要硬件抽象层 程序库时,通过 ID
号加载相应的程序库。硬件抽象层的工作流程如下图示。 应用层传递传感器类型值到硬件抽象层,硬件抽象层完成对应传感器的配置和初始化,最后判断硬件抽象层的命令是打开或者是关闭,如果是打开传感器,则上报传感器的数据,最后判断传感器是否处于动态,如果处于动态则再次上报传感器的数 据,在上报传感器数据的时候会有一定时间的延时。如果关闭传感器,则直接结束。在传感器不处于动态时,也会直接结束读取流程。
Android
框架相关的数据结构如图:
结构体分为三个部分。
1. hw_module_t
hw_module_t
是 Android
框架定义的结构体,按照 Android
硬件抽象层的定 义 , 被 sensors_module_t
封 装 , 作 为 重 力 传 感 器 模 块 的 数 据 结 构 。 而 且 hw_module_t
必须定义在结构体 sensors_module_t
的开头。这样定义主要为了扩展以 及接口的统一。任何可以被系统自动调用的程序都有一个规范,例如 main
函数。 HAL
模块可以被 Android
系统自动调用,所以它也必须要有一个固定的接口,但是它不是一个函数,而是一个结构体的变量名。该结构的设计如下:
/*初始化描述 HAL 模块信息的结构体,该结构体变量名必须为 HAL_MODULE_INFO_SYM*/
struct sensors_module_t HAL_MODULE_INFO_SYM = {
.common = {
.id = SENSORS_HARDWARE_MODULE_ID,//初始化 HAL 模块的 ID 通 过这 ID 可以找到该 HAL 模块
.methods= &sensors_module_methods,//初始化 HAL 模块的 open 函数指针
};
.get_sensors_list = sensors_get_sensors_list
};
static struct hw_module_methods_t sensors_module_methods = {
.open = open_sensors
};
2. sensors_poll_device_t
sensors_poll_device_t
是对 hw_device_t
的封装,这个结构体代表的是传感器。主要包括打开传感器,关闭传感器,以及读取传感器的数据等函数接口。
3. hw_module_methods_t
hw_module_methods_t
提供了 open_sensors
方法给上层调用。 在这个结构体中,首先使用 sensors_module_t
结构体,通过该结构体的 methods
方法找到 sensors_module_methods.open
方法,open
方法相当于 HAL
模块的入口。 调用该函数,打开设备文件,初始化 sensor_poll_context_t
结构体。
open_sensors
函数将在NDK
函数中被调用。该函数的最后一个参数被 HAL
层初始化,但是框架层调用时传入的变量类型是 sensors_poll_context_t
,这样就必须 要求 sensor_poll_device_t
必须为 sensors_poll_context_t
第一个结构体,该函数的主要的工作是初始化 sensor_poll_device_t
的子结构。除了初始化一些必要的变量外, 还需要初始化操作传感器的一些方法(本文中的 close
、activate
、setDelay
和 poll
)
适配不同传感器的类如下图:
来源:CSDN
作者:雪松研究所
链接:https://blog.csdn.net/qq_33487044/article/details/104113953