diff --git a/zh-cn/device-dev/driver/driver-peripherals-sensor-des.md b/zh-cn/device-dev/driver/driver-peripherals-sensor-des.md index a548abe552a26190c342b9f758a681f83861d271..d0deb112780afdf0cdadd40156c903f48d236936 100644 --- a/zh-cn/device-dev/driver/driver-peripherals-sensor-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-sensor-des.md @@ -1,3 +1,5 @@ + + # SENSOR - [概述](#section3634112111) @@ -29,6 +31,7 @@ Sensor驱动模型对HDI开放的API接口功能,参考表1。 **表 1** Sensor驱动模型对外API接口功能介绍 + - @@ -73,7 +76,7 @@ Sensor驱动模型对HDI开放的API接口功能,参考表1。 - @@ -98,11 +101,13 @@ Sensor驱动模型对HDI开放的API接口功能,参考表1。

功能分类

接口名

@@ -61,7 +64,7 @@ Sensor驱动模型对HDI开放的API接口功能,参考表1。

设置一种传感器的数据采样间隔和数据上报间隔。

int32_t SetMode(int32_t sensorTypeId, SensorUser *user, int32_t mode)

+

int32_t SetMode(int32_t sensorId, int32_t mode)

设置一种传感器的工作模式,不同的工作模式,上报数据方式不同。

数据订阅操作

int32_t Register(RecordDataCallback cb)

+

int32_t Register(RecordDataCallback cb);

订阅者注册传感器数据回调函数,系统会将获取到的传感器数据上报给订阅者。

+ Sensor驱动模型对驱动开发者开放的功能接口,驱动开发者无需实现,直接使用,参考表2: **表 2** Sensor驱动模型对驱动开发者开放的功能接口列表 + - @@ -128,7 +133,7 @@ Sensor驱动模型对驱动开发者开放的功能接口,驱动开发者无 - @@ -140,16 +145,6 @@ Sensor驱动模型对驱动开发者开放的功能接口,驱动开发者无 - - - - - -

功能分类

接口名

@@ -118,7 +123,7 @@ Sensor驱动模型对驱动开发者开放的功能接口,驱动开发者无

添加当前类型的传感器设备到传感器设备管理。

int32_t DeleteSensorDevice(int32_t sensorId)

+

int32_t DeleteSensorDevice(const struct SensorBasicInfo *sensorBaseInfo)

删除传感器设备管理里指定的传感器设备。

上报指定类型传感器的数据到用户侧。

Sensor抽象总线和平台操作接口

+

Sensor抽象总线

int32_t ReadSensor(struct SensorBusCfg *busCfg, uint16_t regAddr, uint8_t *data, uint16_t dataLen)

按照配置的总线方式,传感器配置数据写入寄存器。

int32_t CreateSensorThread(struct OsalThread *thread, OsalThreadEntry threadEntry, char *name, void *entryPara)

-

创建指定传感器的定时线程,用于传感器数据上报处理。

-

void DestroySensorThread(struct OsalThread *thread, uint8_t *status);

-

销毁传感器创建的定时线程。

-

通用配置操作接口

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 { ## 测试指导 -驱动开发完成后,在传感器单元测试里面开发自测试用例,验证驱动基本功能。测试环境采用开发者自测试平台。 +- 驱动开发完成后,在传感器单元测试里面开发自测试用例,验证驱动基本功能。测试环境采用开发者自测试平台。 + ``` /* 标识是否上报传感器数据 */