单片机应用程序框架时间片轮询法的学习。
根据所见的,学的,看的。大致分为三类程序结构。
1. 简单的前后台顺序执行程序。
2. 时间片轮询法。
3. 操作系统。
简单的顺序执行的程序,写起来往往很混乱。越复杂的需求程序,完成需求的时间会更多,质量也并不好,bug也会越多,导致程序一直不能让自己满意。
为此我们需要用某个东西去管理我们的mcu中的执行逻辑。也就很容易想到用时间这条线去管理我们的逻辑。
首先我们需要构建一个结构体数据类型去管理任务
typedef struct
{
void(*task_func)(void); //函数指针
uint16_t interval_time; //执行时间间隔
uint16_t run_timer; //倒计时器
uint8_t run_sign; //程序运行标志
} schedule_task_t;
我们还得有任务
void task_1(void)
{
printf("我是任务1");
}
void task_2(void)
{
printf("我是任务2");;
}
void task_3(void)
{
printf("我是任务3");;
}
然后定义一个结构体,创建任务管理配置
//创建任务配置
static schedule_task_t schedule_task[] =
{
{task_1, 20, 20, 0} //task_1(函数名) 20 (执行周期) 20(计时器) 0(任务执行标志)
{task_2, 10, 10, 0},
{task_3, 5, 5, 0}
};
当然我们要知道任务数量,可以根据数组长度去判断
//根据数组长度,判断任务数量
#define TASK_NUM (sizeof(schedule_task)/sizeof(schedule_task_t))
我们需要一个定时器中断资源去计时。让这个定时器来管理我们的任务。所以我们需要在中断中去判断查询任务标志。
// 在中断中调用次函数判断任务标志
void task_interrupt(void)
{
uint8_t index = 0;
// 循环判断
for (index = 0; index < TASK_NUM; index++)
{
// 判断计时器是否到时间
if (schedule_task[index].run_timer) //不为0
{
// 计时器减1
schedule_task[index].run_timer--;
//判断计时器是否到时间
if (0 == schedule_task[index].run_timer)
{
// 恢复倒计时器的时间
schedule_task[index].run_timer = schedule_task[index].interval_time;
// 任务标志置1
schedule_task[index].run_sign = 1;
}
}
}
}
任务的周期由定时器去判断,管理。我们只需要在主循环中判断有无任务标志,然后执行它即可。
void task_process(void)
{
uint8_t index = 0;
// 循环判断任务
for (index = 0; index < TASK_NUM; index++)
{
if (schedule_task[index].run_sign)
{
// 清除任务标志
schedule_task[index].run_sign = 0;
// 使用函数指针,执行任务,
schedule_task[index].task_func();
}
}
}
void main(void)
{
for (;;)
{
task_process();
}
}
这样就很方便的管理了我们的逻辑。也很好的理清我们的逻辑。不管移植还是需求的改动我们也很方便的去添加。
被抛弃的写随笔公众号改写技术文章了,感兴趣的可以关注公众号:王崇卫