近年来,传感器技术和制造工艺的快速发展,目前市场可供开发者选择的传感器越来越多,比如:加速度传感器,陀螺仪传感器,磁力传感器,温度传感器等类型。每种传感器厂家都有各自的传感器驱动,在产品开发时就需要对不同厂家或者同一厂家的不同型号进行适配开发,就会增加开发者的开发难度。为了快速开发或者移植传感器驱动,基于HDF(Hardware Driver Foundation)驱动框架开发了Sensor(传感器)驱动模型。Sensor驱动模型主要为上层提供稳定接口能力,对驱动开发者提供开放的接口实现和抽象的配置接口能力。
传感器模型框架介绍
Sensor设备作为外接设备重要组成模块,Sensor驱动模型为上层Sensor服务系统提供稳定的Sensor基础能力接口,包括Sensor列表查询、Sensor启停、Sensor订阅及去订阅,Sensor参数配置等功能。传感器驱动模型总体框架如图1所示。图1 传感器驱动模型总体框架图 Sensor驱动抽象模型主要位于OpenHarmony软件的HAL层,其核心包括三个子模块: 1)Sensor HDI子模块:提供Sensor南向的标准接口定义和实现。 2)Sensor设备管理和通用配置子模块:提供Sensor设备管理,Sensor通用配置能力,Sensor通用数据解析能力。 3)Sensor器件驱动子模块:提供Sensor器件通用驱动和差异化驱动实现。
传感器设备驱动模型介绍
Sensor设备作为外接设备重要组成模块,通过Sensor驱动模型屏蔽硬件器件差异,为上层Sensor服务系统提供稳定的Sensor基础能力接口,包括Sensor列表查询、Sensor启停、Sensor订阅及取消订阅,Sensor参数配置等功能;Sensor设备驱动的开发是基于HDF驱动框架基础上,结合操作系统适配层(OSAL)和平台驱动接口(比如I2C/SPI/UART总线等平台资源)能力,屏蔽不同操作系统和平台总线资源差异,实现Sensor驱动“一次开发,多系统部署”的目标。传感器设备驱动模型框图如图2。
图2 传感器驱动模型框图
Sensor驱动模型作为HDF框架中一个Device Host(驱动宿主),完成对Sensor设备管理,包括Sensor驱动加载,注册,卸载,绑定,配置管理,接口发布。
Sensor驱动模型主要包括Sensor HDI子模块,Sensor设备管理和通用配置子模块和Sensor器件驱动子模块。Sensor HDI子模块抽象出Sensor设备的基本能力Sensor列表查询、Sensor启停、Sensor订阅及取消订阅,Sensor参数配置接口,接口和类型定义参考sensor_if.h和sensor_type.h。Sensor设备管理和通用配置子模块,其中,Sensor设备管理完成Sensor设备的注册、管理能力,数据报告能力,接口定义参考sensor_device_if.h;通用配置子模块完成寄存器配置操作接口抽象,Sensor HCS通用配置解析能力,接口定义参考sensor_config_parser.h、sensor_config_controller.h。Sensor器件驱动子模块完成每类Sensor类型驱动的抽象和器件差异化驱动实现。
传感器驱动模型工作流程解析
通过介绍Sensor驱动模型的加载以及运行流程,对模型内部关键组件以及关联组件之间的关系进行了划分,整体加载流程如图3。
图3 Sensor驱动模型运行图 Sensor驱动模型以标准系统Hi3516DV300产品中的加速度计驱动为例,介绍整个驱动加载及运行流程为: 1)从device info HCS 的Sensor Host里读取Sensor设备管理配置信息。 2)HDF配置框架从HCB数据库解析Sensor设备管理配置信息,并关联到对应设备驱动。 3)加载并初始化Sensor设备管理驱动。 4)Sensor设备管理驱动向HDI发布Sensor基础能力接口。 5)从device info HCS 的Sensor Host里读取加速度计驱动配置信息。 6)加载加速度抽象驱动,调用初始化接口,完成Sensor器件驱动资源分配和数据处理队列创建。 7)从accel_xxx_config HCS里读取加速度器件差异化驱动配置和私有化配置信息。 8)加速度计差异化驱动,调用通用配置解析接口,完成器件属性信息解析,器件寄存器解析。 9)加速度计差异化驱动完成器件探测,并分配加速度传感器配置资源,完成加速度计差异化接口注册。 10)加速度器件探测成功之后,加速度差异化驱动通知加速度抽象驱动,注册加速度设备到Sensor设备管理中。 为了让开发者更清晰的了解Sensor驱动模型工作流程,本节将对Sensor驱动模型加载的关键流程代码进行说明。
Sensor设备管理驱动实现
HDF驱动框架从device info HCS 的Sensor Host里读取Sensor设备管理配置信息,加载并初始化Sensor设备管理驱动。
步骤1-步骤4实现关键代码介绍如下,参考完整代码实现路径driversframeworkmodelsensordrivercommonsrcsensor_device_manager.c。 定义Sensor设备管理驱动对应的HdfDriverEntry对象,其中Driver Entry入口函数定义如下:
Sensor设备管理模块负责系统中所有Sensor器件接口发布,在系统启动过程中,HDF框架机制通过Sensor Host里设备HCS配置信息,加载设备管理驱动。
Sensor设备管理驱动DispatchSensor接口完成Sensor设备对外能力的发布,DispatchSensor接口实现如下:
加速度计抽象驱动实现
HDF驱动框架从device info HCS 的Sensor Host里读取加速度计抽象驱动配置信息,加载并初始化加速度计抽象驱动,完成Sensor器件驱动资源分配和数据处理队列创建。 步骤5-步骤6实现关键代码介绍如下,参考完整代码实现路径driversframeworkmodelsensordriveraccelsensor_accel_driver.c。 定义加速度计抽象驱动对应的HdfDriverEntry对象,其中,Driver Entry入口函数定义如下:
加速度计抽象驱动的配置信息在Sensor Host定义如下:
不同型号的加速度器件在初始化时,会进行器件探测,探测器件是否在位,如果在位,会对加速度器件分配资源,用于存放器件HCS配置信息。加速度计抽象驱动提供初始化过程中器件探测,器件属性配置,寄存器配置资源分配和释放接口。
1、创建加速度配置数据接口
此接口在差异化器件驱动初始化时调用,解析器件HCS私有配置,读取sensor的基本信息,总线方式,器件探测寄存器,并校验器件是否在位。如果器件探测成功,完成加速度器件资源分配,并返回传感器配置数据结构体地址。
2、释放加速度配置数据接口 此接口在差异化器件驱动初始化失败,或者加速度抽象驱动卸载时调用,释放已分配的资源。
3、注册加速度差异化接口 此接口在差异化器件驱动初始化成功时,注册差异实现接口,方便实现器件差异的驱动接口,此接口支持扩展。
加速度计差异化驱动实现
加速度计差异化驱动主要实现因为器件差异无法通过加速度计HCS差异化配置文件实现的能力接口。HDF驱动框架从device info HCS 的Sensor Host里读取加速度计差异化驱动配置信息,加载并初始化加速度计抽象驱动,完成器件探测,并分配加速度传感器配置资源,完成加速度计差异化接口注册。另外,初始化过程中会从accel_xxx_config HCS里读取私有化配置信息。 步骤7-步骤9实现关键代码介绍如下,参考完整代码实现路径driversframeworkmodelsensordriveraccelsensor_accel_driver.c。 定义加速度计差异化驱动对应的HdfDriverEntry对象,其中,Driver Entry入口函数定义如下:
加速度计差异化驱动的配置信息在Sensor Host定义如下:
加速度计私有化配置信息主要包括总线信息,sensor信息,sensor寄存器等资源信息。加速度计私有化配置信息在如下路径vendorhisiliconHi3516DV300hdf_configkhdfsensoraccelaccel_bmi160_config.hcs。 为了方面开发者使用传感器HCS私有配置,在sensor_common.hcs里面定义通用的传感器配置模板,其他器件直接引用模板修改对应的属性值,如果需要新增功能,可以在私有的配置文件里扩展新的节点即可。
每个Sensor器件都要根据业务需求增加或者修改对应的Sensor 寄存器分组以满足器件业务需求,当前基本业务分组如下:
通用配置子模块提供寄存器配置操作和HCS通用配置解析接口。驱动开发者基于通用Sensor HCS配置模板实现的HCS,无需实现解析接口,直接调用如下抽象接口解析即可。
1、传感器设备HCS抽象接口
Sensor器件驱动模型提供设备资源通用接口,解析配置文件中的通用节点信息。配置接口会在驱动加载过程中初始化的两个阶段调用,第一个阶段调用GetSensorBaseConfigData接口,解析设备资源HCS中的节点(sensorInfo,sensorBusConfig,sensorAttr)信息,第二个阶段在Sensor器件探测成功之后,调用ParseSensorRegConfig接口,解析Sensor寄存器配置信息。最后器件驱动卸载时调用ReleaseSensorAllRegConfig接口释放所有配置资源。接口定义在sensor_config_parser.h文件。 传感器基本配置数据解析接口函数定义 int32_t GetSensorBaseConfigData(const struct DeviceResourceNode *node, struct SensorCfgData *config); 传感器寄存器配置数据解析接口函数定义 int32_t ParseSensorRegConfig(struct SensorCfgData *config); 释放传感器所有配置数据接口函数定义 void ReleaseSensorAllRegConfig(struct SensorCfgData *config); 传感器器件探测在位接口 int32_t DetectSensorDevice(struct SensorCfgData *config); 2、传感器读写寄存器接口 器件驱动开发时,需要用到不同总线接口,配置器件。由于不同操作系统或者平台,总线接口总是有差异,导致开发过程中,需要不断地进行适配修改。传感器驱动模型依赖HDF框架提供的平台接口能力,封装了传感器器读写设备的接口,支持的总线有I2C,SPI接口。 读传感器寄存器接口函数定义 int32_t ReadSensor(struct SensorBusCfg *busCfg, uint16_t regAddr, uint8_t *data, uint16_t dataLen); 读传感器寄存器接口函数定义 int32_t WriteSensor(struct SensorBusCfg *busCfg, uint8_t *writeData, uint16_t len); Sensor设备管理能力接口
加速度器件探测成功之后,加速度差异化驱动通知加速度抽象驱动,注册加速度设备到Sensor设备管理中,对应步骤10。Sensor设备管理模块还提供如下接口能力: 1、注册设备 设备注册接口AddSensorDevice把加速度计设备信息注册到Sensor设备管理模块。调用注册设备函数时,系统要求sensorTpyeId和sensorId全局唯一,并实现Sensor信息和Sensor接口,才能确保Sensor设备注册成功。 struct SensorOps { int32_t (*Enable)(void); // 使能传感器 int32_t (*Disable)(void);// 使能传感器 int32_t (*SetBatch)(int64_t samplingInterval, int64_t reportInterval);// 配置传感器采样率和上报时延 int32_t (*SetMode)(int32_t mode);// 配置传感器模式 int32_t (*SetOption)(uint32_t option);// 配置传感器可选项参数 }; struct SensorDeviceInfo { struct SensorBasicInfo sensorInfo; // 传感器信息,包括传感器名字,厂商名,传感类型ID,传感ID等信息
注册设备接口函数定义如下:
int32_t AddSensorDevice(const struct SensorDeviceInfo *deviceInfo); 2、删除设备 设备注册失败或者驱动需要卸载时,需要删除注册到Sensor设备管理里的设备信息。调用DeleteSensorDevice接口完成设备信息的删除。
int32_t DeleteSensorDevice(const struct SensorBasicInfo *sensorBaseInfo); 3、设备数据报告 Sensor设备管理模块提供了抽象的数据上报接口,器件驱动产生数据事件后,调用ReportSensorEvent接口,把数据事件上报给Sensor服务端 上报数据事件格式定义如下: // 传感器数据上报事件 struct SensorReportEvent { int32_t sensorId; // 用户自定义传感器ID,兼容不同厂商定义,ID值要求全局唯一,无特殊要求默认和sensorTypeId保持一致,设备访问时采用SensorId作为系统中器件唯一标识 int32_t version; // 传感器版本号,有HAL层定义 int64_t timestamp; // 采样数据产生时的时间戳 uint32_t option; // 传感器可选配置,如量程,精度 int32_t mode; // 传感器数据上报模式 uint8_t *data; // 采样数据,根据器件特性定义传感器数据格式和单位,此数据可以是一组采样数据或者多组采样数据 uint32_t dataLen; // 采样数据存储长度
数据事件上报接口函数定义如下:
int32_t ReportSensorEvent(const struct SensorReportEvent *events); 对于Sensor驱动模型来说,已经实现了Sensor HDI接口定义,设备管理驱动和通用配置解析接口,及一些平台无关的读写寄存的接口能力,驱动开发者新增一款传感器器件,只需要实现文件里struct SensorOps结构体定义接口,并调用AddSensorDevice接口添加。 传感器驱动开发指导
本示例介绍新开发一款加速度BMI160器件传感器驱动的实现步骤为例。设备的通讯方式采用I2C总线方式。
加速计传感器驱动开发主要包括两个部分:加速度抽象驱动和加速度差异化驱动。
1)基于HDF驱动框架,按照驱动Driver Entry程序,完成加速度抽象驱动开发,主要有Bind,Init,Release,Dispatch函数接口实现。 2)完成加速度传感器驱动的设备信息配置。 3)完成加速度抽象驱动内部接口开发,包括定时器,工作队列,Enable,Disable,SetBatch,SetMode,SetOption,AccelCreateCfgData,AccelReleaseCfgData,AccelRegisterChipOps接口实现。 4)基于HDF驱动框架,按照驱动Driver Entry程序,完成加速度差异化驱动开发,主要有Bind,Init,Release,Dispatch函数接口实现。 5)完成加速度传感器差异化驱动中差异化接口ReadData函数实现。 6)新增文件脚本适配。
加速度抽象驱动实现示例
定义加速度抽象驱动对应的HdfDriverEntry对象,其中Driver Entry入口函数定义如下:
Bind接口实现驱动接口实例化,实现示例:
Init接口实现驱动接口实例化,实现示例:
Release接口在驱动卸载或者Init执行失败时,会调用此接口释放资源:
加速度抽象驱动配置示例
加速度计设备配置信息在device_info.hcs文件Sensor_host里面,配置HCS文件在源码仓位置为
vendorhisiliconHi3516DV300hdf_configkhdfdevice_infodevice_info.hcs: 加速度抽象驱动内部接口开发实现示例
提供给差异化驱动的初始化接口,完成加速度器件基本配置信息解析(加速度信息,加速度总线配置,加速度器件探测寄存器配置),器件探测,器件寄存器解析。
加速度计差异化驱动实现示例
定义加速度差异化驱动对应的HdfDriverEntry对象,其中Driver Entry入口函数定义如下:
Bind驱动接口实例化,实现示例:
Init驱动接口实例化,实现示例:
Release驱动接口实例化,实现示例:
加速度计差异化驱动私有HCS配置实现示例
加速度计器件私有HCS配置在如下路径vendorhisiliconHi3516DV300hdf_configkhdfsensoraccelaccel_bmi160_config.hcs。为了方面开发者使用传感器HCS配置,在accel_config.hcs里面配置通用的传感器模板,加速度计器件直接引用模板并修改对应的属性值,在此基础上新增寄存器配置,生成accel_bmi160_config.hcs配置文件。
加速度计差异化函数接口实现示例
需要开发者实现的ReadBmi160Data接口函数,在Bmi160InitDriver函数里面注册此函数。
适配编译入口示例
传感器驱动实现在内核态,代码参与编译是通过适配makefile实现,并通过内核模块宏定义,控制加速度设备驱动是否参与编译。 标准系统Linux内核加速度模块配置宏定义CONFIG_DRIVERS_HDF_SENSOR_ACCEL、CONFIG_DRIVERS_HDF_SENSOR_ACCEL_BMI160在kernel/linux/config/linux-4.19/arch/arm/configs/hi3516dv300_standard_defconfig文件,若开启模块则CONFIG_DRIVERS_HDF_SENSOR_ACCEL=y, CONFIG_DRIVERS_HDF_SENSOR_ACCEL_BMI160=y,若关闭模块则删除宏即可。 Makefile脚本入口在drivers/adapter/khdf路径下,根据不同操作系统选择不同目录,以标准系统为例说明脚本适配步骤,脚本路径如下/drivers/adapter/khdf/linux/model/sensor/Makefile。
总结
本文主要和大家分享传感器驱动模型,重点分析传感驱动模型框架原理和传感器抽象驱动适配开发过程。以开源板Hi3516DV300标准系统版本加速度计为例进行了详细的代码说明,希望通过本文档您能初步掌握基于HDF框架的传感器设备的开发步骤与流程。关于传感器驱动框架的更多分析,请关注后续文章。
|