逻辑系统与多任务系统

裸机系统与多任务系统

说在前面(闲话)

大学一开始迷茫的我在大一下学期既然接触到单片机这么好且玩神奇的东西,好多人在初中(高中)的时候都已经接触了。为什么我大学才能接触(哭辽)。。。。。原因可能是高中了解的接触的太少了。最开始上手51单片机点亮一个小灯泡就贼有成就感,四五行的代码看的满心欢喜,觉得嵌入式应该不难并决定以后要超这个方向发展。(什么狗屁通信工程——老子喜欢嵌入式)
直到我学习了中断学习了PWM我才知道原来和我想的不太一样啊!给的例程可以跑得通,我自己写的就是没啥效果(内心骂自己100遍——为什么我这么菜)实现一个功能代码我调了近一天。不过黄天不负有心人我最终还是达到了效果。学习51单片机让我对IO口有了基本的认识。
大一暑假接触了STM32,学长学姐建议先学习使用寄存器版的。我内心想着应该和51差不多,上去直接看代码。看了以后只想说(卧槽卧槽卧槽)这都是啥???然后慢慢地看正点原子给的资料和例程有了一定的认识。了解了GPIO时钟等概念,后来学习了定时器、中断、输入捕获对寄存器有了一定的认识。通过寻迹小车基于STM32的三路超声波避障小车对学到的东西巩固了一些,进一步加深理解和认识。(文章都是寄存器版本的呦,网上有的源码很少,支持一哈博主呗!!!)后来学习了LCD、TFLCD等就看文章、看代码、下载验证感觉没有学到啥(作用不大)。后来通过STM32实现一个五子棋小游戏加深了对触摸屏的理解,同时对C语言巩固了不少。然后不知不觉一年就过去了,要期末考试了。成绩出来我既然没有挂科!!!(感谢信号老师让我61分飘过,今年不挂、来年必定好好学习)
学期末没有怎么学,看了一点UCOS相关的知识。了解了一些API函数、消息队列、信号量等内容但是没有深究。刚好放假了可以深入学习一哈,动手写一个实时操作系统。再看看数据结构与算法相关的内容。希望2020会有好运,能有更大的收获。
立个flag——每个月发表博客平均在3篇以上!!

裸机系统

裸机系统通常分成轮询系统和前后台系统,

轮询系统

轮询系统即是在裸机编程的时候, 先初始化好相关的硬件设备,然后让主程序在一个死循环里面不断循环, 顺序地做各种事情,大概的伪代码具体见代码清单 4-1。通常只适用于那些只需要顺序执行代码且不需要外部事件来驱动的就能完成的事情。在代码清单 4-1 中,如果只是实现 LED 翻转,串口输出,液晶显示等这些操作,那么使用轮询系统将会非常完美。但是,如果加入了按键操作等需要检测外部信号的事件,用来模拟紧急报警,那么整个系统的实时响应能力就不会那么好了。假设DoSomething3 是按键扫描,当外部按键被按下,相当于一个警报,这个时候,需要立马响应,并做紧急处理,而这个时候程序刚好执行到 DoSomething1,要命的是DoSomething1需要执行的时间比较久,久到按键释放之后都没有执行完毕,那么当执行到 DoSomething3的时候就会丢失掉一次事件。可见,轮询系统只适合顺序执行的功能代码,当有外部事件驱动时,实时性就会降低。
在这里插入图片描述

前后台系统

相比轮询系统,前后台系统是在轮询系统的基础上加入了中断。外部事件的响应在中断里面完成, 事件的处理还是回到轮询系统中完成,中断在这里我们称为后台, main 函数里面的无限循环我们称为后台,大概的伪代码见代码如下:

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 DoSomethin1();
15 }1617 if (flag2) {
18 /* 处理事情 2 */
19 DoSomething2();
20 }2122 if (flag3) {
23 /* 处理事情 3 */
24 DoSomething3();
25 }
26 }
27 }
28
29 void ISR1(void)
30 {
31 /* 置位标志位 */
32 flag1 = 1;
33 /* 如果事件处理时间很短,则在中断里面处理
34 如果事件处理时间比较长,在回到前台处理 */
35 DoSomethin1();
36 }
37
38 void ISR1(void)
39 {
40 /* 置位标志位 */
41 flag1 = 2;
42
43 /* 如果事件处理时间很短,则在中断里面处理
44 如果事件处理时间比较长,在回到前台处理 */
45 DoSomethin2();
46 }
47
48 void ISR3(void)
49 {
50 /* 置位标志位 */
51 flag3 = 1;
52
53 /* 如果事件处理时间很短,则在中断里面处理
54 如果事件处理时间比较长,在回到前台处理 */
55 DoSomethin3();
56 } 

在顺序执行后台程序的时候,如果有中断来临,那么中断会打断后台程序的正常执行流,转而去执行中断服务程序,在中断服务程序里面标记事件,如果事件要处理的事情很简短,则可在中断服务程序里面处理,如果事件要处理的事情比较多,则返回到后台程序里面处理。虽然事件的响应和处理是分开了,但是事件的处理还是在后台里面顺序执行的,但相比轮询系统,前后台系统确保了事件不会丢失,再加上中断具有可嵌套的功能,这可以大大的提高程序的实时响应能力。 在大多数的中小型项目中,前后台系统运用的好,堪称有操作系统的效果

多任务系统

相比前后台系统,多任务系统的事件响应也是在中断中完成的,但是事件的处理是在任务中完成的。在多任务系统中,任务跟中断一样,也具有优先级,优先级高的任务会被优先执行。当一个紧急的事件在中断被标记之后,如果事件对应的任务的优先级足够高,就会立马得到响应。相比前后台系统,多任务系统的实时性又被提高了。 多任务系统大概的伪代码具体见代码如下。

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 ISR1(void)
24 {
25 /* 置位标志位 */
26 flag1 = 2;
27 }
28
29 void ISR3(void)
30 {
31 /* 置位标志位 */
32 flag3 = 1;
33 }
34
35 void DoSomethin1(void)
36 {
37 /* 无限循环,不能返回 */
38 for (;;) {
39 /* 任务实体 */
40 if (flag1) {
41
42 }
43 }
44 }
45
46 void DoSomethin2(void)
47 {
48 /* 无限循环,不能返回 */
49 for (;;) {
50 /* 任务实体 */
51 if (flag2) {
52
53 }
54 }
55 }
56
57 void DoSomethin3(void)
58 {
59 /* 无限循环,不能返回 */
60 for (;;) {
61 /* 任务实体 */
62 if (flag3) {
63
64 }
65 }
66 } 

相比前后台系统中后台顺序执行的程序主体,在多任务系统中,根据程序的功能,我们把这个程序主体分割成一个个独立的,无限循环且不能返回的小程序,这个小程序我们称之为任务。 每个任务都是独立的,互不干扰的,且具备自身的优先级,它由操作系统调度管理。 加入操作系统后, 我们在编程的时候不需要精心地去设计程序的执行流,不用担心每个功能模块之间是否存在干扰。加入了操作系统,我们的编程反而变得简单了。 现如今,单片机的 FLASH 和 RAM 是越来越大,完全足以抵挡 RTOS 那点开销。无论是裸机系统中的轮询系统、 前后台系统和多任务系统,我们不能一锤子的敲定孰优孰劣,它们是不同时代的产物,在各自的领域都还有相当大的应用价值,只有合适才是最好。有关这三者的软件模型区别具体见表格 4-1。
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章