日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

鸿蒙Hi3861学习六-Huawei LiteOS-M(软件定时器)

發布時間:2024/1/18 编程问答 59 豆豆
生活随笔 收集整理的這篇文章主要介紹了 鸿蒙Hi3861学习六-Huawei LiteOS-M(软件定时器) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、簡介

? ? ? ? 軟件定時器,是基于系統Tick時鐘中斷且由軟件來模擬的定時器。當經過設定的Tick時鐘計數值后,會觸發用戶定義的回調函數。定時精度與系統Tick時鐘周期有關。

? ? ? ? 硬件定時器受硬件的限制,數量上不足以滿足用戶的實際需求。因此,為了滿足用戶需求,提供更多的定時器,LiteOS提供軟件定時器功能。

? ? ? ? 軟件定時器擴展了定時器的數量,允許創建更多的定時業務。

? ? ? ? 軟件定時器功能上支持:

  • 靜態裁剪:能通過宏關閉軟件定時器功能。
  • 軟件定時器創建。
  • 軟件定時器啟動。
  • 軟件定時器停止
  • 軟件定時器刪除。
  • 軟件定時器剩余Tick數獲取

? ? ? ? 更多概念可以參考:FreeRTOS學習六(軟件定時器)_freertos 執行定時器回調函數的內存消耗將是在定時器任務堆棧上動態分配_t_guest的博客-CSDN博客

????????Timer Management

二、運作機制

? ? ? ? 軟件定時器使用了系統的一個隊列一個任務資源,軟件定時器的觸發遵循隊列規則,先進先出。定時時間短的定時器總是比定時時間長的靠近隊列頭,滿足優先被觸發的準則。

? ? ? ? 軟件定時器以Tick為基本計時單位,當用戶創建并啟動一個軟件定時器時,LiteOS會根據當前系統Tick時間寄用戶設置的定時間隔確定該定時器的到期Tick時間,并將該定時器控制結構掛入計時全局鏈表。

? ? ? ? 當Tick中斷到來時,在Tick中斷處理函數中掃描軟件定時器的計時全局鏈表,看是否有定時器超時,若有則將超時的定時器記錄下來。

? ? ? ? Tick中斷處理函數結束后,軟件定時器任務(優先級最高)被喚醒,在該任務中調傭之前記錄下來的定時器的超時回調函數。

三、API介紹

??????osTimerNew

????????函數功能

? ? ? ? 創建一個軟件定時器

? ? ? ??函數原型

osTimerId_t osTimerNew(osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr)

? ? ? ??參數

? ? ? ? func:超時回調函數

? ? ? ? type:運行模式

osTimerOnce0,單次
osTimerPeriodic1,周期

? ? ? ? argument:傳給定時器的參數。沒有填NULL

? ? ? ? attr:定時器相關屬性。自定義地址的時候會用到。大部分情況用不到,填NULL。

? ? ? ??返回值

? ? ? ? NULL:失敗

? ? ? ? 其他值:osTimerId_t類型的定時器ID。該ID給其他函數使用

? ? ? ??實例

osTimerPeriodic char timer1_param[] = "timer1 param"; g_timer1_id = osTimerNew(Timer1_Callback, osTimerPeriodic, timer1_param, NULL);

??????osTimerStart

????????函數功能

? ? ? ? 軟件定時器啟動

? ? ? ??函數原型

osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks)

? ? ? ??參數

? ? ? ? timer_id:軟件定時器ID,創建時osTimerNew獲得。

? ? ? ? ticks:軟件定時器的定時周期。對于Hi3861,定時器單位為10ms。

? ? ? ??返回值

? ? ? ? osOK:成功

? ? ? ? 其他值:失敗

typedef enum {/** Operation completed successfully */osOK = 0,/** Unspecified error */osError = -1,/** Timeout */osErrorTimeout = -2,/** Resource error */osErrorResource = -3,/** Incorrect parameter */osErrorParameter = -4,/** Insufficient memory */osErrorNoMemory = -5,/** Service interruption */osErrorISR = -6,/** Reserved. It is used to prevent the compiler from optimizing enumerations. */osStatusReserved = 0x7FFFFFFF } osStatus_t;

? ? ? ??實例

