在嵌入式开发中,可能很多人都像我一样遇到过这样的问题:随着项目的功能增多,代码越来越乱,模块之间相互耦合,后期维护与扩展越来越难,尤其是在资源受限的裸机环境下。
今天要介绍的就是一个可以解决这类问题的 MCU 裸机开发框架——task_manage,该框架为我带来了不少便利,我是极力推荐的,一个轻量级、模块化、易于使用、基于时间片轮询的裸机任务调度框架。
并且调用的接口很像操作系统,主要接口如下:
/* 系统、参数、驱动、模块初始化宏注册 */
#define SYSTEM_INIT(func) INIT_EXPORT(func,"1")
#define PARAM_INIT(func) INIT_EXPORT(func,"2")
#define DRIVER_INIT(func) INIT_EXPORT(func,"3")
#define MODULE_INIT(func) INIT_EXPORT(func,"4")
// 系统初始化(最高优先级)
SYSTEM_INIT(system_init_example);
// 驱动初始化(中等优先级)
DRIVER_INIT(driver_init_example);
// 模块初始化(最低优先级)
MODULE_INIT(module_init_example);
比如我写一个函数需要放到主程序中运行,可以这样做:
void task_handler(void)
{
printf("任务执行 @ tick=%u\n", system_tick);
}
/* 注册任务 */
TASK_REGISTER(task_handler, 50); // 任务,50ms间隔
这就极大地解耦了,可以在功能模块文件中直接注册任务!
一、task_manage的核心特点
① 轻量级:整个框架代码量不大,非常适合资源有限的MCU,并且不需要依赖任何第三方库或操作系统。
② 模块化:你可以将每个功能模块(如LED控制、按键扫描、传感器读取)封装成独立任务,方便复用和移植。
③ 简单易用:提供了清晰的API接口,并且只有几个调用接口,好像操作系统。
二、怎么用?
①注册初始化函数
这些函数只要调用一次,有相应的接口,分优先级,通过宏注册
②注册任务并设置执行间隔
这些任务按执行间隔周期性调用,没有优先级,也是通过宏注册
③注册系统tick函数与启动任务调度
系统tick函数用于时间片轮询框架计时,任务调度会自动在后台协调各个任务的运行
举个例子:一个项目中有系统参数、驱动代码、功能模块需要初始化,然后有三个任务,各任务分别按100ms、200ms、300ms周期执行,则代码如下:
#include <stdio.h>
/* 模拟系统tick变量 */
static uint32_t system_tick = 0;
/* 获取系统tick函数 */
uint32_t get_tick(void)
{
return system_tick;
}
/* 初始化函数示例 */
void system_init_example(void)
{
printf("系统初始化完成\n");
}
void driver_init_example(void)
{
printf("驱动初始化完成\n");
}
void module_init_example(void)
{
printf("模块初始化完成\n");
}
/* 任务函数示例 */
void task1_handler(void)
{
printf("任务1执行 @ tick=%u\n", system_tick);
}
void task2_handler(void)
{
printf("任务2执行 @ tick=%u\n", system_tick);
}
void task3_handler(void)
{
printf("任务3执行 @ tick=%u\n", system_tick);
}
/* 注册初始化函数 */
SYSTEM_INIT(system_init_example); // 系统初始化(最高优先级)
DRIVER_INIT(driver_init_example); // 驱动初始化(中等优先级)
MODULE_INIT(module_init_example); // 模块初始化(最低优先级)
/* 注册任务 */
TASK_REGISTER(task1_handler, 100); // 任务1,100ms间隔
TASK_REGISTER(task2_handler, 200); // 任务2,200ms间隔
TASK_REGISTER(task3_handler, 300); // 任务3,300ms间隔
int main(void)
{
/* 注册tick函数 */
task_tick_register(get_tick);
/* 执行初始化 */
task_initialize();
/* 主循环 */
for(;;) {
/* 处理任务 */
task_handle();
/* 延时 */
delay_ms(10);
}
return 0;
}
三、总结
如果你正在做裸机开发,又希望代码能整洁一些、好维护一点,task_manage会是一个很不错的选择。它简单易用,不像一些RTOS那样复杂,却又能帮你实现模块化设计,提高代码质量。
如果您觉得这个项目有用,需要进一步了解,可以查看开源项目地址:https://gitee.com/plant-some-trees/task-manage
1085

被折叠的 条评论
为什么被折叠?



