摘要: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/LiteOS/tree/master/components/sensorhub。
