admin 管理员组文章数量: 1087139
2024年3月13日发(作者:linux系统中文版下载)
裸机系统与多线程系统
在真正开始动学习 RTOS 之前,我们先来讲解下单片机编程中的裸机系统和多线程系
统的区别。
1.裸机系统
裸机系统通常分成轮询系统和前后台系统,有关这两者的具体实现方式请看下面的讲
解。
1.1 轮询系统
轮询系统即是在裸机编程的时候,先初始化好相关的硬件,然后让主程序在一个死循
环里面不断循环,顺序地做各种事情,大概的伪代码具体见代码清单1。轮询系统是一
种非常简单的软件结构,通常只适用于那些只需要顺序执行代码且不需要外部事件来驱
动的就能完成的事情。在代码清单1 中,如果只是实现 LED 翻转,串口输出,液晶显
示等这些操作,那么使用轮询系统将会非常完美。但是,如果加入了按键操作等需要检
测外部信号的事件,用来模拟紧急报警,那么整个系统的实时响应能力就不会那么好了。
假设DoSomething3 是按键扫描,当外部按键被按下,相当于一个警报,这个时候,需
要立马响应,并做紧急处理,而这个时候程序刚好执行到 DoSomething1,要命的是
DoSomething1需要执行的时间比较久,久到按键释放之后都没有执行完毕,那么当执
行到 DoSomething3的时候就会丢失掉一次事件。足见,轮询系统只适合顺序执行的功
能代码,当有外部事件驱动时,实时性就会降低。
代码清单 1 轮询系统伪代码
1 int main(void)
2 {
3 /* 硬件相关初始化 */
4 HardWareInit();
5
6 /* 无限循环 */
7 for (;;) {
8 /* 处理事情 1 */
9 DoSomething1();
10
11 /* 处理事情 2 */
12 DoSomething2();
13
14 /* 处理事情 3 */
15 DoSomething3();
16 }
17 }
1.2 前后台系统
相比轮询系统,前后台系统是在轮询系统的基础上加入了中断。外部事件的响应在中
断里面完成,事件的处理还是回到轮询系统中完成,中断在这里我们称为前台, main 函
数里面的无限循环我们称为后台,大概的伪代码见代码清单2。
代码清单2 前后台系统伪代码
1 int flag1 = 0;
2 int flag2 = 0;
3 int flag3 = 0;
4
5 int main(void)
6 {
7 /* 硬件相关初始化 */
8 HardWareInit();
9
10 /* 无限循环 */
11 for (;;) {
12 if (flag1) {
13 /* 处理事情 1 */
14 DoSomething1();
15 }
16
17 if (flag2) {
18 /* 处理事情 2 */
19 DoSomething2();
20 }
21
22 if (flag3) {
23 /* 处理事情 3 */
24 DoSomething3();
25 }
26 }
27 }
28
29 void ISR1(void)
30 {
31 /* 置位标志位 */
32 flag1 = 1;
33 /* 如果事件处理时间很短,则在中断里面处理
34 如果事件处理时间比较长,在回到前台处理 */
35 DoSomething1();
36 }
37
38 void ISR2(void)
39 {
40 /* 置位标志位 */
41 flag2 = 1;
42
43 /* 如果事件处理时间很短,则在中断里面处理
44 如果事件处理时间比较长,在回到前台处理 */
45 DoSomething2();
46 }
47
48 void ISR3(void)
49 {
50 /* 置位标志位 */
51 flag3 = 1;
52
53 /* 如果事件处理时间很短,则在中断里面处理
54 如果事件处理时间比较长,在回到前台处理 */
55 DoSomething3();
56 }
在顺序执行后台程序的时候,如果有中断来临,那么中断会打断后台程序的正常执行
流,转而去执行中断服务程序,在中断服务程序里面标记事件,如果事件要处理的事情
很简短,则可在中断服务程序里面处理,如果事件要处理的事情比较多,则返回到后台
程序里面处理。虽然事件的响应和处理是分开了,但是事件的处理还是在后台里面顺序
执行的,但相比轮询系统,前后台系统确保了事件不会丢失,再加上中断具有可嵌套的
功能,这可以大大的提高程序的实时响应能力。在大多数的中小型项目中,前后台系统
运用的好,堪称有操作系统的效果。
2 多线程系统
相比前后台系统,多线程系统的事件响应也是在中断中完成的,但是事件的处理是在
线程中完成的。在多线程系统中,线程跟中断一样,也具有优先级,优先级高的线程会
被优先执行。当一个紧急的事件在中断被标记之后,如果事件对应的线程的优先级足够
高,就会立马得到响应。相比前后台系统,多线程系统的实时性又被提高了。多线程系
统大概的伪代码具体见代码清单3。
代码清单3 多线程系统伪代码
1 int flag1 = 0;
2 int flag2 = 0;
3 int flag3 = 0;
4
5 int main(void)
6 {
7 /* 硬件相关初始化 */
8 HardWareInit();
9
10 /* OS 初始化 */
11 RTOSInit();
12
13 /* OS 启动,开始多线程调度,不再返回 */
14 RTOSStart();
15 }
16
17 void ISR1(void)
18 {
19 /* 置位标志位 */
20 flag1 = 1;
21 }
22
23 void ISR2(void)
24 {
25 /* 置位标志位 */
26 flag2 = 2;
27 }
28
29 void ISR3(void)
30 {
31 /* 置位标志位 */
32 flag3 = 1;
33 }
34
35 void DoSomething1(void)
36 {
37 /* 无限循环,不能返回 */
38 for (;;) {
39 /* 线程实体 */
40 if (flag1) {
41
42 }
43 }
44 }
45
46 void DoSomething2(void)
47 {
48 /* 无限循环,不能返回 */
49 for (;;) {
50 /* 线程实体 */
51 if (flag2) {
52
53 }
54 }
55 }
56
57 void DoSomething3(void)
58 {
59 /* 无限循环,不能返回 */
60 for (;;) {
61 /* 线程实体 */
62 if (flag3) {
63
64 }
65 }
66 }
相比前后台系统中后台顺序执行的程序主体,在多线程系统中,根据程序的功能,我
们把这个程序主体分割成一个个独立的,无限循环且不能返回的小程序,这个小程序我
们称之为线程。每个线程都是独立的,互不干扰的,且具备自身的优先级,它由操作系
统调度管理。加入操作系统后,我们在编程的时候不需要精心地去设计程序的执行流,
不用担心每个功能模块之间是否存在干扰。加入了操作系统,我们的编程反而变得简单
了。整个系统随之带来的额外开销就是操作系统占据的那一丁点的 FLASH 和 RAM。
现如今,单片机的 FLASH 和 RAM 是越来越大,完全足以抵挡 RTOS 那点开销。
无论是裸机系统中的轮询系统、前后台系统和多线程系统,我们不能一锤子的敲定孰
优孰劣,它们是不同时代的产物,在各自的领域都还有相当大的应用价值,只有合适才
是最好。
有关这三者的软件模型区别具体见下面表格。
轮询、前后台和多线程系统软件模型区别
模型
轮询系统
前后台系统
多线程系统
事件响应
主程序
中断
中断
事件处理
主程序
主程序
线程
特点
轮询响应事件,轮询处理事件
实时响应事件,轮询处理事件
实时响应事件,实时处理事件
版权声明:本文标题:单片机裸机系统与多线程系统区别 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1710277134a565732.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论