Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

TTask 多任务调度器模板

轻量级裸机任务调度器,不用 RTOS。
每个任务只需填三个函数指针(init / periodic / on_event),调度器自动按时机调用。
支持消息队列通信、1ms 精确定时。


🤖 AI 一键生成

把整个项目文件夹丢给 AI(Claude、GPT 等),再附上一句你的需求,AI 就能自动为你的 MCU 工程生成多任务框架:

把这个 TTask 模板集成到我的 STM32G0 项目中。
我的项目有:
• 按键扫描(4个按键,10ms 轮询)
• LED 指示灯(2个,状态指示)
• 串口协议解析(115200bps,不定长帧)
• 继电器控制(3路,带过零检测)
帮我生成对应的 task_xxx.c 和 timer.c 移植代码。

原理: 仓库中的 SKILL.md 包含了调度器的完整知识(API、任务模式、消息通信、移植方法、注意事项),AI 阅读后就能精准理解并替你写出适配代码。你只需要把生成的 task_xxx.c 放到工程里注册即可。

💡 这就是本项目的主要使用方式——不用自己读源码,交给 AI 理解框架然后自动输出你需要的任务代码。


快速开始

1. 目录结构

TTask-MultiTask-Template/
├── README.md ← 本文件
├── SKILL.md ← 完整技能文档(含教程、示例、FAQ)
├── User/
│ ├── main.c ← 主入口(只需 3 行)
│ └── scheduler/
│ ├── ptask.h / .c ← Protothreads + 消息队列(底层)
│ ├── ttask.h / .c ← 通用任务模板(上层 API)
│ ├── timer.h ← 硬件定时器接口
│ ├── tasks.h ← 任务 ID 定义
│ └── tasks.c ← 任务集中注册
├── examples/ ← 6 个示例任务
│ ├── task_led.c ← LED 闪烁
│ ├── task_key.c ← 按键扫描 + 消息发送
│ ├── task_echo.c ← 串口回显 + 定时报告 + 事件接收
│ ├── task_ota.c ← OTA 升级(纯事件驱动)
│ ├── task_sensor.c ← 传感器读取(慢周期)
│ └── task_relay.c ← 继电器定时控制
└── port/ ← 移植指南
└── PORTING.md ← 各平台移植说明

2. 移植到你的项目

三步移植:

① 实现 1ms 硬件定时器

在你的工程中创建一个 timer.c,实现:

#include"scheduler/ptask.h"voidTimer_Init_1ms(void)
{
// 配置你的 MCU 硬件定时器,产生 1ms 中断// 在定时器中断中调用 PTASK_Tick();
}
// 定时器中断服务函数voidTIMx_IRQHandler(void)
{
// 清除中断标志PTASK_Tick(); // ← 驱动调度器时基
}

各平台的参考实现见 port/PORTING.md

② 创建一个任务

复制 examples/task_led.c 到你的 User/ 目录,按需修改:

#include"scheduler/ttask.h"staticvoidmy_init(void) { /* 初始化外设 */ }
staticvoidmy_periodic(void) { /* 周期执行的逻辑 */ }
staticvoidmy_event(uint16_tevent, uint16_tparam, void*data) {
/* 收到消息时处理 */
}
TTasktask_my= {
.init=my_init,
.periodic=my_periodic,
.interval=100, // 每 100ms 执行一次
.on_event=my_event,
};

③ 注册任务

scheduler/tasks.h 加一行 ID:

#defineTASK_ID_MY 6 /* 你的新任务 */

scheduler/tasks.c 加一行注册:

externTTasktask_my;
TTASK_Register(&task_my); /* TASK_ID_MY = 6 */

3. 核心 API

API说明
TTASK_Init()初始化调度器
TTASK_Register(&task)注册任务,返回 ID
TTASK_Run()主循环调用,驱动调度
TTASK_SendEvent(id, param)发送消息
TTASK_SendEventISR(id, param)从中断发送消息
PTASK_GetTick()获取 1ms 时基计数值

4. 三种任务模式

模式实现方式适用场景
周期执行.periodic + .intervalLED 闪烁、按键扫描、传感器轮询
事件驱动.on_event,不填 periodicOTA 升级、串口命令响应
混合两者都填继电器控制(周期检查超时 + 事件触发开关)

5. 任务间通信

// 发消息TTASK_SendEvent(TASK_ID_ECHO, TASK_PARAM(1, 1)); // 按键1单击// 收消息(定义 on_event 回调即可)staticvoidmy_event(uint16_tevent, uint16_tparam, void*data) {
uint8_tkey=TASK_KEY(param); // 获取按键号uint8_tevt=TASK_EVT(param); // 获取事件类型
}

6. 关键特性

特性说明
零 RTOS 依赖纯 C 实现,只需 1ms 硬件定时器
低 RAM 占用每任务约 20 字节
补偿式调度last_run += interval,消除时间漂移
消息队列每任务 8 条深度,环形缓冲
中断安全SendEventISR 关中断保护
uint32_t 溢出安全差值计算,溢出后仍正确

7. 从轮询迁移到 TTask

// 改造前:超级循环while(1) {
KEY_Scan();
USART_Echo();
Sensor_Read();
LED_Toggle();
Delay_Ms(10);
}
// 改造后:拆成 4 个 TTaskTTasktask_key= { .periodic=KEY_Scan, .interval=10 };
TTasktask_echo= { .periodic=USART_Echo, .interval=1 };
TTasktask_sensor= { .periodic=Sensor_Read, .interval=1000 };
TTasktask_led= { .periodic=LED_Toggle, .interval=500 };
// main 只剩一行while(1) TTASK_Run();

许可证

基于 WCH 官方 CH32V303 EVT 例程的调度器实现,MIT 许可证。

About

轻量级裸机任务调度器,不用 RTOS。 每个任务只需填三个函数指针(init / periodic / on_event),调度器自动按时机调用。 支持消息队列通信、1ms 精确定时。

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages