|
OpenHarmony 传感器的生态目前还不完善,体现在
hdf_unittest_sensor 功能缺失,只支持 als 读取数据。hdf_unittest_sensor enable 并未真正执行读取动作,只是读取了旧值。hdf_unittest_sensor 在设备没有传感器的情况下必失败,影响 xts 验证。hdi_unittest_sensor 同样功能缺失,甚至不支持数据验证。除 als 外,其他数据在 hdf_core 中的上报通路都没打通。实际测试中有发现 hcs 配置中,掩码不生效的问题。chipset raw 数据读取存在重入 bug。
鉴于很多都是一些低级错误,甚至基础不牢的问题。我开发了一个测试工具,用来检测传感器是否能正常上报数据。
用法如下:- >hdc shell sensor_tool
- Usage: sensor_tool [options] [sensor_id]
- sensor_tool (help | -h | --help)
- Note: Commands without sensor_id will apply to all sensors
- Commands:
- list List all sensors
- enable [sensor_id] Enable specified sensor
- disable [sensor_id] Disable specified sensor
- read [sensor_id] Read sensor data once
- monitor [sensor_id] Monitor sensor data continuously
- Monitor Options:
- -i, --interval Set sampling interval (default: 1000ms)
- -c, --count Set number of readings (default: infinite)
- -t, --time Set monitoring duration in seconds (default: infinite)
复制代码 你可以
使用 enable,read,disable 配合 i2cget,i2cset,单独调试 hcs 中的 init,enable,disable 序列是否有问题,或者是掩码是否生效(用来排除 OH 代码问题)。使用 monitor 检查传感器能否正常上报读数,传感器读数是否会随环境变化而变化。
效果如下- C:\Users\chao>hdc shell sensor_tool list
- Available sensors (5):
- ----------------------------------------
- Sensor[0]: ID=6, Name=magnetometer
- Sensor[1]: ID=12, Name=proximity
- Sensor[2]: ID=5, Name=als
- Sensor[3]: ID=2, Name=gyroscope
- Sensor[4]: ID=1, Name=accelerometer
- ----------------------------------------
- C:\Users\chao>hdc shell sensor_tool enable
- Sensor 6 (magnetometer) enabled successfully
- Sensor 12 (proximity) enabled successfully
- Sensor 5 (als) enabled successfully
- Sensor 2 (gyroscope) enabled successfully
- Sensor 1 (accelerometer) enabled successfully
- All sensors enabled successfully
- C:\Users\chao>hdc shell sensor_tool read
- Reading data:
- ----------------------------------------
- Sensor[6] magnetometer data: -22.50 -45.15 86.85
- Failed to read sensor 12 (proximity) data
- Sensor[5] als data: 0.60
- Sensor[2] gyroscope data: -6.38 3.19 6.38
- Sensor[1] accelerometer data: 0.01 1.76 -10.01
- ----------------------------------------
- C:\Users\chao>hdc shell sensor_tool monitor
- Sensor 6 (magnetometer) enabled successfully
- Sensor 12 (proximity) enabled successfully
- Sensor 5 (als) enabled successfully
- Sensor 2 (gyroscope) enabled successfully
- Sensor 1 (accelerometer) enabled successfully
- All sensors enabled successfully
- Reading data (count: 1):
- ----------------------------------------
- Trying to read data from sensor 6 (magnetometer):
- Sensor[6] magnetometer data: -22.65 -45.60 89.25
- Trying to read data from sensor 12 (proximity):
- Failed to read sensor 12 (proximity) data, ret=-1
- Trying to read data from sensor 5 (als):
- Sensor[5] als data: 0.60
- Trying to read data from sensor 2 (gyroscope):
- Sensor[2] gyroscope data: -3.19 4.25 5.32
- Trying to read data from sensor 1 (accelerometer):
- Sensor[1] accelerometer data: 0.00 1.75 -9.98
- ----------------------------------------
- Reading data (count: 2):
- ----------------------------------------
- Trying to read data from sensor 6 (magnetometer):
- Sensor[6] magnetometer data: -22.05 -44.70 87.60
- Trying to read data from sensor 12 (proximity):
- Failed to read sensor 12 (proximity) data, ret=-1
- Trying to read data from sensor 5 (als):
- Sensor[5] als data: 0.60
- Trying to read data from sensor 2 (gyroscope):
- Sensor[2] gyroscope data: -5.32 2.13 3.19
- Trying to read data from sensor 1 (accelerometer):
- Sensor[1] accelerometer data: 0.02 1.73 -9.99
- ----------------------------------------
复制代码 编译说明
用法是,把下面文件放到 unittest 下面,改改仿照 BUILD.gn 里的 hdf_unittest_sensor,重新设置一个编译目标,比如 sensor_tool,然后单编。- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include "hdf_base.h"
- #include "osal_mem.h"
- #include "osal_time.h"
- #include "sensor_if.h"
- #include "sensor_type.h"
- // 全局变量
- static const struct SensorInterface *g_sensorDev = nullptr;
- static struct SensorInformation *g_sensorInfo = nullptr;
- static int32_t g_sensorCount = 0;
- static uint32_t g_interval = 1000; // 默认采样间隔1秒
- static int32_t g_count = -1; // 默认持续读取
- static int32_t g_duration = -1; // 默认持续运行
- static bool g_running = true; // 运行状态标志
- // 命令类型枚举
- enum CommandType {
- CMD_NONE = 0,
- CMD_LIST,
- CMD_ENABLE,
- CMD_DISABLE,
- CMD_READ,
- CMD_MONITOR
- };
- // 命令参数结构
- struct CommandArgs {
- enum CommandType cmd;
- int32_t sensorId;
- };
- // 函数声明
- static void PrintUsage(void);
- static int32_t ParseCommandLine(int argc, char *argv[], struct CommandArgs *args);
- static int32_t InitSensorDev(void);
- static void DeinitSensorDev(void);
- static int32_t ListSensors(void);
- static int32_t EnableSensor(int32_t sensorId);
- static int32_t EnableAllSensors(void);
- static int32_t DisableSensor(int32_t sensorId);
- static int32_t DisableAllSensors(void);
- static int32_t ReadSensorData(int32_t sensorId, bool autoEnable, bool readAll);
- static const char* GetSensorName(int32_t sensorId);
- static int32_t ReadAndPrintSensorData(struct SensorEvents **events, int32_t numSensors,
- int32_t sensorId, bool readAll, int32_t readCount = -1);
- // 信号处理函数
- static void SignalHandler(int signo)
- {
- if (signo == SIGINT) {
- printf("\nReceived Ctrl+C, stopping...\n");
- g_running = false;
- }
- }
- // 主函数
- int main(int argc, char *argv[])
- {
- struct CommandArgs args = {CMD_NONE, 0}; // 修复结构体初始化
- int32_t ret;
- // 设置信号处理
- signal(SIGINT, SignalHandler);
- // 解析命令行参数
- ret = ParseCommandLine(argc, argv, &args);
- if (ret != 0) {
- PrintUsage();
- return -1;
- }
- // 初始化传感器设备
- ret = InitSensorDev();
- if (ret != 0) {
- printf("Failed to init sensor device\n");
- return -1;
- }
- // 执行命令
- switch (args.cmd) {
- case CMD_LIST:
- ret = ListSensors();
- break;
- case CMD_ENABLE:
- ret = (args.sensorId == -1) ? EnableAllSensors() : EnableSensor(args.sensorId);
- break;
- case CMD_DISABLE:
- ret = (args.sensorId == -1) ? DisableAllSensors() : DisableSensor(args.sensorId);
- break;
- case CMD_READ:
- ret = (args.sensorId == -1) ? ReadSensorData(0, false, true) : ReadSensorData(args.sensorId, false, false);
- break;
- case CMD_MONITOR:
- ret = (args.sensorId == -1) ? ReadSensorData(0, true, true) : ReadSensorData(args.sensorId, true, false);
- break;
- default:
- PrintUsage();
- ret = -1;
- break;
- }
- // 释放传感器设备
- DeinitSensorDev();
- return ret;
- }
- // 打印使用说明
- static void PrintUsage(void)
- {
- printf("Usage: sensor_tool [options] [sensor_id]\n");
- printf(" sensor_tool (help | -h | --help)\n");
- printf("\nNote: Commands without sensor_id will apply to all sensors\n");
- printf("\nCommands:\n");
- printf(" list List all sensors\n");
- printf(" enable [sensor_id] Enable specified sensor\n");
- printf(" disable [sensor_id] Disable specified sensor\n");
- printf(" read [sensor_id] Read sensor data once\n");
- printf(" monitor [sensor_id] Monitor sensor data continuously\n");
- printf("\nMonitor Options:\n");
- printf(" -i, --interval Set sampling interval (default: 1000ms)\n");
- printf(" -c, --count Set number of readings (default: infinite)\n");
- printf(" -t, --time Set monitoring duration in seconds (default: infinite)\n");
- }
- // 解析命令行参数
- static int32_t ParseCommandLine(int argc, char *argv[], struct CommandArgs *args)
- {
- int opt;
- int option_index = 0;
- struct option long_options[] = {
- {"interval", required_argument, nullptr, 'i'},
- {"count", required_argument, nullptr, 'c'},
- {"time", required_argument, nullptr, 't'},
- {"help", no_argument, nullptr, 'h'},
- {nullptr, 0, nullptr, 0}
- };
- // 默认设置为-1表示所有传感器
- args->sensorId = -1;
- // 解析选项
- while ((opt = getopt_long(argc, argv, "i:c:t:h", long_options, &option_index)) != -1) {
- switch (opt) {
- case 'i':
- g_interval = atoi(optarg);
- break;
- case 'c':
- g_count = atoi(optarg);
- break;
- case 't':
- g_duration = atoi(optarg);
- break;
- case 'h':
- PrintUsage();
- exit(0);
- default:
- return -1;
- }
- }
- // 解析命令
- if (optind >= argc) {
- return -1;
- }
- const char *cmd = argv[optind];
- struct {
- const char *name;
- enum CommandType type;
- bool needId;
- } cmdMap[] = {
- {"list", CMD_LIST, false},
- {"enable", CMD_ENABLE, true},
- {"disable", CMD_DISABLE, true},
- {"read", CMD_READ, true},
- {"monitor", CMD_MONITOR, true},
- {nullptr, CMD_NONE, false}
- };
- for (int i = 0; cmdMap[i].name != nullptr; i++) {
- if (strcmp(cmd, cmdMap[i].name) == 0) {
- args->cmd = cmdMap[i].type;
- if (cmdMap[i].needId && optind + 1 < argc && argv[optind + 1][0] != '-') {
- args->sensorId = atoi(argv[optind + 1]);
- }
- return 0;
- }
- }
- return -1;
- }
- // 初始化传感器设备
- static int32_t InitSensorDev(void)
- {
- g_sensorDev = NewSensorInterfaceInstance();
- if (g_sensorDev == nullptr) {
- printf("Failed to get sensor interface instance\n");
- return -1;
- }
- int32_t ret = g_sensorDev->GetAllSensors(&g_sensorInfo, &g_sensorCount);
- if (ret != 0) {
- printf("Failed to get sensor information\n");
- FreeSensorInterfaceInstance();
- g_sensorDev = nullptr;
- return -1;
- }
- return 0;
- }
- // 释放传感器设备
- static void DeinitSensorDev(void)
- {
- if (g_sensorDev != nullptr) {
- FreeSensorInterfaceInstance();
- g_sensorDev = nullptr;
- }
- }
- // 列出所有传感器
- static int32_t ListSensors(void)
- {
- if (g_sensorInfo == nullptr || g_sensorCount sensorId, info->sensorName);
- info++;
- }
- printf("----------------------------------------\n");
- return 0;
- }
- // 通过传感器ID获取传感器名称
- static const char* GetSensorName(int32_t sensorId)
- {
- if (g_sensorInfo == nullptr || g_sensorCount SetBatch(sensorId, g_interval * 1000000, 0);
- if (ret != 0) {
- printf("Failed to set batch for sensor %d\n", sensorId);
- return -1;
- }
- // 使能传感器
- ret = g_sensorDev->Enable(sensorId);
- if (ret != 0) {
- printf("Failed to enable sensor %d\n", sensorId);
- return -1;
- }
- printf("Sensor %d (%s) enabled successfully\n", sensorId, GetSensorName(sensorId));
- return 0;
- }
- // 使能所有传感器
- static int32_t EnableAllSensors(void)
- {
- if (g_sensorDev == nullptr || g_sensorInfo == nullptr || g_sensorCount sensorId);
- if (ret != 0) {
- printf("Failed to enable sensor %d\n", info->sensorId);
- return -1;
- }
- info++;
- }
- printf("All sensors enabled successfully\n");
- return 0;
- }
- // 禁用指定传感器
- static int32_t DisableSensor(int32_t sensorId)
- {
- if (g_sensorDev == nullptr) {
- printf("Sensor device not initialized\n");
- return -1;
- }
- int32_t ret = g_sensorDev->Disable(sensorId);
- if (ret != 0) {
- printf("Failed to disable sensor %d\n", sensorId);
- return -1;
- }
- printf("Sensor %d (%s) disabled successfully\n", sensorId, GetSensorName(sensorId));
- return 0;
- }
- // 禁用所有传感器
- static int32_t DisableAllSensors(void)
- {
- if (g_sensorDev == nullptr || g_sensorInfo == nullptr || g_sensorCount sensorId);
- if (ret != 0) {
- printf("Failed to disable sensor %d\n", info->sensorId);
- return -1;
- }
- info++;
- }
- printf("All sensors disabled successfully\n");
- return 0;
- }
- // 读取并打印传感器数据
- static int32_t ReadAndPrintSensorData(struct SensorEvents **events, int32_t numSensors,
- int32_t sensorId, bool readAll, int32_t readCount)
- {
- if (readCount >= 0) {
- printf("\nReading data (count: %d):\n", readCount + 1);
- } else {
- printf("\nReading data:\n");
- }
- if (readAll) {
- printf("----------------------------------------\n");
- }
- for (int32_t i = 0; i < numSensors; i++) {
- int32_t currentSensorId = readAll ? g_sensorInfo[i].sensorId : sensorId;
- if (readCount >= 0) {
- printf("\nTrying to read data from sensor %d (%s):\n", currentSensorId, GetSensorName(currentSensorId));
- }
- int32_t ret = g_sensorDev->ReadData(currentSensorId, events[i]);
- if (ret != 0) {
- printf("Failed to read sensor %d (%s) data%s\n",
- currentSensorId, GetSensorName(currentSensorId),
- readCount >= 0 ? (", ret=" + std::to_string(ret)).c_str() : "");
- if (readCount >= 0) {
- fflush(stdout);
- }
- continue;
- }
- // 打印数据
- float *data = reinterpret_cast(events[i]->data);
- printf("Sensor[%d] %s data: ", currentSensorId, GetSensorName(currentSensorId));
- for (int32_t j = 0; j < events[i]->dataLen / sizeof(float); j++) {
- printf("%.2f ", data[j]);
- }
- printf("\n");
- }
- if (readAll) {
- printf("----------------------------------------\n");
- }
- if (readCount >= 0) {
- fflush(stdout);
- }
- return 0;
- }
- // 读取传感器数据
- static int32_t ReadSensorData(int32_t sensorId, bool autoEnable, bool readAll)
- {
- if (g_sensorDev == nullptr) {
- printf("Sensor device not initialized\n");
- return -1;
- }
- // 如果是读取所有传感器,需要额外的检查
- if (readAll && (g_sensorInfo == nullptr || g_sensorCount data = (uint8_t *)OsalMemCalloc(sizeof(float) * 3);
- if (events[i]->data == nullptr) {
- printf("Failed to allocate sensor data %d\n", i);
- goto cleanup;
- }
- events[i]->dataLen = sizeof(float) * 3;
- }
- // 如果是自动读取模式,使用循环读取
- if (autoEnable) {
- // 计算读取次数
- int32_t readCount = 0;
- int32_t maxCount = (g_count > 0) ? g_count : INT32_MAX;
- int32_t maxTime = (g_duration > 0) ? g_duration : INT32_MAX;
- OsalTimespec startTime = {0};
- OsalGetTime(&startTime);
- // 循环读取数据
- while (readCount < maxCount && g_running) {
- // 检查是否超时
- OsalTimespec currentTime = {0};
- if (OsalGetTime(¤tTime) == HDF_SUCCESS) {
- uint64_t elapsedTime = (currentTime.sec - startTime.sec) * 1000 +
- (currentTime.usec - startTime.usec) / 1000;
- if (elapsedTime >= maxTime * 1000) {
- break;
- }
- }
- ReadAndPrintSensorData(events, numSensors, sensorId, readAll, readCount);
- readCount++;
- OsalMSleep(g_interval);
- }
- } else {
- // 一次性读取数据
- ReadAndPrintSensorData(events, numSensors, sensorId, readAll);
- }
- // 禁用传感器(如果指定了auto)
- if (autoEnable) {
- if (readAll) {
- DisableAllSensors();
- } else {
- DisableSensor(sensorId);
- }
- }
- cleanup:
- // 释放资源
- if (events != nullptr) {
- for (int32_t i = 0; i < numSensors; i++) {
- if (events[i] != nullptr) {
- if (events[i]->data != nullptr) {
- OsalMemFree(events[i]->data);
- }
- OsalMemFree(events[i]);
- }
- }
- OsalMemFree(events);
- }
- return 0;
- }
复制代码 |
|