最近刷知乎、B站,大家都在聊怎么在Arduino、ESP32上跑多任务,不想被 delay() 锁死,也觉得FreeRTOS有点重。别急,今天给你安利一个超轻量、超好用的“调度神器”——TaskScheduler。保准让你秒懂协作式多任务!
什么是TaskScheduler
TaskScheduler 是一个专门为Arduino、ESPx、STM32等MCU平台打造的协作式多任务调度库。简单来说,你把不同的任务(Task)交给它,它按照你定好的频率、次序,帮你自动执行,不会出现死锁、竞态这种让人头秃的并发问题。
能帮你做什么
-
• 周期性执行任务:毫秒级(默认)或微秒级(可选)
-
• 限定或无限次循环,灵活切换
-
• 按顺序、按优先级调度,随时动态修改参数
-
• 空闲时自动睡眠,省电利器
-
• 事件驱动调用,状态请求对象随你玩
-
• 错误处理、看门狗、任务ID和控制点,出错更好诊断
-
• 支持
std::function、本地存储指针、动态绑定回调 -
• FreeRTOS 下“无滴答”模式,连睡眠都替你搞定
下面这张表,帮你快速浏览核心特性:
|
功能 |
说明 |
|
周期执行 |
ms/μs 精度,支持动态变更 |
|
循环次数 |
限定次数/无限循环 |
|
调度模式 |
原始顺序/带补偿/定 interval |
|
省电模式 |
IDLE 睡眠 |
|
事件驱动 |
Status Request 对象调用 |
|
错误 & 看门狗 |
任务超时、控制点监测 |
|
兼容性 |
Arduino、ESP、STM32、nRF52、MSP430… |
解决了哪些痛点
-
1. 延迟锁死:不用再写一堆
if (millis()-last>delta),代码清爽 -
2. 竞态死锁:协作式调度天然避免并发陷阱
-
3. 切换频率:运行中随手改任务频率、迭代次数,实时生效
-
4. 省电需求:自动进IDLE睡眠,复杂系统也能轻松省电
-
5. 可维护性:再也不用在
loop()里塞一堆时序判断了
如何安装和使用
-
1. 打开 Arduino IDE,库管理 搜索 “TaskScheduler”,一键安装
-
2. 或者:
cd your-projects-folder
git clone https://github.com/arkhipenko/TaskScheduler.git -
3. 在代码开头加一句:
#include <TaskScheduler.h> -
4. 下面这段「三步走」示例,跟着敲,保证秒会上手:
Scheduler runner; // 调度器
TaskledTask(1000, TASK_FOREVER,[](){
digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN));
});
voidsetup(){
pinMode(LED_BUILTIN, OUTPUT);
runner.init();
runner.addTask(ledTask);
ledTask.enable();
}
voidloop(){
runner.execute();
}
示例代码速览
下面是一个稍微复杂点的 Demo,演示“动态添加/删除任务”、“限次循环”、“修改频率”怎么玩:
#include <TaskScheduler.h>
Scheduler runner;
// 定义任务回调
voidt1Callback();
voidt2Callback();
voidt3Callback();
// 任务对象
Taskt1(2000,5,&t1Callback);// 执行5次
Taskt2(3000, TASK_FOREVER,&t2Callback);
Taskt3(500, TASK_FOREVER,&t3Callback);
voidsetup(){
Serial.begin(115200);
runner.init();
runner.addTask(t1);
runner.addTask(t2);
delay(1000);
t1.enable();
t2.enable();
}
voidloop(){
runner.execute();
}
voidt1Callback(){
Serial.println("t1 执行");
if(t1.isFirstIteration()){
runner.addTask(t3);
t3.enable();
Serial.println(" >> 添加 t3");
}
if(t1.isLastIteration()){
t3.disable();
runner.deleteTask(t3);
t2.setInterval(500);
Serial.println(" >> 删除 t3,t2 频率变 500ms");
}
}
voidt2Callback(){
Serial.println("t2 执行");
}
voidt3Callback(){
Serial.println("t3 高频执行");
}
优缺点大盘点
|
优点 |
缺点 |
|
非常轻量:UNO 上单次调度仅 ~15μs |
微秒级模式需显式开启,略麻烦 |
|
协作式不易死锁、竞态 |
不是抢占式,重任务会影响整体调度 |
|
支持动态增删、动态修改参数 |
回调函数里逻辑要写好,否则容易“拖”调度 |
|
FreeRTOS 可“无滴答”睡眠 |
对新手来说,事件驱动概念需适应 |
|
内置看门狗、错误处理 |
平台兼容列表有限(虽常见板子都有) |
总结
TaskScheduler 就像给你的MCU装了个「调度大脑」,不管是简单的 LED 闪烁,还是复杂的传感器轮询、网络心跳,全都一句 runner.execute(),剩下的交给它跑、交给它省电、交给它管理。对于想要写出结构清晰、易维护、低功耗的项目,真的强烈推荐一试!
项目地址:https://github.com/arkhipenko/TaskScheduler