osTimerId_t g_timer1_id; timerDelay = 100U; status = osTimerStart(g_timer1_id, timerDelay);

??????osTimerStop

????????函數功能

? ? ? ? 軟件定時器停止

? ? ? ??函數原型

osStatus_t osTimerStop(osTimerId_t timer_id)

? ? ? ??參數

? ? ? ? timer_id 定時器ID

? ? ? ??返回值

????????osOK:成功

? ? ? ? 其他值:失敗

? ? ? ??實例

osTimerId_t g_timer1_id; osTimerStop(g_timer1_id);

??????osTimerDelete

????????函數功能

? ? ? ? 軟件定時器刪除

? ? ? ??函數原型

osStatus_t osTimerDelete(osTimerId_t timer_id)

? ? ? ??參數

????????timer_id 定時器ID

? ? ? ??返回值

????????osOK:成功

? ? ? ? 其他值:失敗

? ? ? ??實例

osTimerId_t g_timer1_id; osTimerDelete(g_timer1_id);

四、代碼實例

? ? ? ? 此代碼創建兩個軟件定時器,定時器1為循環定時器,定時器2為單次定時器。

#define LOG_I(fmt, args...) printf("<%8ld> - [TIMER]:"fmt"\r\n",osKernelGetTickCount(),##args); #define LOG_E(fmt, args...) printf("<%8ld>-[TIMER_ERR]>>>>>>>>>>>>:"fmt"\r\n",osKernelGetTickCount(), ##args);osTimerId_t g_timer1_id; osTimerId_t g_timer2_id;/***** 定時器1 回調函數 *****/ void Timer1_Callback(void *arg) {static uint8_t cnt = 0;LOG_I("timer1 callback,cnt:%d,param:%s",cnt,arg);if(cnt++ > 10){osTimerDelete(g_timer1_id);LOG_I("timer1 delete");}else if(cnt == 3){osTimerStop(g_timer1_id);LOG_I("timer1 stop and restart timer2");osTimerStart(g_timer2_id, 500);} }/***** 定時器2 回調函數 *****/ void Timer2_Callback(void *arg) {LOG_I("timer2 callback,param:%d",*(uint32_t *)arg);osTimerStart(g_timer1_id, 100);LOG_I("start timer1"); }char timer1_param[] = "timer1 param"; uint32_t timer2_param = 1024;void Hello_World(void) {LOG_I("Test software Timer");uint32_t timerDelay;osStatus_t status;/*timer 1*/g_timer1_id = osTimerNew(Timer1_Callback, osTimerPeriodic, timer1_param, NULL);if (g_timer1_id != NULL){// Hi3861 1U=10ms,100U=1StimerDelay = 100U;status = osTimerStart(g_timer1_id, timerDelay);if (status != osOK){LOG_E("timer1 start error"); }else{LOG_I("timer1 start success,cycle:%dms",timerDelay * 10);}}else{LOG_E("timer1 create fail!!!");}/*timer 2*/g_timer2_id = osTimerNew(Timer2_Callback, osTimerOnce, (void *)&timer2_param, NULL);if (g_timer2_id != NULL){// Hi3861 1U=10ms,100U=1StimerDelay = 500U;status = osTimerStart(g_timer2_id, timerDelay);if (status != osOK){LOG_E("timer2 start error");}else{LOG_I("timer2 start success,cycle:%dms",timerDelay * 10);}}else{LOG_E("timer2 create fail!!!");} }

? ? ? ? 定時器1為循環定時器,循環周期為1秒,定時器2為單次定時器,超時時間為5秒。兩個定時器同時啟動。在定時器1第三秒的時候,會停止自己,并且重新啟動定時器2。定時器2超時后會重新啟動定時器1。定時器1在第10次時會刪除自己。

? ? ? ? 看運行結果:

? ? ? ? ?可以看到,雖然定時器2在運行,但是如果此時再次調用osTimerStart來啟動定時器2,會刷新定時器的超時時間。

? ? ? ? 這里我們用軟件打印當前的時間戳,來看一下1秒的定時周期是否準確。

? ? ? ? ?可以看到1秒的定時還是很準的。

總結

以上是生活随笔為你收集整理的鸿蒙Hi3861学习六-Huawei LiteOS-M(软件定时器)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。