概述
TaskScheduler是协作式多任务(任务调度)的轻量级实现,主要有以下特点:
任务周期性执行,执行频率以毫秒(默认)或微秒(如果显式启用)为单位;
支持设定执行次数(有限或无限次)
按预定义的顺序执行任务
支持任务执行参数的动态变化(频率、执行次数、回调方法)
支持在没有任务运行时进入睡眠模式以省电
支持事件驱动的任务调度
支持任务优先级
调度开销:每次调度 15 到 18 微秒(Arduino UNO rev 3 @ 16MHz 时钟,没有优先级的单个调度程序)
基本用法
/**
* TaskScheduler 测试
* 初始化时,task1和task2是激活的
* task1 间隔2s,运行10次后停止
* task2 间隔3s,一直运行
* task1 第一次运行时激活task3
* task3 间隔5s,一直运行
* task1 最后一次运行时关闭task3,并将task2的运行间隔设置为1/2s
*/
#include <TaskScheduler.h>
// 声明回调函数,即任务实际执行的代码
void t1Callback();
void t2Callback();
void t3Callback();
// 定义任务
Task t1(2000, 10, &t1Callback); //任务名称t1,间隔2000ms,总共执行10次,执行的代码为t1Callback()
Task t2(3000, TASK_FOREVER, &t2Callback);//任务名称t2,间隔3000ms,一直执行,执行的代码为t2Callback()
Task t3(5000, TASK_FOREVER, &t3Callback);//任务名称t3,间隔5000ms,一直执行,执行的代码为t3Callback()
//声明调度器
Scheduler runner;
//定义t1Callback()
void t1Callback() {
Serial.print("t1: ");
Serial.println(millis());
if (t1.isFirstIteration()) {//如果t1任务是第一次运行,则执行该代码块
runner.addTask(t3);//将t3任务添加到调度器的任务链中,添加之后要打开(使能)才能够真正运行
t3.enable();//打开t3任务,执行该语句后,t3任务会立即执行
Serial.println("t1: 将t3任务加入任务链并开始执行");
}
if (t1.isLastIteration()) {//如果t1任务是最后一次运行,则执行该代码块
t3.disable();//关闭t3任务
runner.deleteTask(t3);//从任务链中删除t3任务
t2.setInterval(500);//将t2任务的执行间隔设置为500ms
Serial.println("t1: 关闭t3任务并将其从任务链中删除,并将t2任务的执行间隔设置为500ms");
}
}
//定义t2Callback()
void t2Callback() {
Serial.print("t2: ");
Serial.println(millis());
}
//定义t3Callback()
void t3Callback() {
Serial.print("t3: ");
Serial.println(millis());
}
void setup () {
Serial.begin(115200);
Serial.println("Scheduler TEST");
runner.init();
Serial.println("初始化 scheduler");
runner.addTask(t1);
Serial.println("添加t1任务");
runner.addTask(t2);
Serial.println("添加t2任务");
delay(5000);
t1.enable();
Serial.println("打开t1任务");
t2.enable();
Serial.println("打开t2任务");
}
void loop () {
//loop()中只要调用调度器的execute()函数即可
runner.execute();
}
任务生命周期
看图

注意
- 在PlatformIO中使用需要在声明中包含
#define _TASK_INLINE;
参考资料
版权声明:本文为weixin_39155340原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。