裸机条件下写一个基于时间片轮转的多任务并发程序

文章介绍了如何在不使用RTOS的情况下,利用STM32的硬件定时器实现裸机多任务并发,通过时间片轮转确保各个任务按预设时间间隔交替执行,以实现类似操作系统的效果。作者提供了任务结构体定义、任务数组初始化、定时器中断配置以及主循环中的任务切换逻辑。

前言

在学习各种MCU的时候,都是用在main函数里写一个while(1){/* 执行代码 */},这种方式只能一个函数运行完以后再运行另一个函数。
假设需求控制多个模块,如显示屏幕信息的同时控制电机,还要一边接收按键输入。如果用上面的方式每个模块要排队等待CPU运行,就会显的很卡。
那有没有办法每个模块运行固定的时间,时间到了运行下一个模块,这样单个模块即使特别耗时,也不影响其他模块的运行,这个方法叫时间片轮转。
想到这个办法很容易,但要怎么编写代码呢?

A. 使用RTOS

根据不要重复造轮子的理论,能用现有的开源代码当然是最好的了。如类STM32常用的操作系统有uCOS, RT-thread(国产),FreeRTOS。
用现成的去官网等地方搜移植教程,本文不再详述。
用这些开源代码的问题是如果MCU RAM或ROM太小,删减起来就不太方便了,这时候手搓一个多任务并发系统的作用来了。

B.裸机多任务并发

时间片轮转的基本思路就是通过定时器(最好是硬件定时器)将CPU的运行时间切片成一个个时间片,代码里叫tick,然后一个任务每运行一个时间片,tick计数加1,当前任务运行的tick数已经达到分配给任务的tick数,就不再执行当前任务执行下一个任务。

先定义一个最任务结构体,至少包括任务主体函数,分配给任务的时间片tick数和当前运行已经消耗的时间片tick计数。用结构体就是为了方便扩展用的,还可以增加参数比如任务使能,任务偏移量等。这样就使任务执行更加灵活。

typedef void (*Func)(void);
typedef struct task_info_t
{
   
   
    Func func;                /* 任务主体函数 */
    uint16_t task_tick;        /* 分配给任务的时间片tick数 */
    uint16_t tast_tick_cnt;    /* 当前运行已经消耗的时间片tick计数 */
} TaskInfo_t;

初学者 typedef void (*Func)(void); 看不懂,这个是定义一种函数类型,这种函数类型是void (*)(void)型的,给他取个别名叫Func. 相当于下面这种写法:
不清楚的看这篇文章typedef void *(Func)(void)用法

typedef struct task_info_t
{
   
   
    void (*func)(void);                /* 任务主体函数 */
    uint16_t task_tick;        /* 分配给任务的时间片tick数 */
    uint16_t tast_tick_cnt;    /* 当前运行已经消耗的时间片tick计数 */
} TaskInfo_t;

定义好结构体后创建一个结构体数组,在数组里初始化任务的参数,结构体数组不清楚的看这里结构体数组

TaskInfo_t TaskInfoArray[] =
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值