SENSOR

About 26 min

SENSOR

概述

Sensor(传感器)驱动模块为上层Sensor服务系统提供稳定的Sensor基础能力API,包括Sensor列表查询、Sensor启停、Sensor订阅及去订阅,Sensor参数配置等功能;基于HDF(Hardware Driver Foundation)驱动框架开发的Sensor驱动模型,实现跨操作系统迁移,器件差异配置等功能。Sensor驱动模型如下图1所示:

图 1 Sensor驱动模型图

Sensor驱动模型对外开放的API接口能力如下:

  • 提供Sensor HDI(Hardware Driver Interface)能力接口,简化服务开发。
  • 提供Sensor驱动模型能力接口:依赖HDF驱动框架实现Sensor器件驱动的注册,加载,去注册,器件探测等能力,提供同一类型Sensor器件驱动归一接口, 寄存器配置解析操作接口,总线访问抽象接口,平台抽象接口。
  • 提供开发者实现的能力接口:依赖HDF驱动框架的HCS(HDF Configuration Source)配置管理,根据同类型Sensor差异化配置,实现Sensor器件参数序列化配置和器件部分操作接口,简化Sensor器件驱动开发。

接口说明

Sensor驱动模型对HDI开放的API接口功能,参考表1。

表 1 Sensor驱动模型对外API接口功能介绍

功能分类

接口名

功能描述

查询操作

int32_t GetAllSensors(struct SensorInformation **sensorInfo, int32_t *count)

获取系统中注册的所有传感器信息,一种类型传感器信息包括传感器名字、设备厂商、固件版本号、硬件版本号、传感器类型编号、传感器标识、最大量程、精度、功耗。

配置操作

int32_t Enable(int32_t sensorId)

使能一种传感器设备,只有数据订阅者使能传感器后,才能获取订阅的传感器数据。

int32_t Disable(int32_t sensorId)

去使能一种传感器设备。

int32_t SetBatch(iint32_t sensorId, int64_t samplingInterval, int64_t reportInterval)

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

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

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

int32_t SetOption(int32_t sensorId, uint32_t option)

设置一种传感器量程,精度等可选配置。

数据订阅操作

int32_t Register(RecordDataCallback cb)

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

int32_t Unregister(void)

订阅者去注册传感器数据回调函数。

接口实例

const struct SensorInterface *NewSensorInterfaceInstance(void)

创建传感器接口实例。

int32_t FreeSensorInterfaceInstance(void)

释放传感器接口实例。

Sensor驱动模型对驱动开发者开放的功能接口,驱动开发者无需实现,直接使用,参考表2:

表 2 Sensor驱动模型对驱动开发者开放的功能接口列表

功能分类

接口名

功能描述

设备管理操作接口

int32_t AddSensorDevice(const struct SensorDeviceInfo *deviceInfo)

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

int32_t DeleteSensorDevice(int32_t sensorId)

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

int32_t ReportSensorEvent(const struct SensorReportEvent *events)

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

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

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

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

int32_t WriteSensor(struct SensorBusCfg *busCfg, uint8_t *writeData, uint16_t len)

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

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);

根据传感器总线类型信息,下发寄存器分组配置。

配置解析操作接口

int32_t GetSensorBaseConfigData(const struct DeviceResourceNode *node, struct SensorCfgData *config)

根据传感器设备HCS资源配置,获取传感器信息,总线配置信息,属性配置等基本配置信息,并初始化对应的基本配置数据结构体。

int32_t ParseSensorRegConfig(struct SensorCfgData *config)

根据传感器设备HCS资源配置,解析寄存器分组信息,并初始化配置数据结构体。

void ReleaseSensorAllRegConfig(struct SensorCfgData *config)

释放传感器配置数据结构体里分配的资源。

int32_t GetSensorBusHandle(struct SensorBusCfg *busCfg)

获取传感器总线句柄信息。

int32_t ReleaseSensorBusHandle(struct SensorBusCfg *busCfg)

释放传感器句柄信息。

Sensor驱动模型要求驱动开发者实现的接口功能,参考表3

表 3 Sensor驱动模型要求驱动开发者实现的接口列表

功能分类

接口名

功能描述

基本功能操作

int32_t init(void)

