diff --git a/zh-cn/device-dev/driver/driver-peripherals-light-des.md b/zh-cn/device-dev/driver/driver-peripherals-light-des.md index fa38732ca3b3d3334e75714df9a30b72df687edd..2e0ba1e5c9cdbf36e5eb07d1e83e241d463aed35 100644 --- a/zh-cn/device-dev/driver/driver-peripherals-light-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-light-des.md @@ -10,7 +10,6 @@ - [接口说明](###接口说明) - [开发步骤](###开发步骤) - - [开发实例](###开发实例) - [调测验证](###调测验证) @@ -60,20 +59,12 @@ Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模 | int32_t (*TurnOffLight)(uint32_t type) | 根据指定的灯类型关闭灯列表中可用的灯。 | ### 开发步骤 -1. 基于HDF驱动框架,按照驱动Driver Entry程序,完成Light抽象驱动开发(主要由Bind、Init、Release、Dispatch函数接口实现),资源配置及HCS解析。完成Light驱动的设备信息配置。 -3. 调用配置解析接口,完成器件属性信息解析,器件寄存器解析,并注册到Light设备管理中。 -3. 完成Light获取类型、闪烁和停止接口开发,会根据闪烁模式创建和销毁定时器。 - -### 开发实例 - -基于HDF驱动模型,加载启动Light驱动,代码形式如下,具体原理可参考[HDF驱动开发指南](driver-hdf-development.md)。本例中Light驱动通讯接口方式选择GPIO。 - -1. Light驱动的初始化和去初始化 +1. 基于HDF驱动框架,按照驱动Driver Entry程序,完成Light抽象驱动开发(主要由Bind、Init、Release、Dispatch函数接口实现),资源配置及HCS解析。完成Light驱动的设备信息配置。 - 调用HDF_INIT将驱动入口注册到HDF框架中。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 Light驱动模型使用HCS作为配置描述源码,HCS配置字段详细介绍请参考[配置管理](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf-manage.md)。 其Driver Entry入口函数定义如下: - + ```c /* 注册灯入口数据结构体对象 */ struct HdfDriverEntry g_lightDriverEntry = { @@ -86,7 +77,7 @@ Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模 /* 调用HDF_INIT将驱动入口注册到HDF框架中。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release函数释放驱动资源并退出 */ HDF_INIT(g_lightDriverEntry); ``` - + - 基于HDF驱动框架,按照驱动Driver Entry程序,完成Light抽象驱动开发,主要由Bind、Init、Release、Dispatch函数接口实现。 ```c @@ -172,12 +163,11 @@ Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模 (void)OsalMemFree(drvData); g_lightDrvData = NULL; } - ``` - Light设备管理模块负责系统中Light器件接口发布,在系统启动过程中,HDF框架机制通过灯Host里设备HCS配置信息,加载设备管理驱动。 - ```hcs + ``` /* 灯设备HCS配置 */ device_light :: device { device0 :: deviceNode { @@ -189,70 +179,42 @@ Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模 serviceName = "hdf_light"; // Light驱动对外发布服务的名称,必须唯一 deviceMatchAttr = "hdf_light_driver"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等 } - } ``` -2. 分配资源,解析灯HCS配置。 +2. 调用配置解析接口,完成器件属性信息解析,器件寄存器解析,并注册到Light设备管理中。 - - 解析HCS配置文件。 - - ```c - /* 分配资源,解析灯HCS配置 */ - static int32_t ParseLightInfo(const struct DeviceResourceNode *node) - { - ..... - /* 从HCS获取支持灯的类型个数 */ - drvData->lightNum = parser->GetElemNum(light, "lightType"); - .... - for (i = 0; i < drvData->lightNum; ++i) { - /* 获取类型 */ - ret = parser->GetUint32ArrayElem(light, "lightType", i, &temp, 0); - CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "lightType"); - } - - for (i = 0; i < drvData->lightNum; ++i) { - ..... - /* 类型作为下标开辟空间 */ - drvData->info[temp] = (struct LightDeviceInfo *)OsalMemCalloc(sizeof(struct LightDeviceInfo)); - ..... - /* 将Light设备信息进行填充 */ - ret = parser->GetUint32(light, "busRNum", &drvData->info[temp]->busRNum, 0); - CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "busRNum"); - ret = parser->GetUint32(light, "busGNum", &drvData->info[temp]->busGNum, 0); - CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "busGNum"); - ret = parser->GetUint32(light, "busBNum", &drvData->info[temp]->busBNum, 0); - CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "busBNum"); - ..... - return HDF_SUCCESS; - - } - ``` - - - 灯效果模型使用HCS作为配置描述源码,HCS配置字段详细介绍参考[配置管理](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf-manage.md)介绍。 - - ```hcs - /* 灯数据配置模板(light_config.hcs) */ - root { - lightConfig { - boardConfig { - match_attr = "hdf_light_driver"; - lightAttr { - light01 { - lightType = [1, 2]; // 灯类型 - busRNum = 31; // 红色对应的GPIO管脚 - busGNum = 30; // 绿色对应的GPIO管脚 - busBNum = 29; // 蓝色对应的GPIO管脚 - lightBrightness = 0X80000000;// RGB: R:16-31bit、G:8-15bit、B:0-7bit - onTime = 50; // 一个闪烁周期内亮灯时长(ms) - offTime = 50; // 一个闪烁周期内熄灯时长(ms) - } - } - } - } - } - ``` + ```c + /* 分配资源,解析灯HCS配置 */ + static int32_t ParseLightInfo(const struct DeviceResourceNode *node) + { + ..... + /* 从HCS获取支持灯的类型个数 */ + drvData->lightNum = parser->GetElemNum(light, "lightType"); + .... + for (i = 0; i < drvData->lightNum; ++i) { + /* 获取类型 */ + ret = parser->GetUint32ArrayElem(light, "lightType", i, &temp, 0); + CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "lightType"); + } + + for (i = 0; i < drvData->lightNum; ++i) { + ..... + /* 类型作为下标开辟空间 */ + drvData->info[temp] = (struct LightDeviceInfo *)OsalMemCalloc(sizeof(struct LightDeviceInfo)); + ..... + /* 将Light设备信息进行填充 */ + ret = parser->GetUint32(light, "busRNum", &drvData->info[temp]->busRNum, 0); + CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "busRNum"); + ret = parser->GetUint32(light, "busGNum", &drvData->info[temp]->busGNum, 0); + CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "busGNum"); + ret = parser->GetUint32(light, "busBNum", &drvData->info[temp]->busBNum, 0); + CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "busBNum"); + ..... + return HDF_SUCCESS; + } + ``` -3. 完成获取灯类型,闪烁和停止接口开发,会根据闪烁模式创建和销毁定时器。 +3. 完成Light获取类型、闪烁和停止接口开发,会根据闪烁模式创建和销毁定时器。 ```c /* Light驱动服务调用GetAllLightInfo获取灯类型,Enable接口启动闪烁模式, 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 df1a8f8c4e9d44de8cfa6d8a4a23327280910966..6122876321f65616dea51bc1dba60bf2f0ad4f2d 100755 --- a/zh-cn/device-dev/driver/driver-peripherals-sensor-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-sensor-des.md @@ -9,7 +9,6 @@ - [场景介绍](###场景介绍) - [接口说明](#section188213414114) - [开发步骤](#section7893102915819) - - [开发实例](#section257750691) - [调测验证](#section106021256121219) @@ -271,29 +270,11 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考[表3](#tab 接口实现参考[开发实例](#section257750691)章节。 ### 开发步骤 -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)。 -> ->- 需要开发人员实现部分有:传感器部分操作接口([表3](#table1083014911336))和传感器HCS差异化数据配置。 -> - 驱动基本功能验证。 - -### 开发实例 - -基于HDF驱动模型,加载启动加速度计传感器驱动,代码形式如下,具体原理可参考[HDF驱动开发指南](driver-hdf-development.md)。本例中加速度传感器选择博世BMI160,其通讯接口方式选择I2C。 - -1. 加速度传感器驱动入口注册 +1. 基于HDF驱动框架,按照驱动Driver Entry程序,完成加速度抽象驱动开发,主要由Bind、Init、Release、Dispatch函数接口实现。 - 加速度传感器驱动入口函数实现 - ``` + ```c /* 注册加速度计传感器入口数据结构体对象 */ struct HdfDriverEntry g_sensorAccelDevEntry = { .moduleVersion = 1, //加速度计传感器模块版本号 @@ -307,9 +288,144 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考[表3](#tab HDF_INIT(g_sensorAccelDevEntry); ``` - - 加速度传感器设备配置描述 + - 加速度传感器驱动操作接口实现 + + ```c + /* 加速度计传感器驱动对外提供的服务绑定到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 SensorCfgData *config, struct SensorDeviceInfo *deviceInfo) + { + CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM); + + deviceInfo->ops.Enable = SetAccelEnable; + deviceInfo->ops.Disable = SetAccelDisable; + deviceInfo->ops.SetBatch = SetAccelBatch; + deviceInfo->ops.SetMode = SetAccelMode; + deviceInfo->ops.SetOption = SetAccelOption; + + if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo), + &config->sensorInfo, sizeof(config->sensorInfo)) != EOK) { + HDF_LOGE("%s: Copy sensor info failed", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; + } + /* 提供给差异化驱动的初始化接口,完成加速度器件基本配置信息解析(加速度信息,加速度总线配置,加速度器件探测寄存器配置),器件探测,器件寄存器解析 */ + static int32_t InitAccelAfterDetected(struct SensorCfgData *config) + { + struct SensorDeviceInfo deviceInfo; + 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 (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) { + HDF_LOGE("%s: Add accel device failed", __func__); + return HDF_FAILURE; + } + /* 器件寄存器解析 */ + 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; + } + struct SensorCfgData *AccelCreateCfgData(const struct DeviceResourceNode *node) + { + …… + /* 如果探测不到器件在位,返回进行下个器件探测 */ + if (drvData->detectFlag) { + HDF_LOGE("%s: Accel sensor have detected", __func__); + return NULL; + } + 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; + goto BASE_CONFIG_EXIT; + } + 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 AccelInitDriver(struct HdfDeviceObject *device) + { + …… + /* 工作队列资源初始化 */ + if (InitAccelData(drvData) != HDF_SUCCESS) { + HDF_LOGE("%s: Init accel config failed", __func__); + return HDF_FAILURE; + } + /* 分配加速度配置信息资源 */ + drvData->accelCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*drvData->accelCfg)); + if (drvData->accelCfg == NULL) { + HDF_LOGE("%s: Malloc accel config data failed", __func__); + return HDF_FAILURE; + } + /* 注册寄存器分组信息 */ + drvData->accelCfg->regCfgGroup = &g_regCfgGroup[0]; + …… + return HDF_SUCCESS; + } + /* 释放驱动初始化时分配的资源 */ + void AccelReleaseDriver(struct HdfDeviceObject *device) + { + CHECK_NULL_PTR_RETURN(device); + struct AccelDrvData *drvData = (struct AccelDrvData *)device->service; + CHECK_NULL_PTR_RETURN(drvData); + /* 器件在位,释放已分配资源 */ + if (drvData->detectFlag) { + AccelReleaseCfgData(drvData->accelCfg); + } + OsalMemFree(drvData->accelCfg); + drvData->accelCfg = NULL; + /* 器件在位,销毁工作队列资源 */ + HdfWorkDestroy(&drvData->accelWork); + HdfWorkQueueDestroy(&drvData->accelWorkQueue); + OsalMemFree(drvData); + } + ``` + +2. 完成加速度传感器驱动的设备信息配置。 - 加速度传感器模型使用HCS作为配置描述源码,HCS配置字段请参考[配置管理](driver-hdf-manage.md)介绍。 + - 加速度传感器模型使用HCS作为配置描述源码,HCS配置字段请参考[配置管理](driver-hdf-manage.md)介绍。 ``` /* 加速度计传感器设备HCS配置 */ @@ -326,11 +442,9 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考[表3](#tab } ``` -2. 加速度传感器驱动操作接口实现 +3. 完成加速度传感器抽象驱动内部接口开发,包括Enable、Disable、SetBatch、SetMode、SetOption、AccelCreateCfgData、AccelReleaseCfgData、AccelRegisterChipOps接口实现。 - 开发者需要根据每种类型的传感器实现归一化接口。 - - ``` + ```c /* 不使用函数暂时置空 */ static int32_t SetAccelInfo(struct SensorBasicInfo *info) { @@ -427,7 +541,6 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考[表3](#tab (void)option; return HDF_SUCCESS; } - /* 设置传感器可选配置 */ static int32_t SetAccelOption(uint32_t option) { @@ -436,329 +549,100 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考[表3](#tab } ``` -3. 加速度传感器驱动初始化和去初始化 +4. 基于HDF驱动框架,按照驱动Driver Entry程序,完成加速度传感器差异化驱动开发,主要有Bind、Init、Release、Dispatch函数接口实现。 - ``` - /* 加速度计传感器驱动对外提供的服务绑定到HDF框架 */ - int32_t AccelBindDriver(struct HdfDeviceObject *device) + ```c + /* 加速度计传感器差异化驱动消息交互 */ + static int32_t DispatchBMI160(struct HdfDeviceIoClient *client, + int cmd, struct HdfSBuf *data, struct HdfSBuf *reply) + { + (void)client; + (void)cmd; + (void)data; + (void)reply; + + return HDF_SUCCESS; + } + /* 加速度计传感器差异化驱动对外提供的服务绑定到HDF框架 */ + int32_t Bmi160BindDriver(struct HdfDeviceObject *device) { CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); - struct AccelDrvData *drvData = (struct AccelDrvData *)OsalMemCalloc(sizeof(*drvData)); + struct Bmi160DrvData *drvData = (struct Bmi160DrvData *)OsalMemCalloc(sizeof(*drvData)); if (drvData == NULL) { - HDF_LOGE("%s: Malloc accel drv data fail!", __func__); + HDF_LOGE("%s: Malloc Bmi160 drv data fail", __func__); return HDF_ERR_MALLOC_FAIL; } - drvData->ioService.Dispatch = DispatchAccel; + drvData->ioService.Dispatch = DispatchBMI160; drvData->device = device; device->service = &drvData->ioService; - g_accelDrvData = drvData; + g_bmi160DrvData = drvData; + return HDF_SUCCESS; } - - /* 注册加速度计传感器驱动归一化的接口函数 */ - static int32_t InitAccelOps(struct SensorCfgData *config, struct SensorDeviceInfo *deviceInfo) + /* 加速度计传感器差异化驱动初始化 */ + int32_t Bmi160InitDriver(struct HdfDeviceObject *device) { - CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM); + int32_t ret; + struct AccelOpsCall ops; - deviceInfo->ops.Enable = SetAccelEnable; - deviceInfo->ops.Disable = SetAccelDisable; - deviceInfo->ops.SetBatch = SetAccelBatch; - deviceInfo->ops.SetMode = SetAccelMode; - deviceInfo->ops.SetOption = SetAccelOption; + CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM); + struct Bmi160DrvData *drvData = (struct Bmi160DrvData *)device->service; + CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); - if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo), - &config->sensorInfo, sizeof(config->sensorInfo)) != EOK) { - HDF_LOGE("%s: Copy sensor info failed", __func__); + ret = InitAccelPreConfig(); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: Init BMI160 bus mux config", __func__); return HDF_FAILURE; } - return HDF_SUCCESS; - } - /* 提供给差异化驱动的初始化接口,完成加速度器件基本配置信息解析(加速度信息,加速度总线配置,加速度器件探测寄存器配置),器件探测,器件寄存器解析 */ - static int32_t InitAccelAfterDetected(struct SensorCfgData *config) - { - struct SensorDeviceInfo deviceInfo; - 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 (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) { - HDF_LOGE("%s: Add accel device failed", __func__); - return HDF_FAILURE; - } - /* 器件寄存器解析 */ - 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; - } - struct SensorCfgData *AccelCreateCfgData(const struct DeviceResourceNode *node) - { - …… - /* 如果探测不到器件在位,返回进行下个器件探测 */ - if (drvData->detectFlag) { - HDF_LOGE("%s: Accel sensor have detected", __func__); - return NULL; - } - 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; - goto BASE_CONFIG_EXIT; + drvData->sensorCfg = AccelCreateCfgData(device->property); + if (drvData->sensorCfg == NULL || drvData->sensorCfg->root == NULL) { + HDF_LOGD("%s: Creating accelcfg failed because detection failed", __func__); + return HDF_ERR_NOT_SUPPORT; } - 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) - { - int32_t AccelInitDriver(struct HdfDeviceObject *device) - { - …… - /* 工作队列资源初始化 */ - if (InitAccelData(drvData) != HDF_SUCCESS) { - HDF_LOGE("%s: Init accel config failed", __func__); + + ops.Init = NULL; + ops.ReadData = ReadBmi160Data; + ret = AccelRegisterChipOps(&ops); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: Register BMI160 accel failed", __func__); return HDF_FAILURE; } - /* 分配加速度配置信息资源 */ - drvData->accelCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*drvData->accelCfg)); - if (drvData->accelCfg == NULL) { - HDF_LOGE("%s: Malloc accel config data failed", __func__); + + ret = InitBmi160(drvData->sensorCfg); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: Init BMI160 accel failed", __func__); return HDF_FAILURE; } - /* 注册寄存器分组信息 */ - drvData->accelCfg->regCfgGroup = &g_regCfgGroup[0]; - …… + return HDF_SUCCESS; } - /* 释放驱动初始化时分配的资源 */ - void AccelReleaseDriver(struct HdfDeviceObject *device) + void Bmi160ReleaseDriver(struct HdfDeviceObject *device) { - CHECK_NULL_PTR_RETURN(device); - struct AccelDrvData *drvData = (struct AccelDrvData *)device->service; - CHECK_NULL_PTR_RETURN(drvData); - /* 器件在位,释放已分配资源 */ - if (drvData->detectFlag) { - AccelReleaseCfgData(drvData->accelCfg); + ...... + if (drvData->sensorCfg != NULL) { + AccelReleaseCfgData(drvData->sensorCfg); + drvData->sensorCfg = NULL; } - OsalMemFree(drvData->accelCfg); - drvData->accelCfg = NULL; - /* 器件在位,销毁工作队列资源 */ - HdfWorkDestroy(&drvData->accelWork); - HdfWorkQueueDestroy(&drvData->accelWorkQueue); OsalMemFree(drvData); } + /* 加速度传感器差异化驱动对应的HdfDriverEntry对象 */ + struct HdfDriverEntry g_accelBmi160DevEntry = { + .moduleVersion = 1, + .moduleName = "HDF_SENSOR_ACCEL_BMI160", + .Bind = Bmi160BindDriver, + .Init = Bmi160InitDriver, + .Release = Bmi160ReleaseDriver, + }; + HDF_INIT(g_accelBmi160DevEntry); ``` -4. 加速度传感器差异化驱动私有HCS配置实现 - - - 为了方便开发者使用传感器HCS私有配置,在sensor_common.hcs里面定义通用的传感器配置模板。 - - ``` - accel sensor common config template - root { - sensorAccelConfig { - accelChipConfig { - /* 传感器设备信息模板 */ - template sensorInfo { - sensorName = "accelerometer"; // 加速度计名字,字符最大长度16字节 - vendorName = "borsh_bmi160"; // 传感器设备厂商,字符最大长度16字节 - firmwareVersion = "1.0"; // 传感器固件版本号,默认1.0,字符最大长度16字节 - hardwareVersion = "1.0"; // 传感器硬件版本号,默认1.0,字符最大长度16字节 - sensorTypeId = 1; // 传感器类型编号,详见{@link SensorTypeTag} - sensorId = 1; // 传感器的标识号,有传感器驱动开发者定义,推荐用{@link SensorTypeTag}枚举 - maxRange = 8; // 传感器的最大量程,根据开发者需要配置 - accuracy = 0; // 传感器的精度,与上报数据配合使用,上报数据结构体{@link SensorEvents } - power = 230; // 传感器的功耗 - } - /* 传感器使用的总线类型和配置信息模板 */ - template sensorBusConfig { - busType = 0; // 0:i2c 1:spi - busNum = 6; // 芯片上分配给传感器的器件号 - busAddr = 0; // 芯片上分配给传感器的地址 - regWidth = 1; // 传感器寄存器地址宽度 - regBigEndian = 0; // 传感器寄存器大小端 - } - /* 传感器设备属性模板 */ - template sensorAttr { - chipName = ""; // 传感器芯片名字 - chipIdRegister = 0xf; // 传感器在位检测寄存器地址 - chipIdValue = 0xd1; // 校验传感器在位检测寄存器值 - } - } - } - } - ``` - - - 开发者配置accel_bmi160_config.hcs文件时,引用加速度传感器的模板,并根据需要修改模板中继承的字段。如果需要新增寄存器配置字段,在配置传感器HCS后扩展。 - - ``` - /* 根据不同器件硬件差异,修改模板配置,不修改的就会默认采用模板配置 */ - #include "accel_config.hcs" - root { - 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; // 1 btye - } - 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 - ]; - } - } - } - ``` - -5. 加速度传感器差异化驱动实现 - - - 定义加速度传感器差异化驱动对应的HdfDriverEntry对象,其中Driver Entry入口函数定义如下: - - ``` - struct HdfDriverEntry g_accelBmi160DevEntry = { - .moduleVersion = 1, - .moduleName = "HDF_SENSOR_ACCEL_BMI160", - .Bind = Bmi160BindDriver, - .Init = Bmi160InitDriver, - .Release = Bmi160ReleaseDriver, - }; - HDF_INIT(g_accelBmi160DevEntry); - ``` - - - Bind驱动接口实例化。 - - ``` - 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; - } - ``` - - - Init驱动接口实例化。 - - ``` - int32_t Bmi160InitDriver(struct HdfDeviceObject *device) - { - …… - /* 加速度计差异化初始化配置 */ - ret = InitAccelPreConfig(); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: Init BMI160 bus mux config", __func__); - return HDF_FAILURE; - } - /* 创建传感器配置数据接口,完成器件探测,私有数据配置解析 */ - 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; - } - ``` - - - Release驱动接口实例化。 - - ``` - void Bmi160ReleaseDriver(struct HdfDeviceObject *device) - { - 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); - } - ``` - -6. 加速度传感器差异化函数接口实现 - - 需要开发者实现的ReadBmi160Data接口函数,在Bmi160InitDriver函数里面注册此函数。 +5. 完成加速度传感器差异化驱动中差异化接口ReadData函数实现。 - ``` + ```c int32_t ReadBmi160Data(struct SensorCfgData *data) { int32_t ret; @@ -783,51 +667,12 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考[表3](#tab } ``` -7. 主要的数据结构 - - ``` - /* 传感器2g对应灵敏度转换值 */ - #define BMI160_ACC_SENSITIVITY_2G 61 - /* 传感器数据采样寄存器地址 */ - #define BMI160_ACCEL_X_LSB_ADDR 0X12 - #define BMI160_ACCEL_X_MSB_ADDR 0X13 - #define BMI160_ACCEL_Y_LSB_ADDR 0X14 - #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, - ACCEL_Y_AXIS = 1, - ACCEL_Z_AXIS = 2, - ACCEL_AXIS_NUM = 3, - }; - /* 传感器每个维度值 */ - struct AccelData { - int32_t x; - int32_t y; - int32_t z; - }; - /* 传感器私有数据结构体 */ - struct AccelDrvData { - struct IDeviceIoService ioService; - struct HdfDeviceObject *device; - HdfWorkQueue accelWorkQueue; - HdfWork accelWork; - OsalTimer accelTimer; - bool detectFlag; - bool enable; - int64_t interval; - struct SensorCfgData *accelCfg; - struct AccelOpsCall ops; - }; - /* 差异化适配函数 */ - struct AccelOpsCall { - int32_t (*Init)(struct SensorCfgData *data); - int32_t (*ReadData)(struct SensorCfgData *data); - }; - ``` +>![](../public_sys-resources/icon-note.gif) **说明:** +> +>- 传感器驱动模型已经提供一部分能力集,包括驱动设备管理能力、抽象总线和平台操作接口能力、通用配置操作接口能力、配置解析操作接口能力,接口参考[表2](#table1156812588320)。 +> +>- 需要开发人员实现部分有:传感器部分操作接口([表3](#table1083014911336))和传感器HCS差异化数据配置。 +> - 驱动基本功能验证。 ### 调测验证 diff --git a/zh-cn/device-dev/driver/driver-peripherals-vibrator-des.md b/zh-cn/device-dev/driver/driver-peripherals-vibrator-des.md index e92fd0ab496e656479f4bee17d6125bbcfb93a57..50aab04131508567f003a8da6eb490f13d3ac200 100755 --- a/zh-cn/device-dev/driver/driver-peripherals-vibrator-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-vibrator-des.md @@ -11,7 +11,6 @@ - [场景介绍](###场景介绍) - [接口说明](###接口说明) - [开发步骤](###开发步骤) - - [开发实例](###开发实例) ## 概述 @@ -79,17 +78,10 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能力接口,包括马达一次振动、马达效果配置震动、马达停止。基于HDF(Hardware Driver Foundation)驱动框架开发的马达驱动模型,实现跨操作系统迁移、器件差异配置等功能。马达具体的开发步骤如下: 1. 基于HDF驱动框架,按照驱动Driver Entry程序,完成马达抽象驱动开发,主要由Bind、Init、Release、Dispatch函数接口实现,配置资源和HCS解析。 -2. 创建马达效果模型,解析马达效果HCS配置。 -3. 完成马达振动和停止接口开发,会根据振动效果的模式创建和销毁定时器。 -4. 马达驱动模型提供给开发者马达驱动差异化接口,开发者实现差异化接口。 - -### 开发实例 - -1. 马达驱动的初始化和去初始化 - 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出马达驱动模型,使用HCS作为配置描述源码。HCS配置字段详细介绍参考[配置管理](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf-manage.md)。其中Driver Entry入口函数定义如下: - ``` + ```c /* 注册马达抽象驱动入口数据结构体对象 */ struct HdfDriverEntry g_vibratorDriverEntry = { .moduleVersion = 1, //马达模块版本号 @@ -99,12 +91,12 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 .Release = ReleaseVibratorDriver, //马达资源释放函数 }; - HDF_INIT(g_vibratorDriverEntry); + HDF_INIT(g_vibratorDriverEntry); ``` - 基于HDF驱动框架,按照驱动Driver Entry程序,完成马达抽象驱动开发,主要由Bind、Init、Release、Dispatch函数接口实现。 - ``` + ```c /* 马达驱动对外发布的能力 */ static int32_t DispatchVibrator(struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply) @@ -164,10 +156,10 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 g_vibratorDrvData = NULL; } ``` - + - 在系统启动过程中,HDF设备管理模块通过设备HCS配置信息,加载马达抽象驱动,并对外发布马达驱动接口。 - - ``` + + ```c /* 马达设备HCS配置 */ vibrator :: host { hostName = "vibrator_host"; @@ -183,12 +175,12 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 } } ``` - + 2. 创建马达效果模型,解析马达效果HCS配置。 - 创建马达效果模型。 - ``` + ```hcs /* 创建马达效果模型,分配资源,解析马达效果HCS配置 */ int32_t CreateVibratorHaptic(struct HdfDeviceObject *device) { @@ -254,7 +246,7 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 马达硬件服务调用StartOnce接口动态配置持续振动时间;调用StartEffect接口启动静态配置的振动效果,为驱动开发者提供抽象的配置接口能力。 - ``` + ```c /* 按照指定持续时间触发振动马达,duration为振动持续时长 */ static int32_t StartOnce(struct HdfSBuf *data, struct HdfSBuf *reply) { @@ -326,7 +318,7 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 - 在差异化器件驱动初始化成功时,注册差异实现接口,方便实现器件差异的驱动接口。 - ``` + ```c /* 注册马达差异化实现接口 */ int32_t RegisterVibrator(struct VibratorOps *ops) { @@ -347,7 +339,7 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 - 马达驱动模型提供给开发者马达驱动差异化接口,具体实现如下: - ``` + ```c /* 按照指定持续时间触发线性马达的振动 */ static int32_t StartLinearVibrator() {