裸机程序设计模式

裸机程序的设计模式可以分为:轮询、前后台、定时器驱动、基于状态机。前面三种方法都无法解决一个问题:假设有A、B两个都很耗时的函数,无法降低他们互相之间的影响。第4中方法可以解决这个问题,但是实践起来有难度。

1、轮询模式

cpp 复制代码
// 经典单片机程序: 轮询
02 void main()
03 {
04 while (1)
05 {
06 喂一口饭();
07 回一个信息();
08 }
09 }

while循环里有两个函数,这两个函数之间有影响,一个函数运行时间较长,另一个函数就迟迟无法运行。

2、前后台

所谓前后台,就是指使用中断程序。

cpp 复制代码
// 前后台程序
02 void main()
03 {
04 while (1)
05 {
06 // 后台程序
07 喂一口饭();
08 }
09 }
10
11 // 前台程序
12 void 滴_中断()
13 {
14 回一个信息();
15 }

while循环里面的是后台程序,中断里是前台程序,中断程序的执行是非常及时的,但是如果中断函数执行很长,就会造成后台程序运行不及时。

cpp 复制代码
// 前后台程序
02 void main()
03 {
04 while (1)
05 {
06 // 后台程序
07 }
08 }
09
10 // 前台程序
11 void 滴_中断()
12 {
13 回一个信息();
14 }
15
16 // 前台程序
17 void 啊_中断()
18 {
19 喂一口饭();
20 }

改进后,将两个程序都写成前台程序(中断程序),但是如果两个程序同时需要执行,那么就会受影响。

3、定时器驱动

定时器驱动模式,是前后台模式的一种,可以按照不用的频率执行各种函数。比如需要

每 2 分钟给小孩喂一口饭,需要每 5 分钟给同事回复信息。那么就可以启动一个定时器,让

它每 1 分钟产生一次中断,让中断函数在合适的时间调用对应函数。示例代码如下:

cpp 复制代码
// 前后台程序: 定时器驱动
02 void main()
03 {
04     while (1)
05     {
06     // 后台程序
07     }
08 }
09
10 // 前台程序: 每 1 分钟触发一次中断
11 void 定时器_中断()
12 {
13     static int cnt = 0;
14     cnt++;
15     if (cnt % 2 == 0)
16     {
17     喂一口饭();
18     }
19     else if (cnt % 5 == 0)
20     {
21     回一个信息();
22     }
23 }

每发生2次中断,就执行一次喂饭程序,每发生5次中断,就执行一次回一个信息。这种模式适合调用周期性的函数,并且每一个函数执行的时间不能超过一个定时器周期。如果函数执行时间超过定时器周期,那么函数之间就会受影响。

4、基于状态机

当"喂一口饭"、"回一个信息"都需要花很长的时间,无论使用前面的哪种设计模式,

都会退化到轮询模式的缺点:函数相互之间有影响。可以使用状态机来解决这个缺点,示例

代码如下:

cpp 复制代码
// 状态机
02 void main()
03 {
04     while (1)
05     {
06     喂一口饭();
07     回一个信息();
08     }
09 }

01 void 喂一口饭(void)
02 {
03     static int state = 0;
04     switch (state)
05     {
06     case 0:
07     {
08     /* 舀饭 */
09     /* 进入下一个状态 */
10     state++;
11     break;
12     }
13     case 1:
14     {
15     /* 喂饭 */
16     /* 进入下一个状态 */
17     state++;
18     break;
19     }
20     case 2:
21     {
22     /* 舀菜 */
23     /* 进入下一个状态 */
24     state++;
25     break;
26     }
27     case 3:
28     {
29     /* 喂菜 */
30     /* 恢复到初始状态 */
31     state = 0;
32     break;
33     }
34     }
35   }
36
37 void 回一个信息(void)
38 {
39     static int state = 0;
40
41     switch (state)
42     {
43         case 0:
44         {
45         /* 查看信息 */
46         /* 进入下一个状态 */
47         state++;
48         break;
49         }
50         case 1:
51         {
52         /* 打字 */
53         /* 进入下一个状态 */
54         state++;
55         break;
56         }
57         case 2:
58         {
59         /* 发送 */
60         /* 恢复到初始状态 */
61         state = 0;
62         break;
63         }
64     }
65 }

使用状态机模式,可以解决裸机程序的难题:假设有 A、 B 两个都很耗时的函数,怎样

降低它们相互之间的影响。但是很多场景里,函数 A、 B 并不容易拆分为多个状态,并且这

些状态执行的时间并不好控制。所以这并不是最优的解决方法,需要使用多任务系统。

相关推荐
源远流长jerry5 小时前
OpenHarmony概述与使用
c语言·c++·鸿蒙系统
艾莉丝努力练剑5 小时前
深入详解C语言的循环结构:while循环、do-while循环、for循环,结合实例,讲透C语言的循环结构
c语言·开发语言·c++·学习
晨非辰6 小时前
#C语言——学习攻略:自定义类型路线--结构体--结构体类型,结构体变量的创建和初始化,结构体内存对齐,结构体传参,结构体实现位段
c语言·开发语言·经验分享·学习·其他·学习方法·visual studio
·白小白7 小时前
【数据结构】——栈(Stack)的原理与实现
c语言·开发语言·数据结构
KFCgrandpahhh8 小时前
从0开始跟小甲鱼C语言视频使用linux一步步学习C语言(持续更新)8.13
linux·c语言·学习
Rain_is_bad9 小时前
初识c语言————排序方法
c语言·开发语言·数据结构
一支闲人10 小时前
C语言相关简单数据结构:顺序表
c语言·数据结构·基础知识·适用新手小白
John.Lewis14 小时前
数据结构初阶(11)排序的概念与运用
c语言·数据结构·排序算法
daiyanyun15 小时前
Ubuntu 20.04 虚拟机安装完整教程:从 VMware 到 VMware Tools
linux·c语言·c++·ubuntu
Gu_shiwww17 小时前
数据结构3线性表——单链表(C)
c语言·开发语言·数据结构