01
扫描周期与时钟节拍
一般小型系统由Background和Foreground构成。Background称为任务区,Foreground称为中断区。对实时性要求很高的操作要由中断区的中断服务程序来完成。位于Background区域的任务响应时间取决于超级循环(Super-Loops)执行一次的时间,也称之为扫描周期ScanCycleTime。扫描周期并不固定,任务执行过程中扫描周期的最大值意味着任务最坏的响应时间。
microLite裸机系统最小的时间单位是时钟节拍(Tick),时钟节拍是特定的周期性中断,这个中断可以看做是系统心跳,时钟节拍由硬件定时器产生,当中断到来时,将调用一次ml_tick_increase()。不同硬件定时器的中断实现不同,下面的中断函数以 STM32 定时器作为示例:
void SysTick_Handler(void)
{
ml_tick_increase();
}
在中断函数中调用 ml_tick_increase()对全局变量 ml_tick 进行自加,代码如下:
void ml_tick_increase(void)
{
ml_tick++;
}
通过调用 ml_tick_get会返回当前 ml_tick 的值,即可以获取到当前的时钟节拍值。此接口可用于获取系统的最大扫描周期,或者测量某任务运行的时间。接口函数如下:
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介绍
软件定时器microLite_timer提供两类定时器机制:
- 第一类是周期触发定时器(MLPeriod),这类定时器会周期性的触发定时器,并且“一旦启动,永不停止”。
- 第二类是单次触发定时器(MLShot),这类定时器在启动后只会触发一次定时器事件,然后定时器自动停止。
03
应用场景
周期触发定时器(MLPeriod),适用于对首次触发时间要求不严格的场合。比如,让LED以280ms周期性亮灭。这种情况下我们并不关心LED首次由灭到亮用了多长时间,我们只要求LED在以后的时间以准确的280ms周期性亮灭。
单次触发定时器(MLShot),适用于对首次触发时间要求严格的场合。另外MLshot定时器自动停止后,调用启动函数MLShot.start,亦可实现周期触发。
04
API接口
microLite_timer支持的MLPeriod接口主要包括:
- MLPeriod.Init,初始化定时器;
- MLPeriod.run;
- MLPeriod.check,检查定时器是否超时。
microLite_timer支持的MLShot接口主要包括:
- MLShot.start,启动定时器;
- MLShot.stop,停止定时器;
- MLShot.check,检查定时器是否超时。
05.1
MLPeriod编程范例
需求:让4个任务分别以1000ms、500ms、500ms、800ms周期性执行。
代码实现:
#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());
}
}
}
运行效果:
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编程范例
需求:见下面“代码实现”的注释。
代码实现:
#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());
}
}
}
运行效果:
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
注意事项
- MLPeriod.run在一个扫描周期内,应被调用一次且仅一次;
- 不建议将MLPeriod.check的参数设置为不固定值;
- 不建议嵌套使用MLPeriod.check;
- MLPeriod支持定时周期不同的定时器的个数为ML_PERIODTIMER_MAX;
- MLShot触发后,定时器自动停止;
- microLite_timer的定时精度由系统Tick时钟的周期以及扫描周期决定。
-
led灯
+关注
关注
22文章
1592浏览量
108157 -
软件定时器
+关注
关注
0文章
18浏览量
6776 -
触发器
+关注
关注
14文章
2000浏览量
61237 -
stm32定时器
+关注
关注
0文章
13浏览量
2301
发布评论请先 登录
相关推荐
评论