一、说明:
示意图

总结:
通过回调函数,与任务块在定时器中断里进行循环检测,当到达设定时间,就置为ready,调用回调,执行对应的任务。
这里使用一个例子:
串口输出,
led,iwdg,
显示信息,
来反映这个模型。
c
// ==================== 任务调度相关全局变量 ====================
volatile uint32_t system_tick_ms = 0; // 系统时间计数器(每1ms+1)
// 任务控制块结构体
typedef struct {
void (*task_func)(void); // 任务函数指针
uint32_t period_ms; // 任务周期(毫秒)
uint32_t remain_ms; // 当前倒计时剩余值
uint8_t ready_flag; // 就绪标志(1=可执行)
uint8_t is_running; // 正在执行标志(防止重入)
uint32_t exec_count; // 任务执行次数统计(用于状态显示)
} Task_Control_Block;
// 任务列表(4个任务)
#define TASK_NUM 4
Task_Control_Block task_list[TASK_NUM] = {
{ .task_func = Task_LED_Blink, .period_ms = 100, .remain_ms = 100, .ready_flag = 0, .is_running = 0, .exec_count = 0 },
{ .task_func = Task_UART_Communication, .period_ms = 200, .remain_ms = 200, .ready_flag = 0, .is_running = 0, .exec_count = 0 },
{ .task_func = Task_FeedWatchdog, .period_ms = 50, .remain_ms = 50, .ready_flag = 0, .is_running = 0, .exec_count = 0 },
{ .task_func = Task_StatusDisplay, .period_ms = 1000, .remain_ms = 1000,.ready_flag = 0, .is_running = 0, .exec_count = 0 }
};
/**
* @brief 中断服务更新函数(由TIM4中断每1ms调用一次)
* 仅负责递减计数器、置位就绪标志,绝不执行任务函数
*/
void Timer_Service_Update(void) {
system_tick_ms++; // 系统时间累加
for (uint8_t i = 0; i < TASK_NUM; i++) {
// 只处理未就绪且未运行的任务(避免干扰正在执行的任务)
if (!task_list[i].ready_flag && !task_list[i].is_running) {
if (task_list[i].remain_ms > 0) {
task_list[i].remain_ms--;
}
if (task_list[i].remain_ms == 0) {
task_list[i].ready_flag = 1; // 置位就绪
task_list[i].remain_ms = task_list[i].period_ms; // 重载周期
}
}
}
}
/**
* @brief 主循环调度函数(在while(1)中反复调用)
* 轮询就绪任务,按数组顺序执行
*/
void Scheduler_Run(void) {
for (uint8_t i = 0; i < TASK_NUM; i++) {
if (task_list[i].ready_flag && !task_list[i].is_running) {
task_list[i].is_running = 1;
task_list[i].ready_flag = 0; // 清除就绪标志
// 执行任务
task_list[i].task_func();
task_list[i].exec_count++; // 统计执行次数
task_list[i].is_running = 0;
}
}
}
main()
{
while (1)
{ // 启动TIM的1ms中断
Scheduler_Run(); // 主循环调度
// 空闲时可执行低优先级后台任务或进入低功耗模式
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM4) {
Timer_Service_Update(); // 每1ms调用一次更新函数
}
}
运行结果:
