通用配置操作接口
|
int32_t SetSensorRegCfgArray(struct SensorBusCfg *busCfg, const struct SensorRegCfgGroupNode *group);
@@ -193,6 +188,7 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考表3
**表 3** Sensor驱动模型要求驱动开发者实现的接口列表
+
功能分类
|
接口名
@@ -208,11 +204,6 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考表3
| 传感器器设备探测成功后,需要对传感器器设备初始化配置。
|
-int32_t GetInfo(struct SensorBasicInfo *info)
- |
-从传感器器设备的HCS配置里,获取当前传感器设备的基本信息。
- |
-
int32_t Enable(void)
|
根据当前传感器器设备的HCS配置,下发传感器设备使能操作组的寄存器配置。
@@ -246,6 +237,7 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考表3
|
+
接口实现参考[SENSOR](#section257750691)章节。
## 开发指导
@@ -254,10 +246,14 @@ Sensor驱动是基于HDF框架、PLATFORM和OSAL基础接口进行开发,不
### 开发步骤
-1. 加速度计传感器驱动注册。HDF驱动框架会提供统一的驱动管理模型,通过加速计传感器模块配置信息,识别并加载对应模块驱动。
-2. 加速度计传感器驱动初始化和去初始化。HDF驱动框架通过init入口函数,依次启动传感器设备驱动加载和分配传感器设备数据配置资源。HDF驱动框架通过release函数,释放驱动加载的资源和配置。
-3. 加速度计传感器寄存器组配置解析。不同类型传感器需要在hcs里配置器件对应的HCS配置文件,然后再设备驱动启动过程中探测器件是否在位,然后加载对应的配置文件,生成配置的结构体对象。
-4. 加速度计传感器驱动操作接口实现。实现各个类型传感器归一化驱动接口,如init,GetInfo,Enable,Disable,SetBatch,SetMode,SetOption,ReadSensorData等函数,完成传感器驱动配置下发和数据上报功能。
+加速计传感器驱动开发主要包括两个部分:加速度抽象驱动和加速度差异化驱动。
+
+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. 新增文件脚本适配。
>![](../public_sys-resources/icon-note.gif) **说明:**
>传感器驱动模型已经提供一部分能力集,包括驱动设备管理能力,抽象总线和平台操作接口能力,通用配置操作接口能力,配置解析操作接口能力,接口参考[表2](#table1156812588320)。需要开发人员实现部分有:1、传感器部分操作接口([表3](#table1083014911336));2、传感器HCS差异化数据配置;3、驱动基本功能验证。
@@ -266,7 +262,7 @@ Sensor驱动是基于HDF框架、PLATFORM和OSAL基础接口进行开发,不
基于HDF驱动模型,加载启动加速度计传感器驱动,代码形式如下,具体原理可参考[HDF驱动开发指南](driver-hdf-development.md)。加速度传感器选择通讯接口方式为I2C,厂家选择博世BMI160加速度传感器。
-1. 加速度计传感器驱动入口注册
+1.加速度计传感器驱动入口注册
- 加速度计传感器驱动入口函数实现
@@ -284,17 +280,17 @@ struct HdfDriverEntry g_sensorAccelDevEntry = {
HDF_INIT(g_sensorAccelDevEntry);
```
-- 加速度计传感器设备配置描述
+- 加速度计传感器设备配置描述
-加速度传感器模型使用HCS作为配置描述源码,HCS配置字段详细介绍参考[配置管理](driver-hdf-manage.md)介绍。
+ 加速度传感器模型使用HCS作为配置描述源码,HCS配置字段详细介绍参考[配置管理](driver-hdf-manage.md)介绍。
```
/* 加速度计传感器设备HCS配置 */
device_sensor_accel :: device {
device0 :: deviceNode {
policy = 1; /* policy字段是驱动服务发布的策略 */
- priority = 105; /* 驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序 */
- preload = 2; /* 驱动按需加载字段,0表示加载,2表示不加载 */
+ priority = 110; /* 驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序 */
+ preload = 0; /* 驱动按需加载字段,0表示加载,2表示不加载 */
permission = 0664; /* 驱动创建设备节点权限 */
moduleName = "HDF_SENSOR_ACCEL"; /* 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 */
serviceName = "sensor_accel"; /* 驱动对外发布服务的名称,必须唯一 */
@@ -303,43 +299,145 @@ device_sensor_accel :: device {
}
```
-1. 加速度计传感器驱动初始化和去初始化
+2.加速度计传感器驱动操作接口实现
+
+- 开发者需要根据每种类型的传感器实现归一化接口。
-- 初始化入口函数init
```
-/* 加速度计传感器驱动对外提供的服务绑定到HDF框架 */
-int32_t BindAccelDriver(struct HdfDeviceObject *device)
+/* 不使用函数暂时置空 */
+static int32_t SetAccelInfo(struct SensorBasicInfo *info)
{
- CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
+ (void)info;
- static struct IDeviceIoService service = {
- .object = {0},
- .Dispatch = DispatchAccel,
- };
- device->service = &service;
+ return HDF_ERR_NOT_SUPPORT;
+}
+/* 下发使能寄存器组的配置 */
+static int32_t SetAccelEnable(void)
+{
+ int32_t ret;
+ struct AccelDrvData *drvData = AccelGetDrvData();
+
+ CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
+ CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM);
+
+ if (drvData->enable) {
+ HDF_LOGE("%s: Accel sensor is enabled", __func__);
+ return HDF_SUCCESS;
+ }
+
+ ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_ENABLE_GROUP]);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: Accel sensor enable config failed", __func__);
+ return ret;
+ }
+
+ ret = OsalTimerCreate(&drvData->accelTimer, SENSOR_TIMER_MIN_TIME, AccelTimerEntry, (uintptr_t)drvData);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: Accel create timer failed[%d]", __func__, ret);
+ return ret;
+ }
+
+ ret = OsalTimerStartLoop(&drvData->accelTimer);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: Accel start timer failed[%d]", __func__, ret);
+ return ret;
+ }
+ drvData->enable = true;
return HDF_SUCCESS;
}
-/*在探测到器件在位后,需要调用RegisterAccelChipOps注册差异化适配函数*/
-int32_t RegisterAccelChipOps(struct AccelOpsCall *ops)
+/* 下发去使能寄存器组的配置 */
+static int32_t SetAccelDisable(void)
{
- struct AccelDrvData *drvData = NULL;
+ int32_t ret;
+ struct AccelDrvData *drvData = AccelGetDrvData();
+
+ CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
+ CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM);
+
+ if (!drvData->enable) {
+ HDF_LOGE("%s: Accel sensor had disable", __func__);
+ return HDF_SUCCESS;
+ }
+
+ ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_DISABLE_GROUP]);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: Accel sensor disable config failed", __func__);
+ return ret;
+ }
+
+ ret = OsalTimerDelete(&drvData->accelTimer);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: Accel delete timer failed", __func__);
+ return ret;
+ }
+ drvData->enable = false;
+
+ return HDF_SUCCESS;
+}
+/* 配置传感器采样率和数据上报间隔 */
+static int32_t SetAccelBatch(int64_t samplingInterval, int64_t interval)
+{
+ (void)interval;
- CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM);
+ struct AccelDrvData *drvData = NULL;
drvData = AccelGetDrvData();
- drvData->ops.Init = ops->Init;
- drvData->ops.ReadData = ops->ReadData;
+ CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
+
+ drvData->interval = samplingInterval;
+
return HDF_SUCCESS;
}
+/* 设置传感器工作模式,当前支持实时模式 */
+static int32_t SetAccelMode(int32_t mode)
+{
+ return (mode == SENSOR_WORK_MODE_REALTIME) ? HDF_SUCCESS : HDF_FAILURE;
+}
+
+static int32_t SetAccelOption(uint32_t option)
+{
+ (void)option;
+ return HDF_SUCCESS;
+}
+
+/* 设置传感器可选配置 */
+static int32_t SetAccelOption(uint32_t option)
+{
+ (void)option;
+ return HDF_ERR_NOT_SUPPORT;
+}
+```
+
+3.加速度计传感器驱动初始化和去初始化
+
+- 初始化入口函数init
+
+```
+/* 加速度计传感器驱动对外提供的服务绑定到HDF框架 */
+int32_t AccelBindDriver(struct HdfDeviceObject *device)
+{
+ CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
+
+ struct AccelDrvData *drvData = (struct AccelDrvData *)OsalMemCalloc(sizeof(*drvData));
+ if (drvData == NULL) {
+ HDF_LOGE("%s: Malloc accel drv data fail!", __func__);
+ return HDF_ERR_MALLOC_FAIL;
+ }
+
+ drvData->ioService.Dispatch = DispatchAccel;
+ drvData->device = device;
+ device->service = &drvData->ioService;
+ g_accelDrvData = drvData;
+ return HDF_SUCCESS;
+}
+
/* 挂载加速度计传感器驱动归一化的接口函数 */
-static int32_t InitAccelOps(struct SensorDeviceInfo *deviceInfo)
+static int32_t InitAccelOps(struct SensorCfgData *config, struct SensorDeviceInfo *deviceInfo)
{
- struct AccelDrvData *drvData = AccelGetDrvData();
+ CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM);
- (void)memset_s((void *)deviceInfo, sizeof(*deviceInfo), 0, sizeof(*deviceInfo));
- deviceInfo->ops.GetInfo = SetAccelInfo;
deviceInfo->ops.Enable = SetAccelEnable;
deviceInfo->ops.Disable = SetAccelDisable;
deviceInfo->ops.SetBatch = SetAccelBatch;
@@ -347,156 +445,118 @@ static int32_t InitAccelOps(struct SensorDeviceInfo *deviceInfo)
deviceInfo->ops.SetOption = SetAccelOption;
if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo),
- &drvData->accelCfg->sensorInfo, sizeof(drvData->accelCfg->sensorInfo)) != EOK) {
- HDF_LOGE("%s: copy sensor info failed", __func__);
+ &config->sensorInfo, sizeof(config->sensorInfo)) != EOK) {
+ HDF_LOGE("%s: Copy sensor info failed", __func__);
return HDF_FAILURE;
}
- /* 传感器类型标识可以在数据HCS配置文件里面配置,也可以在此处 */
- drvData->accelCfg->sensorInfo.sensorTypeId = SENSOR_TAG_ACCELEROMETER;
- drvData->accelCfg->sensorInfo.sensorId = SENSOR_TAG_ACCELEROMETER;
return HDF_SUCCESS;
}
-/* 传感器寄存器初始化操作 */
-static int32_t InitAccelAfterConfig(void)
+/* 提供给差异化驱动的初始化接口,完成加速度器件基本配置信息解析(加速度信息,加速度总线配置,加速度器件探测寄存器配置),器件探测,器件寄存器解析 */
+static int32_t InitAccelAfterDetected(struct SensorCfgData *config)
{
struct SensorDeviceInfo deviceInfo;
-
- if (InitAccelConfig() != HDF_SUCCESS) {
- HDF_LOGE("%s: init accel config failed", __func__);
+ CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM);
+ // 初始化加速度计接口函数
+ if (InitAccelOps(config, &deviceInfo) != HDF_SUCCESS) {
+ HDF_LOGE("%s: Init accel ops failed", __func__);
return HDF_FAILURE;
}
-
- if (InitAccelOps(&deviceInfo) != HDF_SUCCESS) {
- HDF_LOGE("%s: init accel ops failed", __func__);
+ // 注册加速度计设备到传感器管理模块
+ if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) {
+ HDF_LOGE("%s: Add accel device failed", __func__);
return HDF_FAILURE;
}
-
- if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) {
- HDF_LOGE("%s: add accel device failed", __func__);
+ // 器件寄存器解析
+ if (ParseSensorRegConfig(config) != HDF_SUCCESS) {
+ HDF_LOGE("%s: Parse sensor register failed", __func__);
+ (void)DeleteSensorDevice(&config->sensorInfo);
+ ReleaseSensorAllRegConfig(config);
return HDF_FAILURE;
}
-
return HDF_SUCCESS;
}
-/*通过器件探测函数,挂载器件差异化函数接口*/
-static int32_t DetectAccelChip(void)
+struct SensorCfgData *AccelCreateCfgData(const struct DeviceResourceNode *node)
{
- int32_t num;
- int32_t ret;
- int32_t loop;
- struct AccelDrvData *drvData = AccelGetDrvData();
- CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM);
-
- num = sizeof(g_accelDetectIfList) / sizeof(g_accelDetectIfList[0]);
- for (loop = 0; loop < num; ++loop) {
- if (g_accelDetectIfList[loop].DetectChip != NULL) {
- ret = g_accelDetectIfList[loop].DetectChip(drvData->accelCfg);
- if (ret == HDF_SUCCESS) {
- drvData->detectFlag = true;
- break;
- }
- }
+ ……
+ // 如果探测不到器件在位,返回进行下个器件探测
+ if (drvData->detectFlag) {
+ HDF_LOGE("%s: Accel sensor have detected", __func__);
+ return NULL;
}
-
- if (loop == num) {
- HDF_LOGE("%s: detect accel device failed", __func__);
+ if (drvData->accelCfg == NULL) {
+ HDF_LOGE("%s: Accel accelCfg pointer NULL", __func__);
+ return NULL;
+ }
+ // 设备基本配置信息解析
+ if (GetSensorBaseConfigData(node, drvData->accelCfg) != HDF_SUCCESS) {
+ HDF_LOGE("%s: Get sensor base config failed", __func__);
+ goto BASE_CONFIG_EXIT;
+ }
+ // 如果探测不到器件在位,返回进行下个器件探测
+ if (DetectSensorDevice(drvData->accelCfg) != HDF_SUCCESS) {
+ HDF_LOGI("%s: Accel sensor detect device no exist", __func__);
drvData->detectFlag = false;
- return HDF_FAILURE;
+ goto BASE_CONFIG_EXIT;
}
- return HDF_SUCCESS;
+ drvData->detectFlag = true;
+ // 器件寄存器解析
+ if (InitAccelAfterDetected(drvData->accelCfg) != HDF_SUCCESS) {
+ HDF_LOGE("%s: Accel sensor detect device no exist", __func__);
+ goto INIT_EXIT;
+ }
+ return drvData->accelCfg;
+ ……
}
/* 加速度计传感器驱动初始化入口函数,主要功能为对传感器私有数据的结构体对象进行初始化,传感器HCS数据配置对象空间分配,传感器HCS数据配置初始化入口函数调用,传感器设备探测是否在位功能,传感器数据上报定时器创建,传感器归一化接口挂载,传感器设备注册功能 */
int32_t InitAccelDriver(struct HdfDeviceObject *device)
{
- /* 获取传感器私有数据结构体对象 */
- struct AccelDrvData *drvData = AccelGetDrvData();
-
- /* 同类型传感器不同厂家设备探测时,判断此类型传感器是否已经在位,若已经在位,无需再继续探测,直接返回 */
- if (drvData->detectFlag) {
- HDF_LOGE("%s: accel sensor have detected", __func__);
- return HDF_SUCCESS;
- }
-
- CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
- /* 分配存放传感器数据配置的私有结构体数据对象,需要在驱动释放时释放分配的资源空间 */
- drvData->accelCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*cfg));
- if (drvData->accelCfg == NULL) {
- HDF_LOGE("%s: malloc sensor config data failed", __func__);
- return HDF_FAILURE;
- }
-
- drvData->accelCfg->regCfgGroup = &g_regCfgGroup[0];
- /* 初始化传感器配置数据主要是解析传感器通讯总线配置类型信息,传感器基本信息,传感器属性信息,传感器是否在位信息,寄存器分组信息 */
- if (GetSensorBaseConfigData(device->property, drvData->accelCfg) != HDF_SUCCESS) {
- HDF_LOGE("%s: get sensor base config failed", __func__);
- goto Base_CONFIG_EXIT;
- }
-
- if (DetectAccelChip() != HDF_SUCCESS) {
- HDF_LOGE("%s: accel sensor detect device no exist", __func__);
- goto DETECT_CHIP_EXIT;
- }
- drvData->detectFlag = true;
- if (ParseSensorRegConfig(drvData->accelCfg) != HDF_SUCCESS) {
- HDF_LOGE("%s: detect sensor device failed", __func__);
- goto REG_CONFIG_EXIT;
+int32_t AccelInitDriver(struct HdfDeviceObject *device)
+{
+ ……
+ // 工作队列资源初始化
+ if (InitAccelData(drvData) != HDF_SUCCESS) {
+ HDF_LOGE("%s: Init accel config failed", __func__);
+ return HDF_FAILURE;
}
-
- if (InitAccelAfterConfig() != HDF_SUCCESS) {
- HDF_LOGE("%s: init accel after config failed", __func__);
- goto INIT_EXIT;
+ // 分配加速度配置信息资源
+ drvData->accelCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*drvData->accelCfg));
+ if (drvData->accelCfg == NULL) {
+ HDF_LOGE("%s: Malloc accel config data failed", __func__);
+ return HDF_FAILURE;
}
-
- HDF_LOGI("%s: init accel driver success", __func__);
+ // 挂接寄存器分组信息
+ drvData->accelCfg->regCfgGroup = &g_regCfgGroup[0];
+ ……
return HDF_SUCCESS;
-
-INIT_EXIT:
- DestroySensorThread(&drvData->thread, &drvData->threadStatus);
- (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER);
-REG_CONFIG_EXIT:
- ReleaseSensorAllRegConfig(drvData->accelCfg);
- (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg);
-DETECT_CHIP_EXIT:
- drvData->detectFlag = false;
-BASE_CONFIG_EXIT:
- drvData->accelCfg->root = NULL;
- drvData->accelCfg->regCfgGroup = NULL;
- OsalMemFree(drvData->accelCfg);
- drvData->accelCfg = NULL;
- return HDF_FAILURE;
}
/* 释放驱动初始化时分配的资源 */
-void ReleaseAccelDriver(struct HdfDeviceObject *device)
+void AccelReleaseDriver(struct HdfDeviceObject *device)
{
- (void)device;
- struct AccelDrvData *drvData = NULL;
-
- drvData = AccelGetDrvData();
- (void)DestroySensorThread(&drvData->thread, &drvData->threadStatus);
- (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER);
- drvData->detectFlag = false;
-
- if (drvData->accelCfg != NULL) {
- drvData->accelCfg->root = NULL;
- drvData->accelCfg->regCfgGroup = NULL;
- ReleaseSensorAllRegConfig(drvData->accelCfg);
- (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg);
- OsalMemFree(drvData->accelCfg);
- drvData->accelCfg = NULL;
+ CHECK_NULL_PTR_RETURN(device);
+ struct AccelDrvData *drvData = (struct AccelDrvData *)device->service;
+ CHECK_NULL_PTR_RETURN(drvData);
+ // 器件在位,释放已分配资源
+ if (drvData->detectFlag) {
+ AccelReleaseCfgData(drvData->accelCfg);
}
-
- drvData->initStatus = false;
+ OsalMemFree(drvData->accelCfg);
+ drvData->accelCfg = NULL;
+ // 器件在位,销毁工作队列资源
+ HdfWorkDestroy(&drvData->accelWork);
+ HdfWorkQueueDestroy(&drvData->accelWorkQueue);
+ OsalMemFree(drvData);
}
```
-1. 加速度计传感器寄存器组配置信息
+4.加速度计差异化驱动私有HCS配置实现示例
+
+- 为了方便开发者使用传感器HCS私有配置,在sensor_common.hcs里面定义通用的传感器配置模板,加速度直接引用模板修改对应的属性值即可。
-加速度计传感器数据配置只需要按照模板配置即可,基于模板配置的解析功能已经在**InitSensorConfigData**函数完成,只需初始化时调用即可。如果有新增配置项,需要同步修改此函数。
```
-加速度传感器数据配置模板(accel_config.hcs)
+// accel sensor common config template
root {
sensorAccelConfig {
accelChipConfig {
@@ -509,7 +569,7 @@ root {
sensorTypeId = 1; /* 传感器类型编号,详见{@link SensorTypeTag} */
sensorId = 1; /* 传感器的标识号,有传感器驱动开发者定义,推荐用{@link SensorTypeTag}枚举 */
maxRange = 8; /* 传感器的最大量程,根据开发者需要配置 */
- precision = 0; /* 传感器的精度,与上报数据配合使用,上报数据结构体{@link SensorEvents } */
+ accuracy = 0; /* 传感器的精度,与上报数据配合使用,上报数据结构体{@link SensorEvents } */
power = 230; /* 传感器的功耗 */
}
/* 传感器使用的总线类型和配置信息模板 */
@@ -529,285 +589,188 @@ root {
}
}
}
+```
+
+- 开发者使用传感器HCS配置,在accel_config.hcs里面配置通用的传感器模板,加速度计器件直接引用模板并修改对应的属性值,在此基础上新增寄存器配置,生成accel_bmi160_config.hcs配置文件。
+
+```
/* 根据不同器件硬件差异,修改模板配置,不修改的就会默认采用模板配置 */
+#include "accel_config.hcs"
root {
- sensorAccelConfig {
- accel_bmi160_chip_config : accelChipConfig {
- match_attr = "hdf_sensor_accel_driver"; /* 需要和加速度传感器设备配置match_attr字段保持一致 */
- accelInfo :: sensorInfo {
- vendorName = "borsh_bmi160";
- sensorTypeId = 1;
- sensorId = 1;
- }
- accelBusConfig :: sensorBusConfig {
- busType = 0; /* i2c通讯方式 */
- busNum = 6;
- busAddr = 0x68;
- regWidth = 1; /* 1字节位宽 */
- }
- accelAttr :: sensorAttr {
- chipName = "bmi160";
- chipIdRegister = 0x00;
- chipIdValue = 0xd1;
- }
- accelRegConfig {
- /* regAddr: 寄存器地址
- value: 寄存器值
- mask: 寄存器值的掩码
- len: 寄存器值的数据长度(字节)
- delay: 配置寄存器延时(ms)
- opsType:操作类型 0-无 1-读 2-写 3-读并检查 4-位更新
- calType: 计算类型 0-无 1-写 2-取反 3-异或 4-左移 5-右移
- shiftNum: 移动位数
- debug: 调试开关,0-调试关闭 1-调试打开
- save: 保存数据开关,0-不保存数据 1-保存数据
- */
- /* 传感器寄存器操作分组,按照分组进行有序配置 */
- /* 寄存器地址, 寄存器值, 寄存器值的掩码, 寄存器值的数据长度, 配置寄存器延时, 操作类型, 计算类型, 移动位数, 调试开关, 保存开关 */
- /* 初始化寄存器组 */
- initSeqConfig = [
- 0x7e, 0xb6, 0xff, 1, 5, 2, 0, 0, 0, 0,
- 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0
- ];
- /* 使能寄存器组 */
- enableSeqConfig = [
- 0x7e, 0x11, 0xff, 1, 5, 2, 0, 0, 0, 0,
- 0x41, 0x03, 0xff, 1, 0, 2, 0, 0, 0, 0,
- 0x40, 0x08, 0xff, 1, 0, 2, 0, 0, 0, 0
- ];
- /* 去使能寄存器组 */
- disableSeqConfig = [
- 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0
- ];
- }
- }
+ accel_bmi160_chip_config : sensorConfig {
+ match_attr = "hdf_sensor_accel_bmi160_driver";
+ sensorInfo :: sensorDeviceInfo {
+ vendorName = "borsh_bmi160"; // max string length is 16 bytes
+ sensorTypeId = 1; // enum SensorTypeTag
+ sensorId = 1; // user define sensor id
+ }
+ sensorBusConfig:: sensorBusInfo {
+ busType = 0; // 0:i2c 1:spi
+ busNum = 6;
+ busAddr = 0x68;
+ regWidth = 1; // 1btye
+ }
+ sensorIdAttr :: sensorIdInfo{
+ chipName = "bmi160";
+ chipIdRegister = 0x00;
+ chipIdValue = 0xd1;
+ }
+ sensorRegConfig {
+ /* regAddr: register address
+ value: config register value
+ len: size of value
+ mask: mask of value
+ delay: config register delay time (ms)
+ opsType: enum SensorOpsType 0-none 1-read 2-write 3-read_check 4-update_bit
+ calType: enum SensorBitCalType 0-none 1-set 2-revert 3-xor 4-left shift 5-right shift
+ shiftNum: shift bits
+ debug: 0-no debug 1-debug
+ save: 0-no save 1-save
+ */
+ /* regAddr, value, mask, len, delay, opsType, calType, shiftNum, debug, save */
+ // 初始化寄存器组
+ initSeqConfig = [
+ 0x7e, 0xb6, 0xff, 1, 5, 2, 0, 0, 0, 0,
+ 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0
+ ];
+ // 使能寄存器组
+ enableSeqConfig = [
+ 0x7e, 0x11, 0xff, 1, 5, 2, 0, 0, 0, 0,
+ 0x41, 0x03, 0xff, 1, 0, 2, 0, 0, 0, 0,
+ 0x40, 0x08, 0xff, 1, 0, 2, 0, 0, 0, 0
+ ];
+ // 去使能寄存器组
+ disableSeqConfig = [
+ 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0
+ ];
+ }
}
}
```
-1. 加速度计传感器驱动操作接口实现
+5.加速度计差异化驱动实现示例
-开发者需要根据每种类型的传感器实现归一化接口。
+- 定义加速度差异化驱动对应的HdfDriverEntry对象,其中Driver Entry入口函数定义如下:
-```
-/* 不使用函数暂时置空 */
-static int32_t SetAccelInfo(struct SensorBasicInfo *info)
-{
- (void)info;
- return HDF_ERR_NOT_SUPPORT;
-}
-/* 下发使能寄存器组的配置 */
-static int32_t SetAccelEnable(void)
-{
- int32_t ret;
- struct AccelDrvData *drvData = AccelGetDrvData();
+```
+struct HdfDriverEntry g_accelBmi160DevEntry = {
+ .moduleVersion = 1,
+ .moduleName = "HDF_SENSOR_ACCEL_BMI160",
+ .Bind = Bmi160BindDriver,
+ .Init = Bmi160InitDriver,
+ .Release = Bmi160ReleaseDriver,
+};
+HDF_INIT(g_accelBmi160DevEntry);
+```
- CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM);
- ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_ENABLE_GROUP]);
- if (ret != HDF_SUCCESS) {
- HDF_LOGE("%s: accel sensor disable config failed", __func__);
- return HDF_FAILURE;
- }
+- Bind驱动接口实例化,实现示例:
- drvData->threadStatus = SENSOR_THREAD_RUNNING;
+```
+int32_t Bmi160BindDriver(struct HdfDeviceObject *device)
+{
+ CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
+ struct Bmi160DrvData *drvData = (struct Bmi160DrvData *)OsalMemCalloc(sizeof(*drvData));
+ if (drvData == NULL) {
+ HDF_LOGE("%s: Malloc Bmi160 drv data fail", __func__);
+ return HDF_ERR_MALLOC_FAIL;
+ }
+ drvData->ioService.Dispatch = DispatchBMI160;
+ drvData->device = device;
+ device->service = &drvData->ioService;
+ g_bmi160DrvData = drvData;
return HDF_SUCCESS;
}
-/* 下发去使能寄存器组的配置 */
-static int32_t SetAccelDisable(void)
-{
- int32_t ret;
- struct AccelDrvData *drvData = AccelGetDrvData();
+```
- CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM);
+- Init驱动接口实例化,实现示例:
- ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_DISABLE_GROUP]);
+
+```
+int32_t Bmi160InitDriver(struct HdfDeviceObject *device)
+{
+ ……
+ // 加速度计差异化初始化配置
+ ret = InitAccelPreConfig();
if (ret != HDF_SUCCESS) {
- HDF_LOGE("%s: accel sensor disable config failed", __func__);
+ HDF_LOGE("%s: Init BMI160 bus mux config", __func__);
return HDF_FAILURE;
- }
-
- drvData->threadStatus = SENSOR_THREAD_STOPPED;
-
+ }
+ // 创建传感器配置数据接口,完成器件探测,私有数据配置解析
+ drvData->sensorCfg = AccelCreateCfgData(device->property);
+ if (drvData->sensorCfg == NULL) {
+ return HDF_ERR_NOT_SUPPORT;
+ }
+ // 注册差异化接口
+ ops.Init = NULL;
+ ops.ReadData = ReadBmi160Data;
+ ret = AccelRegisterChipOps(&ops);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: Register BMI160 accel failed", __func__);
+ return HDF_FAILURE;
+ }
+ // 初始化器件配置
+ ret = InitBmi160(drvData->sensorCfg);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: Init BMI160 accel failed", __func__);
+ return HDF_FAILURE;
+ }
return HDF_SUCCESS;
}
-/* 配置传感器采样率和数据上报间隔 */
-static int32_t SetAccelBatch(int64_t samplingInterval, int64_t interval)
-{
- (void)interval;
+```
- struct AccelDrvData *drvData = AccelGetDrvData();
- drvData->interval = samplingInterval;
+- Release驱动接口实例化,实现示例:
- return HDF_SUCCESS;
-}
-/* 设置传感器工作模式,当前支持实时模式 */
-static int32_t SetAccelMode(int32_t mode)
-{
- return (mode == SENSOR_WORK_MODE_REALTIME) ? HDF_SUCCESS : HDF_FAILURE;
-}
-/* 设置传感器可选配置 */
-static int32_t SetAccelOption(uint32_t option)
+
+```
+void Bmi160ReleaseDriver(struct HdfDeviceObject *device)
{
- (void)option;
- return HDF_ERR_NOT_SUPPORT;
+ CHECK_NULL_PTR_RETURN(device);
+ struct Bmi160DrvData *drvData = (struct Bmi160DrvData *)device->service;
+ CHECK_NULL_PTR_RETURN(drvData);
+ AccelReleaseCfgData(drvData->sensorCfg);
+ drvData->sensorCfg = NULL;
+ OsalMemFree(drvData);
}
```
-- 差异化处理接口
-
- ```
- /* 器件探测时,如果探测成功,则注册差异化处理函数到accel驱动模型里 */
- int32_t DetectAccelBim160Chip(struct SensorCfgData *data)
- {
- int32_t ret;
- struct AccelOpsCall ops;
- CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
-
- if (strcmp(ACCEL_CHIP_NAME_BMI160, data->sensorAttr.chipName) != 0) {
- return HDF_SUCCESS;
- }
- ret = InitAccelPreConfig();
- if (ret != HDF_SUCCESS) {
- HDF_LOGE("%s: init BMI160 bus mux config", __func__);
- return HDF_FAILURE;
- }
- if (DetectSensorDevice(data) != HDF_SUCCESS) {
- return HDF_FAILURE;
- }
-
- /* 差异化处理函数 */
- ops.Init = InitBmi160;
- ops.ReadData = ReadBmi160Data;
- ret = RegisterAccelChipOps(&ops);
- if (ret != HDF_SUCCESS) {
- HDF_LOGE("%s: register BMI160 accel failed", __func__);
- (void)ReleaseSensorBusHandle(&data->busCfg);
- return HDF_FAILURE;
- }
- return HDF_SUCCESS;
- }
- /* 初始化处理函数 */
- static int32_t InitBmi160(struct SensorCfgData *data)
- {
- int32_t ret;
-
- CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
- ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]);
- if (ret != HDF_SUCCESS) {
- HDF_LOGE("%s: bmi160 sensor init config failed", __func__);
- return HDF_FAILURE;
- }
- return HDF_SUCCESS;
- }
- /* 数据处理函数 */
- int32_t ReadBmi160Data(struct SensorCfgData *data)
- {
- int32_t ret;
- struct AccelData rawData = { 0, 0, 0 };
- int32_t tmp[ACCEL_AXIS_NUM];
- struct SensorReportEvent event;
-
- (void)memset_s(&event, sizeof(event), 0, sizeof(event));
-
- ret = ReadBmi160RawData(data, &rawData, &event.timestamp);
- if (ret != HDF_SUCCESS) {
- return HDF_FAILURE;
- }
-
- event.sensorId = SENSOR_TAG_ACCELEROMETER;
- event.option = 0;
- event.mode = SENSOR_WORK_MODE_REALTIME;
-
- rawData.x = rawData.x * BMI160_ACC_SENSITIVITY_2G;
- rawData.y = rawData.y * BMI160_ACC_SENSITIVITY_2G;
- rawData.z = rawData.z * BMI160_ACC_SENSITIVITY_2G;
-
- tmp[ACCEL_X_AXIS] = (rawData.x * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT;
- tmp[ACCEL_Y_AXIS] = (rawData.y * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT;
- tmp[ACCEL_Z_AXIS] = (rawData.z * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT;
-
- event.dataLen = sizeof(tmp);
- event.data = (uint8_t *)&tmp;
- ret = ReportSensorEvent(&event);
- return ret;
- }
- ```
+6.加速度计差异化函数接口实现示例
-- 数据处理函数
+- 需要开发者实现的ReadBmi160Data接口函数,在Bmi160InitDriver函数里面注册此函数。
-创建传感器定时器,按照配置的采样率定时采样,并上报给数据订阅者。
```
-/* 传感器定时工作线程 */
-static int32_t ReadAccelDataThreadWorker(void *arg)
-{
- (void)arg;
- int64_t interval;
- struct AccelDrvData *drvData = AccelGetDrvData();
-
- drvData->threadStatus = SENSOR_THREAD_START;
- while (true) {
- if (drvData->threadStatus == SENSOR_THREAD_RUNNING) {
- if (drvData->ops.ReadData != NULL) {
- (void)drvData->ops.ReadData(drvData->accelCfg);
- }
- interval = OsalDivS64(drvData->interval, (SENSOR_CONVERT_UNIT * SENSOR_CONVERT_UNIT));
- OsalMSleep(interval);
- } else if (drvData->threadStatus == SENSOR_THREAD_DESTROY) {
- break;
- } else {
- OsalMSleep(ACC_DEFAULT_SAMPLING_200_MS / SENSOR_CONVERT_UNIT / SENSOR_CONVERT_UNIT);
- }
-
- if ((!drvData->initStatus) || (drvData->interval < 0) || drvData->threadStatus != SENSOR_THREAD_RUNNING) {
- continue;
- }
- }
-
- return HDF_SUCCESS;
-}
-/* 创建传感器定时器和器件初始化 */
-static int32_t InitAccelConfig(void)
+int32_t ReadBmi160Data(struct SensorCfgData *data)
{
int32_t ret;
- struct AccelDrvData *drvData = AccelGetDrvData();
-
- if (drvData->threadStatus != SENSOR_THREAD_NONE && drvData->threadStatus != SENSOR_THREAD_DESTROY) {
- HDF_LOGE("%s: accel thread have created", __func__);
- return HDF_SUCCESS;
- }
-
- ret = CreateSensorThread(&drvData->thread, ReadAccelDataThreadWorker, "hdf_sensor_accel", drvData);
+ struct AccelData rawData = { 0, 0, 0 };
+ int32_t tmp[ACCEL_AXIS_NUM];
+ struct SensorReportEvent event;
+ (void)memset_s(&event, sizeof(event), 0, sizeof(event));
+ ret = ReadBmi160RawData(data, &rawData, &event.timestamp);
if (ret != HDF_SUCCESS) {
- HDF_LOGE("%s: accel create thread failed", __func__);
- drvData->threadStatus = SENSOR_THREAD_NONE;
+ HDF_LOGE("%s: BMI160 read raw data failed", __func__);
return HDF_FAILURE;
}
-
- CHECK_NULL_PTR_RETURN_VALUE(drvData->ops.Init, HDF_ERR_INVALID_PARAM);
-
- ret = drvData->ops.Init(drvData->accelCfg);
+ event.sensorId = SENSOR_TAG_ACCELEROMETER;
+ event.option = 0;
+ event.mode = SENSOR_WORK_MODE_REALTIME;
+ ……
+ ret = ReportSensorEvent(&event);
if (ret != HDF_SUCCESS) {
- HDF_LOGE("%s: accel create thread failed", __func__);
- drvData->threadStatus = SENSOR_THREAD_NONE;
- return HDF_FAILURE;
+ HDF_LOGE("%s: BMI160 report data failed", __func__);
}
- drvData->initStatus = true;
- return HDF_SUCCESS;
+ return ret;
}
```
-- 主要的数据结构
+7.主要的数据结构
```
-/* 传感器转换单位*/
-#define SENSOR_CONVERT_UNIT 1000
-#define SENSOR_1K_UNIT 1024
/* 传感器2g对应灵敏度转换值 */
-#define BMI160_ACC_SENSITIVITY_2G 61
+#define BMI160_ACC_SENSITIVITY_2G 61
/* 传感器数据采样寄存器地址 */
#define BMI160_ACCEL_X_LSB_ADDR 0X12
#define BMI160_ACCEL_X_MSB_ADDR 0X13
@@ -815,6 +778,7 @@ static int32_t InitAccelConfig(void)
#define BMI160_ACCEL_Y_MSB_ADDR 0X15
#define BMI160_ACCEL_Z_LSB_ADDR 0X16
#define BMI160_ACCEL_Z_MSB_ADDR 0X17
+#define BMI160_STATUS_ADDR 0X1B
/* 传感器数据维度 */
enum AccelAxisNum {
ACCEL_X_AXIS = 0,
@@ -830,12 +794,15 @@ struct AccelData {
};
/* 传感器私有数据结构体 */
struct AccelDrvData {
+ struct IDeviceIoService ioService;
+ struct HdfDeviceObject *device;
+ HdfWorkQueue accelWorkQueue;
+ HdfWork accelWork;
+ OsalTimer accelTimer;
bool detectFlag;
- uint8_t threadStatus;
- uint8_t initStatus;
+ bool enable;
int64_t interval;
struct SensorCfgData *accelCfg;
- struct OsalThread thread;
struct AccelOpsCall ops;
};
/* 差异化适配函数 */
@@ -847,7 +814,8 @@ struct AccelOpsCall {
## 测试指导
-驱动开发完成后,在传感器单元测试里面开发自测试用例,验证驱动基本功能。测试环境采用开发者自测试平台。
+- 驱动开发完成后,在传感器单元测试里面开发自测试用例,验证驱动基本功能。测试环境采用开发者自测试平台。
+
```
/* 标识是否上报传感器数据 */
|