提交 6d958c98 编写于 作者: S sunxuejiao

modify sensor/vibrator/light file

Signed-off-by: Nsunxuejiao <sunxuejiao5@huawei.com>
上级 32d0bfc9
......@@ -10,7 +10,6 @@
- [接口说明](###接口说明)
- [开发步骤](###开发步骤)
- [开发实例](###开发实例)
- [调测验证](###调测验证)
......@@ -61,14 +60,6 @@ Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模
### 开发步骤
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驱动的初始化和去初始化
- 调用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)
......@@ -172,12 +163,11 @@ Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模
(void)OsalMemFree(drvData);
g_lightDrvData = NULL;
}
```
- Light设备管理模块负责系统中Light器件接口发布,在系统启动过程中,HDF框架机制通过灯Host里设备HCS配置信息,加载设备管理驱动。
```hcs
```
/* 灯设备HCS配置 */
device_light :: device {
device0 :: deviceNode {
......@@ -189,12 +179,9 @@ Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模
serviceName = "hdf_light"; // Light驱动对外发布服务的名称,必须唯一
deviceMatchAttr = "hdf_light_driver"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等
}
}
```
2. 分配资源,解析灯HCS配置。
- 解析HCS配置文件。
2. 调用配置解析接口,完成器件属性信息解析,器件寄存器解析,并注册到Light设备管理中。
```c
/* 分配资源,解析灯HCS配置 */
......@@ -224,35 +211,10 @@ Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模
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)
}
}
}
}
}
```
3. 完成获取灯类型,闪烁和停止接口开发,会根据闪烁模式创建和销毁定时器。
3. 完成Light获取类型、闪烁和停止接口开发,会根据闪烁模式创建和销毁定时器。
```c
/* Light驱动服务调用GetAllLightInfo获取灯类型,Enable接口启动闪烁模式,
......
......@@ -9,7 +9,6 @@
- [场景介绍](###场景介绍)
- [接口说明](#section188213414114)
- [开发步骤](#section7893102915819)
- [开发实例](#section257750691)
- [调测验证](#section106021256121219)
......@@ -272,28 +271,10 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考[表3](#tab
### 开发步骤<a name="section7893102915819"></a>
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差异化数据配置。
> - 驱动基本功能验证。
### 开发实例<a name="section257750691"></a>
基于HDF驱动模型,加载启动加速度计传感器驱动,代码形式如下,具体原理可参考[HDF驱动开发指南](driver-hdf-development.md)。本例中加速度传感器选择博世BMI160,其通讯接口方式选择I2C。
1. 加速度传感器驱动入口注册
- 加速度传感器驱动入口函数实现
```
```c
/* 注册加速度计传感器入口数据结构体对象 */
struct HdfDriverEntry g_sensorAccelDevEntry = {
.moduleVersion = 1, //加速度计传感器模块版本号
......@@ -307,138 +288,9 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考[表3](#tab
HDF_INIT(g_sensorAccelDevEntry);
```
- 加速度传感器设备配置描述
加速度传感器模型使用HCS作为配置描述源码,HCS配置字段请参考[配置管理](driver-hdf-manage.md)介绍。
```
/* 加速度计传感器设备HCS配置 */
device_sensor_accel :: device {
device0 :: deviceNode {
policy = 1; // 驱动服务发布的策略
priority = 110; // 驱动启动优先级(0-200),值越大优先级越低,建议配置为100,优先级相同则不保证device的加载顺序
preload = 0; // 驱动按需加载字段,0表示加载,2表示不加载
permission = 0664; // 驱动创建设备节点权限
moduleName = "HDF_SENSOR_ACCEL"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致
serviceName = "sensor_accel"; // 驱动对外发布服务的名称,必须唯一
deviceMatchAttr = "hdf_sensor_accel_driver"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等
}
}
```
2. 加速度传感器驱动操作接口实现
开发者需要根据每种类型的传感器实现归一化接口。
```
/* 不使用函数暂时置空 */
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();
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;
}
/* 下发去使能寄存器组的配置 */
static int32_t SetAccelDisable(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 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;
struct AccelDrvData *drvData = NULL;
drvData = AccelGetDrvData();
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. 加速度传感器驱动初始化和去初始化
- 加速度传感器驱动操作接口实现
```
```c
/* 加速度计传感器驱动对外提供的服务绑定到HDF框架 */
int32_t AccelBindDriver(struct HdfDeviceObject *device)
{
......@@ -533,8 +385,6 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考[表3](#tab
……
}
/* 加速度计传感器驱动初始化入口函数,主要功能为对传感器私有数据的结构体对象进行初始化,传感器HCS数据配置对象空间分配,传感器HCS数据配置初始化入口函数调用,传感器设备探测是否在位功能,传感器数据上报定时器创建,传感器归一化接口注册,传感器设备注册功能 */
int32_t InitAccelDriver(struct HdfDeviceObject *device)
{
int32_t AccelInitDriver(struct HdfDeviceObject *device)
{
……
......@@ -554,7 +404,6 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考[表3](#tab
……
return HDF_SUCCESS;
}
/* 释放驱动初始化时分配的资源 */
void AccelReleaseDriver(struct HdfDeviceObject *device)
{
......@@ -574,155 +423,186 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考[表3](#tab
}
```
4. 加速度传感器差异化驱动私有HCS配置实现
2. 完成加速度传感器驱动的设备信息配置。
- 为了方便开发者使用传感器HCS私有配置,在sensor_common.hcs里面定义通用的传感器配置模板
- 加速度传感器模型使用HCS作为配置描述源码,HCS配置字段请参考[配置管理](driver-hdf-manage.md)介绍
```
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; // 校验传感器在位检测寄存器值
/* 加速度计传感器设备HCS配置 */
device_sensor_accel :: device {
device0 :: deviceNode {
policy = 1; // 驱动服务发布的策略
priority = 110; // 驱动启动优先级(0-200),值越大优先级越低,建议配置为100,优先级相同则不保证device的加载顺序
preload = 0; // 驱动按需加载字段,0表示加载,2表示不加载
permission = 0664; // 驱动创建设备节点权限
moduleName = "HDF_SENSOR_ACCEL"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致
serviceName = "sensor_accel"; // 驱动对外发布服务的名称,必须唯一
deviceMatchAttr = "hdf_sensor_accel_driver"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等
}
}
```
3. 完成加速度传感器抽象驱动内部接口开发,包括Enable、Disable、SetBatch、SetMode、SetOption、AccelCreateCfgData、AccelReleaseCfgData、AccelRegisterChipOps接口实现。
```c
/* 不使用函数暂时置空 */
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();
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;
}
```
- 开发者配置accel_bmi160_config.hcs文件时,引用加速度传感器的模板,并根据需要修改模板中继承的字段。如果需要新增寄存器配置字段,在配置传感器HCS后扩展。
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;
}
```
/* 根据不同器件硬件差异,修改模板配置,不修改的就会默认采用模板配置 */
#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
];
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;
}
```
/* 下发去使能寄存器组的配置 */
static int32_t SetAccelDisable(void)
{
int32_t ret;
struct AccelDrvData *drvData = AccelGetDrvData();
5. 加速度传感器差异化驱动实现
CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM);
- 定义加速度传感器差异化驱动对应的HdfDriverEntry对象,其中Driver Entry入口函数定义如下:
if (!drvData->enable) {
HDF_LOGE("%s: Accel sensor had disable", __func__);
return HDF_SUCCESS;
}
```
struct HdfDriverEntry g_accelBmi160DevEntry = {
.moduleVersion = 1,
.moduleName = "HDF_SENSOR_ACCEL_BMI160",
.Bind = Bmi160BindDriver,
.Init = Bmi160InitDriver,
.Release = Bmi160ReleaseDriver,
};
HDF_INIT(g_accelBmi160DevEntry);
```
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;
- Bind驱动接口实例化。
struct AccelDrvData *drvData = NULL;
drvData = AccelGetDrvData();
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;
}
```
4. 基于HDF驱动框架,按照驱动Driver Entry程序,完成加速度传感器差异化驱动开发,主要有Bind、Init、Release、Dispatch函数接口实现。
```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 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)
{
……
/* 加速度计差异化初始化配置 */
int32_t ret;
struct AccelOpsCall ops;
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);
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) {
if (drvData->sensorCfg == NULL || drvData->sensorCfg->root == NULL) {
HDF_LOGD("%s: Creating accelcfg failed because detection failed", __func__);
return HDF_ERR_NOT_SUPPORT;
}
/* 注册差异化接口 */
ops.Init = NULL;
ops.ReadData = ReadBmi160Data;
ret = AccelRegisterChipOps(&ops);
......@@ -730,35 +610,39 @@ Sensor驱动模型要求驱动开发者实现的接口功能,参考[表3](#tab
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);
......
if (drvData->sensorCfg != NULL) {
AccelReleaseCfgData(drvData->sensorCfg);
drvData->sensorCfg = NULL;
}
OsalMemFree(drvData);
}
/* 加速度传感器差异化驱动对应的HdfDriverEntry对象 */
struct HdfDriverEntry g_accelBmi160DevEntry = {
.moduleVersion = 1,
.moduleName = "HDF_SENSOR_ACCEL_BMI160",
.Bind = Bmi160BindDriver,
.Init = Bmi160InitDriver,
.Release = Bmi160ReleaseDriver,
};
HDF_INIT(g_accelBmi160DevEntry);
```
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差异化数据配置。
> - 驱动基本功能验证。
### 调测验证<a name="section106021256121219"></a>
......
......@@ -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, //马达模块版本号
......@@ -104,7 +96,7 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能
- 基于HDF驱动框架,按照驱动Driver Entry程序,完成马达抽象驱动开发,主要由Bind、Init、Release、Dispatch函数接口实现。
```
```c
/* 马达驱动对外发布的能力 */
static int32_t DispatchVibrator(struct HdfDeviceIoClient *client,
int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
......@@ -167,7 +159,7 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能
- 在系统启动过程中,HDF设备管理模块通过设备HCS配置信息,加载马达抽象驱动,并对外发布马达驱动接口。
```
```c
/* 马达设备HCS配置 */
vibrator :: host {
hostName = "vibrator_host";
......@@ -188,7 +180,7 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能
- 创建马达效果模型。
```
```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()
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册