四种裸机程序设计和FreeRTOS的对比
裸机程序设计:
假设我们执行的程序,是一个妈妈,同时在做两个事,一个是A 喂饭,一个是B 发送消息。那实现的方式,有以下4种:
1、轮询模式
在while(1)中执行完A以后执行B,也就是喂一勺饭然后发一条消息,这本身没有任何问题。
但是,假如B需要执行半个小时,也就是喂一口饭,需要发半个小时消息,喂一口饭,再发半个小时消息。你在执行B的时候,A可能就会被饿的哇哇直哭。B的运行就会影响到A的执行效率。
void main()
{
A;//喂饭
B;//发送消息
}
2、前后台
这种情况就是你一直在喂饭,如果收到消息,进入中断,你就回复消息。这种情况就是后台不会影响到前台的运行,但是,如果前台运行时间太长,会影响到后台程序的运行。所以中断要求处理时间尽可能的短。
main //后台
{
while(1)
{
//喂饭
}
}
void 中断 //前台
{
//发消息
}
3、定期器驱动
这种就是定时进入不同的任务,分时运行。跟在while(1)里面是一个道理,就是CPU有空闲的情况。如果某一个任务时间过长,也会影响到另一个任务的运行。
void 定时器中断()
{
static int cnt=0;
cnt++;
if(cnt%2==0)
{
A;//喂饭
}
if(cnt%5==0)
{
B;//发消息
}
}
4、基于状态机
可以在裸机中解决两个函数相互影响的问题,每执行完一个小任务,就跳出当前函数,执行下一个函数。这样每个任务都可以执行一小部分,不会一个任务等待很长的时间。
存在的问题就是,如果把一个函数拆分成若干的模块,简单任务还好,复杂的任务拆分就是个大工程。而且复杂模块不好拆分。
void main()
{
A;//喂饭
B;//发消息
}
void A()//喂饭任务
{
static int state = 0;
Switch (state)
{
case 0:
{
执行A_1;//舀一勺饭
state++;
}break;
case 1:
{
执行A_2;//喂嘴里
state++;
}break;
case 2:
{
执行A_3;//舀一勺菜
state++;
} break;
case 3:
{
执行A_2;//喂嘴里
state=0;
} break;
}
}
void B()//发消息任务
{
//拆分成若干个小任务,每执行完一个,就跳出函数
}
正常轮询模式就如下图所示:
每个任务可以分成5个小段,先执行一个任务,再执行下一个任务。
在执行任务1的时候,任务2等待;执行任务2时,任务1等待。
RTOS执行
-》只有一个脑子,一心多用
-》只是反应快,上一秒在考虑夹哪个菜,下一秒考虑回什么信息
本质:RTOS的本质是交叉执行。其实就是两个任务交叉执行,但是因为间隔时间比较短,所以给人感觉是连续同时在跑两个任务。
程序的设计其实更简单,就如同while(1)里面的执行,我们创建2个任务,并且使用任务调度器。这个任务调度器是由RTOS负责的。我们创建的任务中只需要执行一个任务就可以。设计如下图所示:
void 喂饭任务()
{
while(1)
{
喂一口饭;
}
}
void 回信息任务()
{
while(1)
{
回一个信息;
}
}
void main()
{
//创建两个任务
create_task(喂饭任务);
creak_task(回信息任务);
//启动调度器
start_scheduler();
}
特别感谢韦东山老师提供的视频教程,收益多多。感兴趣的小伙伴可以在哔哩哔哩上搜索韦东山视频 FreeRTOS入门与工程实践。非常适合新手入门。