传感器器设备探测成功后,需要对传感器器设备初始化配置。

int32_t GetInfo(struct SensorBasicInfo *info)

从传感器器设备的HCS配置里,获取当前传感器设备的基本信息。

int32_t Enable(void)

根据当前传感器器设备的HCS配置,下发传感器设备使能操作组的寄存器配置。

int32_t Disable(void)

根据当前传感器器设备的HCS配置,下发传感器设备去使能操作组的寄存器配置。

int32_t SetBatch(int64_t samplingInterval, int64_t reportInterval)

根据数据采样率和数据上报间隔,配置当前传感器设备的数据上报线程处理时间。

int32_t SetMode(int32_t mode)

配置当前传感器设备数据上报方式。

int32_t SetOption(uint32_t option)

根据可选配置,下发量程,精度等寄存器配置。

void ReadSensorData(void)

实现传感器的数据读取函数。

接口实现参考SENSOR章节。

开发指导

Sensor驱动是基于HDF框架、PLATFORM和OSAL基础接口进行开发,不区分操作系统和芯片平台,为不同Sensor器件提供统一的驱动模型。本篇开发指导以加速度计传感器为例,介绍传感器驱动开发。

开发步骤

  1. 加速度计传感器驱动注册。HDF驱动框架会提供统一的驱动管理模型,通过加速计传感器模块配置信息,识别并加载对应模块驱动。
  2. 加速度计传感器驱动初始化和去初始化。HDF驱动框架通过init入口函数,依次启动传感器设备驱动加载和分配传感器设备数据配置资源。HDF驱动框架通过release函数,释放驱动加载的资源和配置。
  3. 加速度计传感器寄存器组配置解析。不同类型传感器需要在hcs里配置器件对应的HCS配置文件,然后再设备驱动启动过程中探测器件是否在位,然后加载对应的配置文件,生成配置的结构体对象。
  4. 加速度计传感器驱动操作接口实现。实现各个类型传感器归一化驱动接口,如init,GetInfo,Enable,Disable,SetBatch,SetMode,SetOption,ReadSensorData等函数,完成传感器驱动配置下发和数据上报功能。

说明: 传感器驱动模型已经提供一部分能力集,包括驱动设备管理能力,抽象总线和平台操作接口能力,通用配置操作接口能力,配置解析操作接口能力,接口参考表2。需要开发人员实现部分有:1、传感器部分操作接口(表3);2、传感器HCS差异化数据配置;3、驱动基本功能验证。

开发实例

基于HDF驱动模型,加载启动加速度计传感器驱动,代码形式如下,具体原理可参考HDF驱动开发指南。加速度传感器选择通讯接口方式为I2C,厂家选择博世BMI160加速度传感器。

  1. 加速度计传感器驱动入口注册
  • 加速度计传感器驱动入口函数实现
/* 注册加速度计传感器入口数据结构体对象 */
struct HdfDriverEntry g_sensorAccelDevEntry = {
    .moduleVersion = 1, /* 加速度计传感器模块版本号 */
    .moduleName = "HDF_SENSOR_ACCEL", /* 加速度计传感器模块名,要与device_info.hcs文件里的加速度计moduleName字段值一样*/
    .Bind = BindAccelDriver, /* 加速度计传感器绑定函数 */
    .Init = InitAccelDriver, /* 加速度计传感器初始化函数 */
    .Release = ReleaseAccelDriver, /* 加速度计传感器资源释放函数 */
};

/* 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出 */
HDF_INIT(g_sensorAccelDevEntry);
1
2
3
4
5
6
7
8
9
10
11
  • 加速度计传感器设备配置描述

加速度传感器模型使用HCS作为配置描述源码,HCS配置字段详细介绍参考配置管理介绍。

/* 加速度计传感器设备HCS配置 */
device_sensor_accel :: device {
    device0 :: deviceNode {
        policy = 1; /* policy字段是驱动服务发布的策略 */
        priority = 105; /* 驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序 */
        preload = 2; /* 驱动按需加载字段,0表示加载,2表示不加载 */
        permission = 0664; /* 驱动创建设备节点权限 */
        moduleName = "HDF_SENSOR_ACCEL"; /* 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 */
        serviceName = "sensor_accel"; /* 驱动对外发布服务的名称,必须唯一 */
        deviceMatchAttr = "hdf_sensor_accel_driver"; /* 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等 */
    }
} 
1
2
3
4
5
6
7
8
9
10
11
12
  1. 加速度计传感器驱动初始化和去初始化
  • 初始化入口函数init
