[RK3399][Android7.1] 传感器 HAL 层的设计与实现

江枫思渺然 提交于 2020-01-30 15:14:24
平台 内核版本 安卓版本
RK3399 Linux4.4 Android7.1

传感器 HAL 层的设计与实现

Linux 驱动一般由访问硬件代码和业务逻辑代码两部分组成。Linux 内核提供了 标准的读写硬件的方法,只需要调用 Linux提供的标准函数即可。
在这里插入图片描述
Linux驱动的业务逻辑对厂商或个人来说是保密的。例如,缓冲区的设置等。GoogleAndroid 体系中添加一个 HAL 层的目的是为了满足不想开源的个人或者厂商的要求,该层位于系统库层和 Linux 内核层之间。对于想开源的 Linux 驱动个人或者厂商,既可 以将驱动业务逻辑放在 HAL 层,也可以放在驱动程序中。而对于不想公开 Linux 驱动代码的个人或者厂商,Linux 驱动只是一个传递数据给相关设备的角色。即 Linux 驱动中只有操作设备寄存器的代码,而没有任何的业务代码。HAL 层统一了硬件的 调用接口,HAL 层的编写需要遵循一定的规范。HAL 层的框架如下图所示。 Android 应用程序通过 NDK 访问 HAL 的系统库,或者直接访问 HAL 中程序库,最后通过程序库访问驱动程序为其提供的设备节点实现,设备节点为程序库提供了操 作接口。
在这里插入图片描述

chat将设计并实现重力传感器驱动硬件抽象层模块部分。重力传感器的业务逻 辑放在硬件抽象层。实际上,硬件抽象层也是以 Linux 系统库的形式提供的,HAL 层的库可以被自动加载,而不是像 C 程序中需要在运行时加载。当需要硬件抽象层 程序库时,通过 ID 号加载相应的程序库。硬件抽象层的工作流程如下图示。 应用层传递传感器类型值到硬件抽象层,硬件抽象层完成对应传感器的配置和初始化,最后判断硬件抽象层的命令是打开或者是关闭,如果是打开传感器,则上报传感器的数据,最后判断传感器是否处于动态,如果处于动态则再次上报传感器的数 据,在上报传感器数据的时候会有一定时间的延时。如果关闭传感器,则直接结束。在传感器不处于动态时,也会直接结束读取流程。

Android 框架相关的数据结构如图:
在这里插入图片描述
结构体分为三个部分。

1. hw_module_t
hw_module_tAndroid 框架定义的结构体,按照 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的子结构。除了初始化一些必要的变量外, 还需要初始化操作传感器的一些方法(本文中的 closeactivatesetDelaypoll

适配不同传感器的类如下图:
在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!