一、裸机系统
1、轮询系统
定义: 轮询系统即最开始学习单片机的时候用的main函数大循环
执行机制 顺序执行代码,无限循环。
伪代码如下:
int main(void)
{
HardWareInit(); /* 硬件相关初始化 */
/* 无限循环 */
while(1)
{
DoSomething1(); /* 处理事情 1 */
DoSomething2();/* 处理事情 2 */
DoSomething3();/* 处理事情 3 */
}
}
适用性
轮询系统只适合顺序执行的功能代码,当有外部事件驱动时,实时性就会降低。
具体如下:
如果只是实现 LED 翻转,串口输出,液晶显示等这些操作,那么使用轮询系统将会非常完美。
但是,如果加入了按键操作等需要检测外部信号的事件,用来模拟紧急报警,那么整个系统的实时响应能力就不会那么好了。假设DoSomething3 是按键扫描,当外部按键被按下,相当于一个警报,这个时候,需要立马响应,并做紧急处理,而这个时候程序刚好执行到 DoSomething1,要命的是 DoSomethingg1
需要执行的时间比较久,久到按键释放之后都没有执行完毕,那么当执行到 DoSomething3的时候就会丢失掉一次事件。
2、前后台系统
定义: 相比轮询系统,前后台系统是在轮询系统的基础上加入了中断。
执行机制:
顺序执行while循环中代码,遇到中断就去执行中断服务函数,执行完再回到while循环接着执行。
这里面涉及的两个概念:
外部事件的响应在中断里面完成,事件的处理还是回到轮询系统中完成。中断在这里我们称为前台,main函数里面的无限循环我们称为后台。
伪代码如下:
int flag1 = 0;
int flag2 = 0;
int flag3 = 0;
int main(void)
{
HardWareInit(); /* 硬件相关初始化 */
/* 无限循环 */
while(1)
{
if (flag1) {
DoSomething1();/* 处理事情 1 */
}
if (flag2) {
DoSomething2();/* 处理事情 2 */
}
if (flag3) {
DoSomething3();/* 处理事情 3 */
}
}
}
void ISR1(void)
{
flag1 = 1; /* 置位标志位 */
/* 如果事件处理时间很短,则在中断里面处理
如果事件处理时间比较长,在回到前台处理 */
DoSomething1();
}
void ISR2(void)
{
flag2 = 1; /* 置位标志位 */
/* 如果事件处理时间很短,则在中断里面处理
如果事件处理时间比较长,在回到前台处理 */
DoSomething2();
}
void ISR3(void)
{
flag3 = 1; /* 置位标志位 */
/* 如果事件处理时间很短,则在中断里面处理
如果事件处理时间比较长,在回到前台处理 */
DoSomething3();
}
可以看到while循环和中断服务函数中都有 DoSomething1(),具体在哪儿执行根据DoSomething1复杂程度来选择,复杂在while中执行,简单在服务函数中执行,这是为了保证程序的响应能力。
二、多任务系统
定义: 多任务系统相比裸机系统就是加入了RTOS,用操作系统来调度管理任务,它可以让 MCU “同时”执行多个函数。
注意:事实上,这只是效果上看是多个函数在执行,由于单核的 MCU 每次只能处理一条指令,所以只是通过不断的切换 MCU执行的任务(每个任务都执行一小段时间),由于MCU速度很快,运行效果就是多个任务在同时执行。
执行机制: 启动RTOS后,当有外部事件产生时,便触发中断,执行中断服务函数置位标志位,RTOS会根据任务优先级执行相应任务。
int flag1 = 0;
int flag2 = 0;
int flag3 = 0;
int main(void)
{
HardWareInit(); /* 硬件相关初始化 */
RTOSInit();/* OS 初始化 */
RTOSStart();/* OS 启动,开始多任务调度,不再返回 */
}
void ISR1(void)
{
flag1 = 1;/* 置位标志位 */
}
void ISR2(void)
{
flag2 = 2;/* 置位标志位 */
}
void ISR3(void)
{
flag3 = 1; /* 置位标志位 */
}
void DoSomething1(void)
{
while(1) /* 无限循环,不能返回 */
{
if (flag1) /* 任务实体 */
{
}
}
}
void DoSomething2(void)
{
while(1) /* 无限循环,不能返回 */
{
if (flag2) /* 任务实体 */
{
}
}
}
void DoSomething3(void)
{
while(1) /* 无限循环,不能返回 */
{
if (flag3) /* 任务实体 */
{
}
}
}
什么是任务?
相比前后台系统中后台顺序执行的程序主体,在多任务系统中,根据程序的功能,我们把这个程序主体分割成一个个独立的,无限循环且不能返回的小程序,这个小程序我们称之为任务。
注意:
(1)每个任务都是独立的,互不干扰的,且跟中断一样,也具有优先级
(2)多任务系统的事件响应也是在中断中完成的,但是事件的处理是在任务中完成的。
(3)相比前后台系统,多任务系统的实时性又被提高了。
关于多任务系统执行机制后面还会补充。
三、三种系统对比
注意:前后台系统如果事件简单的话可以在中断中处理,事件复杂则在主程序中处理。