/* 加速度计传感器驱动对外提供的服务绑定到HDF框架 */
int32_t BindAccelDriver(struct HdfDeviceObject *device)
{
    CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);

    static struct IDeviceIoService service = {
        .object = {0},
        .Dispatch = DispatchAccel,
    };
    device->service = &service;

    return HDF_SUCCESS;
}
/*在探测到器件在位后,需要调用RegisterAccelChipOps注册差异化适配函数*/
int32_t RegisterAccelChipOps(struct AccelOpsCall *ops)
{
    struct AccelDrvData *drvData = NULL;

    CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM);

    drvData = AccelGetDrvData();
    drvData->ops.Init = ops->Init;
    drvData->ops.ReadData = ops->ReadData;
    return HDF_SUCCESS;
}
/* 挂载加速度计传感器驱动归一化的接口函数 */
static int32_t InitAccelOps(struct SensorDeviceInfo *deviceInfo)
{
    struct AccelDrvData *drvData = AccelGetDrvData();

    (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;
    deviceInfo->ops.SetMode = SetAccelMode;
    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__);
        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)
{
    struct SensorDeviceInfo deviceInfo;

    if (InitAccelConfig() != HDF_SUCCESS) {
        HDF_LOGE("%s: init accel config failed", __func__);
        return HDF_FAILURE;
    }

    if (InitAccelOps(&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;
    }

    return HDF_SUCCESS;
}
/*通过器件探测函数,挂载器件差异化函数接口*/
static int32_t DetectAccelChip(void)
{
    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 (loop == num) {
        HDF_LOGE("%s: detect accel device failed", __func__);
        drvData->detectFlag = false;
        return HDF_FAILURE;
    }
    return HDF_SUCCESS;
}
/* 加速度计传感器驱动初始化入口函数,主要功能为对传感器私有数据的结构体对象进行初始化,传感器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;
    }

    if (InitAccelAfterConfig() != HDF_SUCCESS) {
        HDF_LOGE("%s: init accel after config failed", __func__);
        goto INIT_EXIT;
    }

    HDF_LOGI("%s: init accel driver success", __func__);
    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)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;
    }

    drvData->initStatus = false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
  1. 加速度计传感器寄存器组配置信息

加速度计传感器数据配置只需要按照模板配置即可,基于模板配置的解析功能已经在InitSensorConfigData函数完成,只需初始化时调用即可。如果有新增配置项,需要同步修改此函数。

加速度传感器数据配置模板(accel_config.hcs)
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; /* 传感器的最大量程,根据开发者需要配置 */
                precision = 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; /* 校验传感器在位检测寄存器值 */
            }
        }
    }
}

/* 根据不同器件硬件差异,修改模板配置,不修改的就会默认采用模板配置 */
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
                ];
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  1. 加速度计传感器驱动操作接口实现

开发者需要根据每种类型的传感器实现归一化接口。

/* 不使用函数暂时置空 */
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->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;
    }

    drvData->threadStatus = SENSOR_THREAD_RUNNING;

    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);

    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 HDF_FAILURE;
        }

    drvData->threadStatus = SENSOR_THREAD_STOPPED;

    return HDF_SUCCESS;
}
/* 配置传感器采样率和数据上报间隔 */
static int32_t SetAccelBatch(int64_t samplingInterval, int64_t interval)
{
    (void)interval;

    struct AccelDrvData *drvData = AccelGetDrvData();
    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_ERR_NOT_SUPPORT;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
  • 差异化处理接口

    /* 器件探测时,如果探测成功,则注册差异化处理函数到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;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
  • 数据处理函数

创建传感器定时器,按照配置的采样率定时采样,并上报给数据订阅者。

/* 传感器定时工作线程 */
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 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);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: accel create thread failed", __func__);
        drvData->threadStatus = SENSOR_THREAD_NONE;
        return HDF_FAILURE;
    }

    CHECK_NULL_PTR_RETURN_VALUE(drvData->ops.Init, HDF_ERR_INVALID_PARAM);

    ret = drvData->ops.Init(drvData->accelCfg);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: accel create thread failed", __func__);
        drvData->threadStatus = SENSOR_THREAD_NONE;
        return HDF_FAILURE;
    }
    drvData->initStatus = true;
    return HDF_SUCCESS;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  • 主要的数据结构
