01
掃描周期與時(shí)鐘節(jié)拍
一般小型系統(tǒng)由Background和Foreground構(gòu)成。Background稱(chēng)為任務(wù)區(qū),F(xiàn)oreground稱(chēng)為中斷區(qū)。對(duì)實(shí)時(shí)性要求很高的操作要由中斷區(qū)的中斷服務(wù)程序來(lái)完成。位于Background區(qū)域的任務(wù)響應(yīng)時(shí)間取決于超級(jí)循環(huán)(Super-Loops)執(zhí)行一次的時(shí)間,也稱(chēng)之為掃描周期ScanCycleTime。掃描周期并不固定,任務(wù)執(zhí)行過(guò)程中掃描周期的最大值意味著任務(wù)最壞的響應(yīng)時(shí)間。
microLite裸機(jī)系統(tǒng)最小的時(shí)間單位是時(shí)鐘節(jié)拍(Tick),時(shí)鐘節(jié)拍是特定的周期性中斷,這個(gè)中斷可以看做是系統(tǒng)心跳,時(shí)鐘節(jié)拍由硬件定時(shí)器產(chǎn)生,當(dāng)中斷到來(lái)時(shí),將調(diào)用一次ml_tick_increase()。不同硬件定時(shí)器的中斷實(shí)現(xiàn)不同,下面的中斷函數(shù)以 STM32 定時(shí)器作為示例:
void SysTick_Handler(void)
{
ml_tick_increase();
}
在中斷函數(shù)中調(diào)用 ml_tick_increase()對(duì)全局變量 ml_tick 進(jìn)行自加,代碼如下:
void ml_tick_increase(void)
{
ml_tick++;
}
通過(guò)調(diào)用 ml_tick_get會(huì)返回當(dāng)前 ml_tick 的值,即可以獲取到當(dāng)前的時(shí)鐘節(jié)拍值。此接口可用于獲取系統(tǒng)的最大掃描周期,或者測(cè)量某任務(wù)運(yùn)行的時(shí)間。接口函數(shù)如下:
ml_tick_t ml_tick_get(void)
{
ml_tick_t t = 0;
t = ml_tick;
while (t != ml_tick) {
t = ml_tick;
}
return t;
}
02
microLite_timer介紹
軟件定時(shí)器microLite_timer提供兩類(lèi)定時(shí)器機(jī)制:
- 第一類(lèi)是周期觸發(fā)定時(shí)器(MLPeriod),這類(lèi)定時(shí)器會(huì)周期性的觸發(fā)定時(shí)器,并且“一旦啟動(dòng),永不停止”。
- 第二類(lèi)是單次觸發(fā)定時(shí)器(MLShot),這類(lèi)定時(shí)器在啟動(dòng)后只會(huì)觸發(fā)一次定時(shí)器事件,然后定時(shí)器自動(dòng)停止。
03
應(yīng)用場(chǎng)景
周期觸發(fā)定時(shí)器(MLPeriod),適用于對(duì)首次觸發(fā)時(shí)間要求不嚴(yán)格的場(chǎng)合。比如,讓LED以280ms周期性亮滅。這種情況下我們并不關(guān)心LED首次由滅到亮用了多長(zhǎng)時(shí)間,我們只要求LED在以后的時(shí)間以準(zhǔn)確的280ms周期性亮滅。
單次觸發(fā)定時(shí)器(MLShot),適用于對(duì)首次觸發(fā)時(shí)間要求嚴(yán)格的場(chǎng)合。另外MLshot定時(shí)器自動(dòng)停止后,調(diào)用啟動(dòng)函數(shù)MLShot.start,亦可實(shí)現(xiàn)周期觸發(fā)。
04
API接口
microLite_timer支持的MLPeriod接口主要包括:
- MLPeriod.Init,初始化定時(shí)器;
- MLPeriod.run;
- MLPeriod.check,檢查定時(shí)器是否超時(shí)。
microLite_timer支持的MLShot接口主要包括:
- MLShot.start,啟動(dòng)定時(shí)器;
- MLShot.stop,停止定時(shí)器;
- MLShot.check,檢查定時(shí)器是否超時(shí)。
05.1
MLPeriod編程范例
需求:讓4個(gè)任務(wù)分別以1000ms、500ms、500ms、800ms周期性執(zhí)行。
代碼實(shí)現(xiàn):
#include "microLite_timer.h"
#include "stdio.h"
void test1(void)
{
MLPeriod.init();
printf("microLite - Bare metal system, 2021 Copyright by stevenLyanrnrn");
printf("microLite timer sample, current tick is %d rn", ml_tick_get());
while (1) {
MLPeriod.run();
if (MLPeriod.check(1000)) {
printf("task1, current tick is %drn", ml_tick_get());
}
if (MLPeriod.check(500)) {
printf("task2, current tick is %drn", ml_tick_get());
}
if (MLPeriod.check(500)) {
printf("task3, current tick is %drn", ml_tick_get());
}
if (MLPeriod.check(800)) {
printf("task4, current tick is %drn", ml_tick_get());
}
}
}
運(yùn)行效果:
microLite - Bare metal system, 2021 Copyright by stevenLyan
microLite timer sample, current tick is 9
task2, current tick is 513
task3, current tick is 515
task4, current tick is 813
task1, current tick is 1013
task2, current tick is 1015
task3, current tick is 1018
task2, current tick is 1513
task3, current tick is 1515
task4, current tick is 1613
task1, current tick is 2013
task2, current tick is 2015
task3, current tick is 2018
task4, current tick is 2413
05.2
MLShot編程范例
需求:見(jiàn)下面“代碼實(shí)現(xiàn)”的注釋。
代碼實(shí)現(xiàn):
#include "microLite_timer.h"
#include "stdio.h"
static ml_shotTimer_TypeDef test2_timer1 = {0};
static ml_shotTimer_TypeDef test2_timer2 = {0};
static ml_shotTimer_TypeDef test2_timer3 = {0};
void test2(void)
{
printf("microLite - Bare metal system, 2021 Copyright by stevenLyanrnrn");
printf("microLite timer sample, current tick is %d rn", ml_tick_get());
MLShot.start(&test2_timer1, 800);
MLShot.start(&test2_timer2, 500);
while (1) {
/*----------------------------------------------------------------------------*/
/* Schedules the specified task for execution after the specified delay.
[the specified delay]: [timer1]800 ticks */
if (MLShot.check(&test2_timer1)) {
printf("timer1 stop(auto), current tick is %d!!!rn", ml_tick_get());
}
/*----------------------------------------------------------------------------*/
/* Schedules the specified task for repeated fixed-delay execution, beginning
after the specified delay.
[the specified delay]: [timer2]500 ticks
[repeated fixed-delay]: [timer3]1000 ticks
*/
if (MLShot.check(&test2_timer2)) {
MLShot.start(&test2_timer3, 1000);
printf("timer2 stop(auto) and timer3 start, current tick is %d!!!rn", ml_tick_get());
}
if (MLShot.check(&test2_timer3)) {
MLShot.start(&test2_timer3, 1000);
printf("timer3 timeout, current tick is %drn", ml_tick_get());
}
}
}
運(yùn)行效果:
microLite - Bare metal system, 2021 Copyright by stevenLyan
microLite - Bare metal system, 2021 Copyright by stevenLyan
microLite timer sample, current tick is 9
timer2 stop(auto) and timer3 start, current tick is 513!!!
timer1 stop(auto), current tick is 813!!!
timer3 timeout, current tick is 1514
timer3 timeout, current tick is 2515
timer3 timeout, current tick is 3516
timer3 timeout, current tick is 4517
06
注意事項(xiàng)
- MLPeriod.run在一個(gè)掃描周期內(nèi),應(yīng)被調(diào)用一次且僅一次;
- 不建議將MLPeriod.check的參數(shù)設(shè)置為不固定值;
- 不建議嵌套使用MLPeriod.check;
- MLPeriod支持定時(shí)周期不同的定時(shí)器的個(gè)數(shù)為ML_PERIODTIMER_MAX;
- MLShot觸發(fā)后,定時(shí)器自動(dòng)停止;
- microLite_timer的定時(shí)精度由系統(tǒng)Tick時(shí)鐘的周期以及掃描周期決定。
-
led燈
+關(guān)注
關(guān)注
22文章
1596瀏覽量
109725 -
軟件定時(shí)器
+關(guān)注
關(guān)注
0文章
18瀏覽量
6940 -
觸發(fā)器
+關(guān)注
關(guān)注
14文章
2039瀏覽量
62135 -
stm32定時(shí)器
+關(guān)注
關(guān)注
0文章
13瀏覽量
2424
發(fā)布評(píng)論請(qǐng)先 登錄
GD32對(duì)Timer定時(shí)器原理的詳細(xì)講解

為什么選擇esp_timer定時(shí)器作為esp32首選軟件定時(shí)器呢
51定時(shí)器計(jì)算軟件

通用定時(shí)器(Timer)
通用定時(shí)器(Timer)總體特性的功能概述和詳細(xì)的程序概述

ESP8266的管腳的控制和軟件定時(shí)器的使用

基于硬件定時(shí)器的軟件定時(shí)器

ESP32 之 ESP-IDF 教學(xué)(三)——通用硬件定時(shí)器(Timer)

msp432快速入門(mén)第十節(jié)之timer32定時(shí)器

FreeRTOS軟件定時(shí)器的使用步驟
基礎(chǔ)定時(shí)器實(shí)驗(yàn)

什么是軟件定時(shí)器?軟件定時(shí)器的實(shí)現(xiàn)原理
STM32L4定時(shí)器(TIMER)介紹

關(guān)于軟件定時(shí)器的一些討論

評(píng)論