电子说
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提供两类定时器机制:
03
应用场景
周期触发定时器(MLPeriod),适用于对首次触发时间要求不严格的场合。比如,让LED以280ms周期性亮灭。这种情况下我们并不关心LED首次由灭到亮用了多长时间,我们只要求LED在以后的时间以准确的280ms周期性亮灭。
单次触发定时器(MLShot),适用于对首次触发时间要求严格的场合。另外MLshot定时器自动停止后,调用启动函数MLShot.start,亦可实现周期触发。
04
API接口
microLite_timer支持的MLPeriod接口主要包括:
microLite_timer支持的MLShot接口主要包括:
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
注意事项
全部0条评论
快来发表一下你的评论吧 !