FreeRTOS之軟件定時器詳解
來源:網(wǎng)絡素材
整理:技術讓夢想更偉大 | 李肖遙
定時器可以說是每個 MCU 都有的外設,有的 MCU 其定時器功能異常強大,比如提供 PWM、輸入捕獲等功能。但是最常用的還是定時器最基礎的功能——定時,通過定時器來完成需要周期性處理的事務。
MCU 自帶的定時器屬于硬件定時器,不同的 MCU 其硬件定時器數(shù)量不同,因為要考慮成本的問題。FreeRTOS 也提供了定時器功能,不過是軟件定時器,軟件定時器的精度肯定沒有硬件定時器那么高,但是對于普通的精度要求不高的周期性處理的任務來說夠了。當 MCU 的硬件定時器不夠的時候就可以考慮使用 FreeRTOS 的軟件定時器。
軟件定時器簡介
軟件定時器允許設置一段時間,當設置的時間到達之后就執(zhí)行指定的功能函數(shù),被定時器調用的這個功能函數(shù)叫做定時器的回調函數(shù)?;卣{函數(shù)的兩次執(zhí)行間隔叫做定時器的定時周期,簡而言之,當定時器的定時周期到了以后就會執(zhí)行回調函數(shù)。
軟件定時器的回調函數(shù)是在定時器服務任務中執(zhí)行的,所以一定不能在回調函數(shù)中調用任何會阻塞任務的 API 函數(shù)!比如,定時器回調函數(shù)中千萬不能調用 vTaskDelay()、vTaskDelayUnti(),還有一些訪問隊列或者信號量的非零阻塞時間的 API 函數(shù)也不能調用。
定時器服務/Daemon 任務
定時器是一個可選的、不屬于 FreeRTOS 內核的功能,它是由定時器服務(或 Daemon)任務來提供的。
FreeRTOS 提供了很多定時器有關的 API 函數(shù),這些 API 函數(shù)大多都使用 FreeRTOS的隊列發(fā)送命令給定時器服務任務。這個隊列叫做定時器命令隊列。定時器命令隊列是提供給FreeRTOS 的軟件定時器使用的,用戶不能直接訪問!
版權聲明:本文來源網(wǎng)絡,免費傳達知識,版權歸原作者所有。如涉及作品版權問題,請聯(lián)系我進行刪除。
???????????????? END ???????????????
關注我的微信公眾號,回復“加群”按規(guī)則加入技術交流群。
點擊“閱讀原文”查看更多分享,歡迎點分享、收藏、點贊、在看。

左側部分屬于用戶應用程序的一部分,并且會在某個用戶創(chuàng)建的用戶任務中調用。圖中右側部分是定時器服務任務的任務函數(shù),定時器命令隊列將用戶應用任務和定時器服務任務連接在一起。在這個例子中,應用程序調用了函數(shù) xTimerReset(),結果就是復位命令會被發(fā)送到定時器命令隊列中,定時器服務任務會處理這個命令。應用程序是通過函數(shù) xTimerReset()間接的向定時器命令隊列發(fā)送了復位命令,并不是直接調用類似 xQueueSend()這樣的隊列操作函數(shù)發(fā)送的。
定時器相關配置
配置在文件 FreeRTOSConfig.h 中。
1、configUSE_TIMERS
如果要使用軟件定時器的話宏 configUSE_TIMERS 一定要設置為 1,當設置為 1 的話定時器服務任務就會在啟動 FreeRTOS 調度器的時候自動創(chuàng)建。
2、configTIMER_TASK_PRIORITY
設置軟件定時器服務任務的任務優(yōu)先級,可以為 0~( configMAX_PRIORITIES-1)。優(yōu)先級一定要根據(jù)實際的應用要求來設置。如果定時器服務任務的優(yōu)先級設置的高的話,定時器命令隊列中的命令和定時器回調函數(shù)就會及時的得到處理。
3、configTIMER_QUEUE_LENGTH
此宏用來設置定時器命令隊列的隊列長度。
4、configTIMER_TASK_STACK_DEPTH
此宏用來設置定時器服務任務的任務堆棧大小,單位為字,不是字節(jié)!,對于 STM32 來說一個字是 4 字節(jié)。由于定時器服務任務中會執(zhí)行定時器的回調函數(shù),因此任務堆棧的大小一定要根據(jù)定時器的回調函數(shù)來設置。
單次定時器和周期定時器
軟件定時器分兩種:單次定時器和周期定時器,單次定時器的話定時器回調函數(shù)就執(zhí)行一次,比如定時 1s,當定時時間到了以后就會執(zhí)行一次回調函數(shù),然后定時器就會停止運行。對于單次定時器我們可以再次手動重新啟動(調用相應的 API 函數(shù)即可),但是單次定時器不能自動重啟。相反的,周期定時器一旦啟動以后就會在執(zhí)行完回調函數(shù)以后自動的重新啟動,這樣回調函數(shù)就會周期性的執(zhí)行。

Timer1 為單次定時器,定時器周期為 100,Timer2 為周期定時器,定時器周期為 200。
API
1、復位軟件定時器
有時候我們可能會在定時器正在運行的時候需要復位軟件定時器,復位軟件定時器的話會重新計算定時周期到達的時間點,這個新的時間點是相對于復位定時器的那個時刻計算的,并不是第一次啟動軟件定時器的那個時間點。下圖演示了這個過程,Timer1 是單次定時器,定時周期是 5s:

定時器復位過程,這是一個通過按鍵打開 LCD 背光的例子,我們假定當喚醒鍵被按下的時候應用程序打開 LCD 背光,當 LCD 背光點亮以后如果 5s 之內喚醒鍵沒有再次按下就自動熄滅。如果在這 5s 之內喚醒鍵被按下了,LCD 背光就從按下的這個時刻起再亮 5s。
FreeRTOS 提供了兩個 API 函數(shù)來完成軟件定時器的復位:

2、創(chuàng)建軟件定時器

3、開啟軟件定時器
如果軟件定時器停止運行的話可以使用 FreeRTOS 提供的兩個開啟函數(shù)來重新啟動軟件定時器。

4、停止軟件定時器

具體的函數(shù)使用大家可以在用到的時候搜索用法,看一遍其實也記不住的。
