传感器管理组件(sensor manager)
概述
在CI110X系列芯片中,传感器管理组件是不可或缺的一个组件;其目的是将设备中的传感器统一管理、为用户提供统一且友好的函数接口、最大限度减少客户二次开发代码的工作量;我们提供大量的传感器驱动程序和使用案例供客户尽快了解传感器管理组件、传感器驱动编写规范、应用程序如何使用传感器。
目录介绍
文件名称 | 功能说明 |
---|---|
sensor.c、sensor.h | 传感器管理组件源代码 |
sensor_config.h | 传感器管理组件配置信息 |
sensor_test.c | 传感器管理组件示例代码 |
使用说明
函数接口简介
以下API仅供传感器驱动程序调用
函数接口 | 说明 |
---|---|
sensor_irq_inform | 传感器中断通知 |
sensor_data_inform | 传感器数据通知 |
以下API仅供应用程序调用
函数接口 | 说明 |
---|---|
sensor_register | 注册传感器 |
sensor_open | 打开传感器(初始化) |
sensor_read | 读取传感器数据 |
sensor_control | 执行传感器自定义命令 |
传感器接入流行程
- 根据实际情况实现以下API
Start实现`int32_t (*open)(void);`接口是否需要读数据 ?实现`int32_t (*read)(sensor_data_t *data);`接口是否有自定义命令 ?实现`int32_t (*control)(sensor_command_t command);`接口Endyesnoyesno
- 配置sensor_config.h文件,填入传感器类型、数据类型、自定义命令
/*----------------------------------------------------------------------------- struct / enum / union -----------------------------------------------------------------------------*/ /* 传感器自定义命令(此表可扩展) */ typedef enum { asdasdas = 0, }sensor_command_t; /* 传感器类型(此表可扩展) */ typedef enum { SENSOR_TYPE_TEMPERATURE = 0, /*!< 类型:温度传感器 */ SENSOR_TYPE_HUMIDITY = 1, /*!< 类型:湿度传感器 */ SENSOR_TYPE_MICROWAVE = 2, /*!< 类型:微波、雷达传感器*/ SENSOR_TYPE_PARTICULATES = 3, /*!< 类型:悬浮粒子(PM2.5)传感器*/ SENSOR_TYPE_GESTURE = 4, /*!< 类型:手势传感器*/ SENSOR_TYPE_INFRARED_ARRAY = 5, /*!< 类型:红外阵列传感器 */ SENSOR_TYPE_LASER_FINDER = 6, /*!< 类型:激光测距传感器 */ }sensor_type_t; /* 传感器数据(此表可扩展) */ typedef union { int32_t temperature; /*!< 温度 单位:0.1℃*/ float humidity; /*!< 湿度 单位:‰RH */ float particulates; /*!< 悬浮粒子(PM2.5) 单位:xx */ double infrared_array[4 * 16]; /*!< 温度 单位:0.1℃*/ uint16_t laser_finder; /*!< 距离 单位:mm*/ }sensor_data_t;
- 传感器中断通知
某些传感器会在某种特定的情况下,以中断的形式通知APP发生了某事件,这时我们传感器驱动就需要实现中断回调函数:void xxxx_callback(void)
,然后在此函数中调用传感器管理组件的中断通知API(sensor_irq_inform(SENSOR_TYPE_XXXX);
)参数为此传感器类型,即可。
常见问题
- (待补充)
ci_sensor.c
1 /** 2 * @file sensor.c 3 * @brief 传感器管理程序源文件 4 * @version 0.1 5 * @date 2019-06-24 6 * 7 * @copyright Copyright (c) 2019 Chipintelli Technology Co., Ltd. 8 * 9 */ 10 /*----------------------------------------------------------------------------- 11 header 12 -----------------------------------------------------------------------------*/ 13 #include <stdlib.h> 14 #include <string.h> 15 #include "freertos\FreeRTOS.h" 16 #include "freertos\task.h" 17 #include "freertos\semphr.h" 18 #include "ci_sensor.h" 19 20 /*----------------------------------------------------------------------------- 21 define 22 -----------------------------------------------------------------------------*/ 23 24 /*----------------------------------------------------------------------------- 25 extern 26 -----------------------------------------------------------------------------*/ 27 28 /*----------------------------------------------------------------------------- 29 struct / enum / union 30 -----------------------------------------------------------------------------*/ 31 /* 传感器结构 */ 32 typedef struct 33 { 34 sensor_block_t block; /*!< 阻不阻塞 */ 35 sensor_type_t type; /*!< 类型 */ 36 sensor_ops_t ops; /*!< 驱动API */ 37 SemaphoreHandle_t lock; /*!< 多线程保护互斥信号量 */ 38 SemaphoreHandle_t data_sem; /*!< 数据信号量 */ 39 void(*callback)(void); /*!< 回调函数 */ 40 }sensor_device_t; 41 42 /*----------------------------------------------------------------------------- 43 global 44 -----------------------------------------------------------------------------*/ 45 static sensor_device_t sensor_device[SENSOR_DEVICE_MAX];/* 传感器设备列表 */ 46 47 /*----------------------------------------------------------------------------- 48 declare 49 -----------------------------------------------------------------------------*/ 50 51 /*----------------------------------------------------------------------------- 52 function 53 -----------------------------------------------------------------------------*/ 54 /** 55 * @brief 中断处理函数 56 * 57 * @param type 58 */ 59 void sensor_irq_inform(sensor_type_t device_type) 60 { 61 xSemaphoreTake(sensor_device[device_type].lock,portMAX_DELAY); 62 sensor_device[device_type].callback(); 63 xSemaphoreGive(sensor_device[device_type].lock); 64 } 65 66 /** 67 * @brief 驱动调用,释放数据信号量 68 * 69 * @param type 70 */ 71 void sensor_data_inform(sensor_type_t device_type) 72 { 73 xSemaphoreTake(sensor_device[device_type].lock,portMAX_DELAY); 74 xSemaphoreGive(sensor_device[device_type].data_sem); 75 xSemaphoreGive(sensor_device[device_type].lock); 76 } 77 78 /** 79 * @brief 注册传感器设备 80 * 81 * @param device_type 传感器类型 82 * @param device_ops 传感器驱动API 83 * @retval RETURN_OK 84 * @retval RETURN_ERR 85 */ 86 int32_t sensor_register(sensor_type_t device_type,sensor_ops_t device_ops) 87 { 88 sensor_device[device_type].type = device_type; 89 sensor_device[device_type].ops = device_ops; 90 /* 创建互斥信号量 */ 91 sensor_device[device_type].lock = xSemaphoreCreateCounting(1,1); 92 if(NULL == sensor_device[device_type].lock) 93 { 94 return RETURN_ERR; 95 } 96 sensor_device[device_type].data_sem = xSemaphoreCreateCounting(1,0); 97 if(NULL == sensor_device[device_type].data_sem) 98 { 99 return RETURN_ERR; 100 } 101 return RETURN_OK; 102 } 103 104 /** 105 * @brief 打开传感器设备 106 * 107 * @param device_type 传感器类型 108 * @param device_block 传感器是否阻塞 109 * @param irq_callback 中断回调函数 110 * @retval RETURN_OK 111 * @retval RETURN_ERR 112 */ 113 int32_t sensor_open(sensor_type_t device_type,sensor_block_t device_block,void* irq_callback) 114 { 115 int32_t result = 0; 116 xSemaphoreTake(sensor_device[device_type].lock,portMAX_DELAY); 117 sensor_device[device_type].block = device_block; 118 sensor_device[device_type].callback = (void(*)(void))irq_callback; 119 result = sensor_device[device_type].ops.open(); 120 xSemaphoreGive(sensor_device[device_type].lock); 121 return result; 122 } 123 124 /** 125 * @brief 读取传感器数据 126 * 127 * @param device_type 传感器类型 128 * @param data 读取到的数据 129 * @retval RETURN_OK 130 * @retval RETURN_ERR 131 */ 132 int32_t sensor_read(sensor_type_t device_type,sensor_data_t *data) 133 { 134 int32_t result = 0; 135 xSemaphoreTake(sensor_device[device_type].lock,portMAX_DELAY); 136 result = sensor_device[device_type].ops.read(data); 137 if(SENSOR_NOBLOCK == sensor_device[device_type].block) 138 { 139 /* 非阻塞 */ 140 if(pdFALSE == xSemaphoreTake(sensor_device[device_type].data_sem,0)) 141 { 142 return RETURN_ERR; 143 } 144 } 145 else 146 { 147 /* 阻塞 */ 148 if(pdFALSE == xSemaphoreTake(sensor_device[device_type].data_sem, 149 portMAX_DELAY)) 150 { 151 return RETURN_ERR; 152 } 153 } 154 xSemaphoreGive(sensor_device[device_type].lock); 155 return result; 156 } 157 158 /** 159 * @brief 传感器其他控制 160 * 161 * @param device_type 传感器类型 162 * @param command 传感器命令 163 * @retval RETURN_OK 164 * @retval RETURN_ERR 165 */ 166 int32_t sensor_control(sensor_type_t device_type,sensor_command_t command) 167 { 168 int32_t result = 0; 169 xSemaphoreTake(sensor_device[device_type].lock,portMAX_DELAY); 170 result = sensor_device[device_type].ops.control(command); 171 xSemaphoreGive(sensor_device[device_type].lock); 172 return result; 173 } 174 175 /*----------------------------------------------------------------------------- 176 end of the file 177 -----------------------------------------------------------------------------*/
ci_sensor.h
/** * @file sensor.h * @brief 传感器管理程序头文件 * @version 0.1 * @date 2019-06-25 * * @copyright Copyright (c) 2019 Chipintelli Technology Co., Ltd. * */ #ifndef __CI_SENSOR_H__ #define __CI_SENSOR_H__ /** * @ingroup components * @defgroup sensor 传感器 * @brief 传感器管理组件 * @{ */ #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------------------------- include -----------------------------------------------------------------------------*/ #include "stdint.h" #include "ci_sensor_config.h" /*----------------------------------------------------------------------------- define -----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- extern -----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- struct / enum / union -----------------------------------------------------------------------------*/ /* 传感器读取数据,阻塞非阻塞类型定义 */ typedef enum { SENSOR_BLOCK = 0,/*!< 阻塞模式 */ SENSOR_NOBLOCK = 1,/*!< 非阻塞模式 */ }sensor_block_t; /* 传感器驱动要实现的API接口结构体,这里命名为OPS */ typedef struct { int32_t (*open)(void); /*!< 传感器驱动打开设备 */ int32_t (*read)(sensor_data_t *data); /*!< 传感器驱动读数据 */ int32_t (*control)(sensor_command_t command); /*!< 传感器驱动其他控制 */ }sensor_ops_t; /*----------------------------------------------------------------------------- global -----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- function declare -----------------------------------------------------------------------------*/ /* 传感器驱动调用 API */ void sensor_irq_inform(sensor_type_t device_type); void sensor_data_inform(sensor_type_t device_type); /* 应用代码调用 API */ int32_t sensor_register(sensor_type_t device_type,sensor_ops_t device_ops); int32_t sensor_open(sensor_type_t device_type,sensor_block_t device_block,void* irq_callback); int32_t sensor_read(sensor_type_t device_type,sensor_data_t *data); int32_t sensor_control(sensor_type_t device_type,sensor_command_t command); #ifdef __cplusplus } #endif /** * @} */ #endif /*----------------------------------------------------------------------------- end of the file -----------------------------------------------------------------------------*/
ci_sensor_config.h
/** * @file ci_sensor_config.h * @brief 传感器管理程序头文件 * @version 0.1 * @date 2019-06-25 * * @copyright Copyright (c) 2019 Chipintelli Technology Co., Ltd. * */ #ifndef __CI_SENSOR_CONFIG_H__ #define __CI_SENSOR_CONFIG_H__ /** * @ingroup sensor * @{ */ #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------------------------- include -----------------------------------------------------------------------------*/ #include "stdint.h" /*----------------------------------------------------------------------------- define -----------------------------------------------------------------------------*/ /* 传感器数目最大值 */ #define SENSOR_DEVICE_MAX (20) /*----------------------------------------------------------------------------- extern -----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- struct / enum / union -----------------------------------------------------------------------------*/ /* 传感器自定义命令(此表可扩展) */ typedef enum { xxxxxxxx = 0, }sensor_command_t; /* 传感器类型(此表可扩展) */ typedef enum { SENSOR_TYPE_TEMPERATURE = 0, /*!< 类型:温度传感器 */ SENSOR_TYPE_HUMIDITY = 1, /*!< 类型:湿度传感器 */ SENSOR_TYPE_MICROWAVE = 2, /*!< 类型:微波、雷达传感器*/ SENSOR_TYPE_PARTICULATES = 3, /*!< 类型:悬浮粒子(PM2.5)传感器*/ SENSOR_TYPE_GESTURE = 4, /*!< 类型:手势传感器*/ SENSOR_TYPE_INFRARED_ARRAY = 5, /*!< 类型:红外阵列传感器 */ SENSOR_TYPE_LASER_FINDER = 6, /*!< 类型:激光测距传感器 */ }sensor_type_t; /* 传感器数据(此表可扩展) */ typedef union { int32_t temperature; /*!< 温度 单位:0.1℃*/ float humidity; /*!< 湿度 单位:‰RH */ float particulates; /*!< 悬浮粒子(PM2.5) 单位:xx */ double infrared_array[4 * 16]; /*!< 温度 单位:0.1℃*/ uint16_t laser_finder; /*!< 距离 单位:mm*/ }sensor_data_t; /*----------------------------------------------------------------------------- global -----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- function declare -----------------------------------------------------------------------------*/ #ifdef __cplusplus } #endif /** * @} */ #endif /*----------------------------------------------------------------------------- end of the file -----------------------------------------------------------------------------*/
sensor_test.c
/** * @file ci_sensor_test.c * @brief 传感器测试代码源文件 * @version 0.1 * @date 2019-06-25 * * @copyright Copyright (c) 2019 Chipintelli Technology Co., Ltd. * */ /*----------------------------------------------------------------------------- include -----------------------------------------------------------------------------*/ #include "stdlib.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "ci_log.h" #include "ci_sensor.h" #include "temperature.h" #include "DHT11.h" #include "RCWL_0516.h" #include "YW_51.h" #include "APDS_9960.h" #include "MLX_90620.h" #include "RCWL_0801.h" /*----------------------------------------------------------------------------- define -----------------------------------------------------------------------------*/ /* 温度传感器 */ #define SENSOR_TEMPERATURE /* 温湿度传感器 */ //#define SENSOR_HUMIDITY /* 雷达传感器 */ //#define SENSOR_MICROWAVE /* PM2.5传感器 */ //#define SENSOR_PARTICULATES /* 手势传感器 */ //#define SENSOR_GESTURE /* 红外矩阵传感器 */ //#define SENSOR_INFRARED_ARRAY /* 激光测距传感器 */ //#define SENSOR_LASER_FINDER /*----------------------------------------------------------------------------- extern -----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- struct / enum / union -----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- global -----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- declare -----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- function -----------------------------------------------------------------------------*/ /* 以下在`#ifdef SENSOR_GESTURE`和`#endif`之间的代码段,为光感手势传感器的 测试代码,从传感器设备注册、打开、数据接收、中断处理;整个处理流程 */ #ifdef SENSOR_GESTURE /** * @brief 中断回调函数 * */ void APDS_9960_callback(void) { gesture_manage();/* 手势处理 */ } /** * @brief 传感器测试任务 * * @param p 任务参数 */ void sensor_task(void *p) { /* 注册传感器时,要明确传感器类型、API结构体 */ sensor_register(SENSOR_TYPE_GESTURE,apds9960_ops); /* open时传入阻塞或非阻塞属性,只作用于读取数据时 */ sensor_open(SENSOR_TYPE_GESTURE,SENSOR_NOBLOCK,APDS_9960_callback); for(;;) { vTaskDelay(pdMS_TO_TICKS(1000)); } } #endif /* 以下在`#ifdef SENSOR_TEMPERATURE`和`#endif`之间的代码段,为温度传感器的测 试代 码,从传感器设备注册、打开、数据接收、中断处理;整个处理流程 */ #ifdef SENSOR_TEMPERATURE /** * @brief 传感器测试任务 * * @param p 任务参数 */ void sensor_task(void *p) { /* 用于读取和保存获取到的传感器数据 */ sensor_data_t sensor_data; /* 注册传感器时,要明确传感器类型、API结构体 */ sensor_register(SENSOR_TYPE_TEMPERATURE,temperature_ops); /* open时传入阻塞或非阻塞属性,只作用于读取数据时 */ sensor_open(SENSOR_TYPE_TEMPERATURE,SENSOR_NOBLOCK,NULL); for(;;) { for(int i = 0;i < 10;i++) { /* 获取传感器数据 */ sensor_read(SENSOR_TYPE_TEMPERATURE,&sensor_data); // TODO: mprintf("temperature %d 单位0.1℃\n",sensor_data.temperature); vTaskDelay(pdMS_TO_TICKS(1000)); } } } #endif /* 以下在`#ifdef SENSOR_HUMIDITY`和`#endif`之间的代码段,为温湿度传感器的测 试代 码,从传感器设备注册、打开、数据接收、中断处理;整个处理流程 */ #ifdef SENSOR_HUMIDITY /** * @brief 传感器测试任务 * * @param p 任务参数 */ void sensor_task(void *p) { /* 用于读取和保存获取到的传感器数据 */ sensor_data_t sensor_data; /* 注册传感器时,要明确传感器类型、API结构体 */ sensor_register(SENSOR_TYPE_HUMIDITY,dht11_ops); /* open时传入阻塞或非阻塞属性,只作用于读取数据时 */ sensor_open(SENSOR_TYPE_HUMIDITY,SENSOR_NOBLOCK,NULL); for(;;) { for(int i = 0;i < 10;i++) { /* 获取传感器数据,这里只读取了湿度 */ sensor_read(SENSOR_TYPE_HUMIDITY,&sensor_data); // TODO: mprintf("humidity %f 单位‰RH\n",sensor_data.humidity); vTaskDelay(pdMS_TO_TICKS(1000)); } } } #endif /* 以下在`#ifdef SENSOR_MICROWAVE`和`#endif`之间的代码段,为雷达微波传感器的 测试代码,从传感器设备注册、打开、数据接收、中断处理;整个处理流程 */ #ifdef SENSOR_MICROWAVE /** * @brief 中断回调函数 * */ void RCWL_0516_callback(void) { mprintf("雷达微波触发\n"); } /** * @brief 传感器测试任务 * * @param p 任务参数 */ void sensor_task(void *p) { /* 注册传感器时,要明确传感器类型、API结构体 */ sensor_register(SENSOR_TYPE_MICROWAVE,rcwl0516_ops); /* open时传入阻塞或非阻塞属性,只作用于读取数据时 */ sensor_open(SENSOR_TYPE_MICROWAVE,SENSOR_NOBLOCK,RCWL_0516_callback); for(;;) { vTaskDelay(pdMS_TO_TICKS(1000)); } } #endif /* 以下在`#ifdef SENSOR_PARTICULATES`和`#endif`之间的代码段,为PM2.5传感器的 测试代码,从传感器设备注册、打开、数据接收、中断处理;整个处理流程 */ #ifdef SENSOR_PARTICULATES /** * @brief 传感器测试任务 * * @param p 任务参数 */ void sensor_task(void *p) { /* 用于读取和保存获取到的传感器数据 */ sensor_data_t sensor_data; /* 注册传感器时,要明确传感器类型、API结构体 */ sensor_register(SENSOR_TYPE_PARTICULATES,yw51_ops); /* open时传入阻塞或非阻塞属性,只作用于读取数据时 */ sensor_open(SENSOR_TYPE_PARTICULATES,SENSOR_NOBLOCK,NULL); for(;;) { for(int i = 0;i < 10;i++) { /* 获取传感器数据 */ sensor_read(SENSOR_TYPE_PARTICULATES,&sensor_data); // TODO: mprintf("PM2.5 %f 单位 xx\n",sensor_data.particulates); vTaskDelay(pdMS_TO_TICKS(1000)); } } } #endif /* 以下在`#ifdef SENSOR_INFRARED_ARRAY`和`#endif`之间的代码段,为红外矩阵传感器的 测试代码,从传感器设备注册、打开、数据接收、中断处理;整个处理流程 */ #ifdef SENSOR_INFRARED_ARRAY /** * @brief 传感器测试任务 * * @param p 任务参数 */ void sensor_task(void *p) { /* 用于读取和保存获取到的传感器数据 */ sensor_data_t sensor_data; /* 注册传感器时,要明确传感器类型、API结构体 */ sensor_register(SENSOR_TYPE_INFRARED_ARRAY,mlx90620_ops); /* open时传入阻塞或非阻塞属性,只作用于读取数据时 */ sensor_open(SENSOR_TYPE_INFRARED_ARRAY,SENSOR_NOBLOCK,NULL); for(;;) { /* 获取传感器数据 */ sensor_read(SENSOR_TYPE_INFRARED_ARRAY,&sensor_data); // TODO: vTaskDelay(pdMS_TO_TICKS(1000)); } } #endif /* 以下在`#ifdef SENSOR_LASER_FINDER`和`#endif`之间的代码段,为激光传感器的 测试代码,从传感器设备注册、打开、数据接收、中断处理;整个处理流程 */ #ifdef SENSOR_LASER_FINDER /** * @brief 传感器测试任务 * * @param p 任务参数 */ void sensor_task(void *p) { /* 用于读取和保存获取到的传感器数据 */ sensor_data_t sensor_data; /* 注册传感器时,要明确传感器类型、API结构体 */ sensor_register(SENSOR_TYPE_LASER_FINDER,rcwl_0801_ops); /* open时传入阻塞或非阻塞属性,只作用于读取数据时 */ sensor_open(SENSOR_TYPE_LASER_FINDER,SENSOR_NOBLOCK,NULL); for(;;) { /* 获取传感器数据 */ sensor_read(SENSOR_TYPE_LASER_FINDER,&sensor_data); // TODO: vTaskDelay(pdMS_TO_TICKS(1000)); } } #endif /*----------------------------------------------------------------------------- end of the file -----------------------------------------------------------------------------*/