摘要:LiteOS传感框架将物联网终端设备上不同类型的传感器统一管理,通过抽象不同类型传感器接口,屏蔽其硬件细节,做到“硬件”无关性,非常方便于物联网设备的开发、维护和功能扩展。
LiteOS传感框架是什么
随着物联网的发展,物联网终端越来越智能化,例如在个人穿戴、智能家居、家用医疗等终端上将配置越来越多的传感器,来获取更多传感数据,使终端更加智能,使得开发和维护变得复杂和困难。LiteOS传感框架将物联网终端设备上例如加速计(Accelerometer)、陀螺仪(Gyroscope)、气压仪(Barometer)、温湿度计(Humidometer)等不同类型的传感器统一管理,通过抽象不同类型传感器接口,屏蔽其硬件细节,做到“硬件”无关性,非常方便于物联网设备的开发、维护和功能扩展。
LiteOS传感框架架构介绍
LiteOS传感框架主要包括了Sensor Manager、BSP manager,Converged Algorithms。
- Sensor Manager:统一的传感器交互管理,如Sensor的配置、采样、上报和管理。
- BSP Manager:统一的驱动接口,负责Sensor驱动管理、电源管理、Sensor交互管理,如Sensor的打开、关闭、读写、数据更新等。
- Converged Algorithms:融合算法库(算法基于具体的业务模型),根据具体业务模型,在端侧MCU进行算法融合,例如环境监测算法、计步算法等,从传统、简单采集算法升级到智能算法,应用直接调用,提升传感数据的业务精准度,降低数据采集时延。
LiteOS传感框架特点
- 提升开发效率,降低开发难度:LiteOS传感框架实现对物联网终端Sensor的统一管理,对不同类型传感器进行抽象,软件工程师专注于功能开发,硬件工程师专注于底层驱动适配,开发人员不需要懂软件又懂硬件,降低了开发难度,提升了开发效率。
- 软件架构分层分级,方便功能扩展和维护:由于软件架构分层,非常方便于物联网设备日后的维护和扩展升级。
LiteOS传感框架适用的场景
LiteOS传感框架是LiteOS物联网操作系统的Sensor管理框架,适应于多种物联网终端的开发。对于智能化、低功耗、多种Sensor、产品更新迭代快的终端设备,更能体现出传感框架的优势,例如可穿戴设备、智能家居设备、家用医疗设备等等。
例如在运动手表(手环)中,就有心率测量(PPG)、环境光、加速度计、磁力计、气压计、GPS等多种传感器,数据上报频繁复杂,不同传感器数据需要协同运算处理,对数据采集、传输、处理提出了更高的要求,同时设计通用的软件平台、提升续航指标也面临巨大挑战。使用SensorHub传感框架有效解决了通用性问题。另外统一的传感器周期管理,还有效减少了无用的中断唤醒,再结合LiteOS出色的低功耗管理能力,助力产品快速上市,具有很好的竞争力。
LiteOS传感框架功能接口
LiteOS传感框架开发流程
使用Sensor Manager管理某一类别传感器典型流程如下:
1.任务、队列、信号量等资源SensorManagerInit。
2.初始化SensorType结构体变量,并注册传感器SensorRegister。
3.通过SensorTableGet获取传感器列表,执行已注册传感器的初始化动作。
4.根据需要配置传感器参数SensorConfigNotify。
5.初始化相同类别标签的传感器应用SensorItemInit,并提供应用Id和数据更新回调函数。
6.打开传感器应用SensorItemEnable,并提供应用采样周期,传感器驱动会根据打开参数的时间间隔创建软件定时器并启动,定时时间到达后则调用SensorSample通知Sensor Manager 读取数据,同时根据采样周期设置推送数据到该应用注册的回调函数。
7.关闭传感器应用SensorItemDisable,停止推送数据到该应用。
传感器消息处理、发送根据具体业务需求增加。
一个编程实例
我们最后通过一个例子,便于大家了解如何使用LitOS传感框架进行快速开发。
本实例中提供的传感器驱动和应用代码仅对使用传感框架读取传感器做基本设计和实现,仅做参考。
硬件设备:
野火挑战者开发板(Cloud_STM32F429IGTx_FIRE)。MPU6050是一种六轴传感器模块,能同时检测三轴加速度、三轴陀螺仪(角加速度)、温度。
开发任务:
开发应用定时读取开发板MPU6050传感器的原始数据。
开发步骤:
- 初始化陀螺仪标签类别的两个应用g_gyroItem1、g_gyroItem2。
- 设置不同的采集周期,打开应用,注册数据更新回调函数SensorReport。
- 采集一段时间后,先关闭g_gyroItem1,此时传感器数据会继续推送g_gyroItem2,一段时间后,关闭g_gyroItem2,此时传感器数据采样停止,SensorReport不再被调用。
- 再执行一遍2、3步骤。
实例代码:
#define STASK_PRIORITY_MISC 4
#define STASK_STKDEPTH_MISC 0x800
#define Item1_SAMPLE_INTERVAL 3000 // LiteOS ticks
#define Item2_SAMPLE_INTERVAL 6000
STATIC SensorItem g_gyroItem1 = {
.id = 1, // 1: gyro item 1
};
STATIC SensorItem g_gyroItem2 = {
.id = 2, // 2: gyro item 2
};
STATIC UINT32 g_miscTskID;
STATIC INT32 SensorReport(UINT32 arg, const INT8 *data, UINT32 len)
{
(VOID)(len);
(VOID)(data);
PRINTK("tag %u report\r\n", arg);
return LOS_OK;
}
STATIC VOID OpenGyro(VOID)
{
OpenParam para;
// period is LiteOS ticks
para.period = Item1_SAMPLE_INTERVAL;
SensorItemEnable(&g_gyroItem1, ¶, g_gyroItem1.id, 0);
para.period = Item2_SAMPLE_INTERVAL;
SensorItemEnable(&g_gyroItem2, ¶, g_gyroItem2.id, 0);
}
STATIC VOID CloseGyro(VOID)
{
CloseParam para;
SensorItemDisable(&g_gyroItem1, ¶, g_gyroItem1.id, 0);
// keep item2 working for 40000 ticks
LOS_TaskDelay(40000);
SensorItemDisable(&g_gyroItem2, ¶, g_gyroItem2.id, 0);
}
STATIC VOID InitGyro(VOID)
{
SensorType *sensor = NULL;
SensorScbTable *scbTable = NULL;
// init gyro sensor
scbTable = SensorTableGet();
sensor = scbTable[TAG_GYRO - TAG_BEGIN].sensorInterface;
if ((sensor != NULL) && (sensor->sensorOp != NULL)) {
(VOID)sensor->sensorOp->Init(sensor);
}
// init item
SensorItemInit(&g_gyroItem1, NULL, TAG_GYRO, SensorReport, TAG_GYRO);
SensorItemInit(&g_gyroItem2, NULL, TAG_GYRO, SensorReport, TAG_GYRO);
}
STATIC VOID MiscTask(VOID const *arg)
{
(VOID)(arg);
// I2C init
I2cMaster_Init();
SensorManagerInit();
LOS_TaskDelay(1000);
GyroSensorRegister();
InitGyro();
OpenGyro();
LOS_TaskDelay(20000);
CloseGyro();
OpenGyro();
LOS_TaskDelay(100000);
CloseGyro();
}
VOID MiscInit(VOID)
{
UINT32 ret;
TSK_INIT_PARAM_S taskInitParam = {0};
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)MiscTask;
taskInitParam.uwStackSize = STASK_STKDEPTH_MISC;
taskInitParam.pcName = "Misc Task";
taskInitParam.usTaskPrio = STASK_PRIORITY_MISC; /* 1~7 */
taskInitParam.uwResved = LOS_TASK_STATUS_DETACHED; /* task is detached, the task can deleteself */
ret = LOS_TaskCreate(&g_miscTskID, &taskInitParam);
if (ret != LOS_OK) {
PRINT_ERR("Misc Task create fail\n");
return;
}
PRINT_DEBUG("MiscTask init \n");
}
结果验证
传感器采样的第一个数据会推送至所有相关应用,然后每个应用在自己的周期到来时才会收到传感器的数据。
图1 实例结果显示
下载Huawei LiteOS源代码,快快体验一下吧。
传感框架代码路径:https://gitee.com/LiteOS/Lite...。