1. 裸机和rtos的多任务处理
试想一种场景,我们正在打游戏,但女朋友在你打游戏的过程中给你发送消息,你需要回复消息
1.1 裸机处理方式
while(1)
{
打游戏();
回复信息();
}
玩过51或者stm32的裸机编程的人都知道,我们往往会在应用程序写一个大循环,如果你一把游戏30min,那么你就得30min后才能执行回复信息的任务,那么你女朋友就会找你麻烦了😆打完游戏才能发送信息,回完信息才能继续打游戏,如下图
1.2 RTOS行为
void main(void)
{
/* 创建打游戏任务 */
xTaskCreate(打游戏)
/* 创建回复信息任务 */
xTaskCreate(回复信息)
}
void 游戏(void)
{
while(1)
{
打游戏();
}
}
void 信息(void)
{
while(1)
{
回复信息();
}
}
而rtos不和裸机相同,它会让打游戏运行一个时间片,回复信息运行一个时间片,一个时间片的时间是可以我们自己设置的,就是滴答定时器的一个节拍,例如我们可以设置1ms来运行,这有点类似于一个伪多线程,在微观来看我们实际是两个任务交替运行,但是宏观上我们却感觉两个任务在同时运行,妥妥的游戏得意,情场得意6️⃣,如下图
2. 裸机和rtos的优先级处理
同样的场景,假设此时小明肚子疼了,要去医院,此时裸机与RTOS又会怎么做呢?
2.1 裸机处理
这时我们可能就知道,这个时候用中断阿,并把它设为一个比较高的优先级,毕竟生命安全第一位,我们可以定义一个中断服务程序,一肚子痛就触发中断去医院,但我们注意,中断是一瞬间的事情,我们不能在中断服务函数做太多的事,比如我们在终端服务函数做一个delay个10ms,程序可能就会出现问题例如:
- 中断处理时间太长或导致正常的应用程序不能按时被执行;
- 执行中断时不能响应其他中断,中断执行时间太长容易丢其他中断;
- 某个中断服务程序执行时间太长,可能导致中断嵌套非常深,容易导致栈溢出,也容易出现逻辑问题。
去医院就是一个长任务,需要坐车挂号看医生,很显然,我们不能把去医院放在中断中
但是呢,玩过单片机的我们都知道,对中断的处理我们一般都是设置一个全局的标志位,我们只需要在中断函数中设置标志位,然后再大循环中去判断这个标志位就可以了,代码如下:
while(1)
{
打游戏();
回复信息();
if(FLAG == 1)
{
去医院();
FLAG = 0;
}
}
但是假如我们此时再打游戏中,打游戏这个任务需要运行30min,即使此时
FLAG
这个标志位已经在中断中被置为1了也无济于事,仍然要等运行完上面两个任务才能进行下面的判断,实时性非常差
2.2 rtos处理
而rtos的处理方式就相当的优雅了,我们可以创建三个任务,并把去医院设为高优先级,让rtos系统自己去进行调度,并且我们注意一种情况,当去医院这个任务在运行没有占有cpu资源时,例如挂号要等待或者去医院的路上,这个时候看病这个任务是没有在进行的,cpu也没有被占用。此时cpu又可以分配给低优先级的任务,例如打游戏回信息,这样我们就很好的使用了cpu的资源
void main(void)
{
/* 创建打游戏任务 */
xTaskCreate(打游戏)
/* 创建回复信息任务 */
xTaskCreate(回复信息)
/* 创建去医院任务 */
xTaskCreate(去医院)
}
void 游戏(void)
{
while(1)
{
打游戏();
}
}
void 信息(void)
{
while(1)
{
回复信息();
}
}
void 去医院(void)
{
while(1)
{
去医院();
}
}
3. 裸机和rtos的区别
3.1 裸机
裸机:裸机又称为前后台系统,前台系统指的中断服务函数,后台系统指的大循环,即应用程序
- 实时性差:(应用程序) 轮流执行
- delay:空等待,CPU不执行其他代码
- 结构臃肿:实现功能都放在无限循环
3.2 rtos
RTOS特点:RTOS全称为:Real Time OS,就是实时操作系统,强调的是:实时性
分而治之:实现功能划分为多个任务
延时函数:任务调度
抢占式:高优先级任务抢占低优先级任务,更高优先级也可以先运行
任务堆栈:每个任务都有自己的栈空间,我们低优先级任务被抢占后,cpu重新回到自己手里,是从之前那个位置继续执行,因此这个栈空间需要有相关的信息,例如:寄存器的值,局部变量…,这和c语言的linux多线程编程有点类似,就是在打断的时候要保存后续的事件,完成中断之后会继续倒回去
值得注意的是,rtos也有中断,我们前面的任务调度其实是软件层面上的说法,而中断的优先级是最高的