裸机程序设计模式

裸机程序的设计模式可以分为:轮询、前后台、定时器驱动、基于状态机。前面三种方法都无法解决一个问题:假设有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 并不容易拆分为多个状态,并且这

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

相关推荐
程序员与背包客_CoderZ1 小时前
高性能分布式KV存储引擎RocksDB入门与C/C++编码实战
c语言·开发语言·数据库·c++·分布式·分布式数据库·rocksdb
william_yangshun1 小时前
【大模型部署实战】kimi-k3-in-c 中文版:用 176KB 纯 C99 引擎在 CPU 上跑 Kimi K3 上手指南
c语言·开发语言
Yyyyyy~3 小时前
【C语言】数据类型和变量【下】
c语言
小雪崩5 小时前
嵌入式学习 day30:minilog
linux·c语言·学习
二级小助手10 小时前
C语言二级操作题高频真题精解与大题代码模板
c语言·计算机二级·二级c语言·c语言操作题·c语言真题·c语言大题
kkkkkkkkkk_Z18 小时前
学嵌入式和C语言编程数据结构|学习日记Day22:栈,二叉树,哈希存储
c语言·数据结构·学习
Navigator_Z18 小时前
LeetCode //C - 1206. Design Skiplist
c语言·算法·leetcode
码行山野赴时序归途18 小时前
三道经典数组题:从暴力到最优的算法思维
c语言·开发语言·数据结构·算法·leetcode
Navigator_Z20 小时前
LeetCode //C - 1209. Remove All Adjacent Duplicates in String II
c语言·算法·leetcode
码行山野赴时序归途1 天前
算法效率的度量(上):时间复杂度中的对数思维
c语言·数据结构·算法