/* 传感器转换单位*/
#define SENSOR_CONVERT_UNIT             1000
#define SENSOR_1K_UNIT                  1024
/* 传感器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
/* 传感器数据维度 */
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 {
    bool detectFlag;
    uint8_t threadStatus;
    uint8_t initStatus;
    int64_t interval;
    struct SensorCfgData *accelCfg;
    struct OsalThread thread;
    struct AccelOpsCall ops;
};
/* 差异化适配函数 */
struct AccelOpsCall {
    int32_t (*Init)(struct SensorCfgData *data);
    int32_t (*ReadData)(struct SensorCfgData *data);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

测试指导

驱动开发完成后,在传感器单元测试里面开发自测试用例,验证驱动基本功能。测试环境采用开发者自测试平台。

/* 标识是否上报传感器数据 */
static int32_t g_sensorDataFlag = 0;
/* 保持获取的传感器接口实例地址 */
static const struct SensorInterface *g_sensorDev = nullptr;

/* 订阅者注册数据上报函数 */
static int SensorTestDataCallback(struct SensorEvents *event)
{
    if (event == nullptr) {
        return -1;
    }
    float *data = (float*)event->data;
    printf("time [%lld] sensor id [%d] x-[%f] y-[%f] z-[%f]\n\r", event->timestamp,
        event->sensorId, (*data), *(data + 1), *(data + g_axisZ));
    if (*data > 1e-5) {
        g_sensorDataFlag = 1;
    }
    return 0;
}
/* 用例执行前,初始化传感器接口实例 */
void HdfSensorTest::SetUpTestCase()
{
    g_sensorDev = NewSensorInterfaceInstance();
    if (g_sensorDev == nullptr) {
        printf("test sensorHdi get Module instace failed\n\r");
    }
}
/* 用例资源释放 */
void HdfSensorTest::TearDownTestCase()
{
    if (g_sensorDev != nullptr) {
        FreeSensorInterfaceInstance();
        g_sensorDev = nullptr;
    }
}
/* 传感器驱动测试验证 */
HWTEST_F(HdfSensorTest,TestAccelDriver_001, TestSize.Level0)
{
    int32_t sensorInterval = 1000000000; /* 数据采样率单位纳秒 */
    int32_t pollTime = 5; /* 数据采样时间单位秒 */
    int32_t accelSensorId = 1; /* 加速度传感器类型标识为1 */
    int32_t count = 0;
    int ret;
    struct SensorInformation *sensorInfo = nullptr;

    ret = g_sensorDev->Register(SensorTestDataCallback)
    EXPECT_EQ(SENSOR_NULL_PTR, ret);

    ret = g_sensorDev->GetAllSensors(&sensorInfo, &count);
    EXPECT_EQ(0, ret);
    if (sensorInfo == nullptr) {
        EXPECT_NE(nullptr, sensorInfo);
        return;
    }
    /* 打印获取的传感器列表 */
    for (int i = 0; i < count; i++) {
        printf("get sensoriId[%d], info name[%s]\n\r", sensorInfo[i]->sensorId, sensorInfo[i]->sensorName);
    }
    ret = g_sensorDev->Enable(accelSensorId);
    EXPECT_EQ(0, ret);
    g_sensorDataFlag = 0;

    ret = g_sensorDev->SetBatch(accelSensorId, sensorInterval, pollTime);
    EXPECT_EQ(0, ret);
    /* 在时间pollTime内,观察输出打印数据 */
    OsalSleep(pollTime);
    EXPECT_EQ(1, g_sensorDataFlag);

    ret = g_sensorDev->Disable(accelSensorId);
    g_sensorDataFlag = 0;
    EXPECT_EQ(0, ret);

    ret = g_sensorDev->Unregister();
    EXPECT_EQ(0, ret);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75