[MM32生态] 一些嵌入式软件设计经验

[复制链接]
2063|17
 楼主| 药无尘 发表于 2022-8-22 16:45 | 显示全部楼层 |阅读模式
1、什么是框架?

程序框架其实就类似一个文件大纲或者模板。因为写程序就和类似于写文章,如果没有大纲或者模板那么你写起来就会比较费劲。


 楼主| 药无尘 发表于 2022-8-22 16:46 | 显示全部楼层
2、为什么要有框架?
节约时间,减少错误。因为对于一种类型的程序它们代码结构体逻辑是一样的,同时有大量相似或者共同的地方。我们可以将这些共同的地方抽出来形成一个固定的程序框架,那么我们再开发新的同一种类型的程序时就可以套用这套框架。

这样会大大提高我们的开发效率,同时由于这个框架是一套公众的大家都在使用的与维护的,使用它会使代码逻辑更不容易出错。
 楼主| 药无尘 发表于 2022-8-22 16:47 | 显示全部楼层
3、嵌入式系统组成
嵌入式控制系统基本都是由普通任务和中断任务组成。

普通任务:指对时间响应要求不高或者说是那种周期性执行的任务;
中断任务:指对时间响应要求高,必须立刻处理的任务;
 楼主| 药无尘 发表于 2022-8-22 16:48 | 显示全部楼层
4、常见的框架
4.1、轮询无中断

说明:所有的任务都是按照顺序执行,为了减少整个系统的响应时间有两种方法:

任务中不要使用等待式的延时函数;
任务无法一次执行完的情况下应该将任务分解成若干个小任务每次执行一个小任务循环直到任务完成;
上述两种方法都会消耗内存,本来局部变量可以解决的事,现在只能用静态或者全局变量来处理。
优点:程序执行流程简单清晰;

缺点:对于系统修改功能非常不方便,同时如果任务数量增加的话会影响整个系统的响应时间,就会显得系统卡顿;

伪代码实现:
  1. int main(void)
  2. {
  3.     while(1)
  4.     {
  5.         doSomething_1(); //任务1
  6.         doSomething_2(); //任务2
  7.         doSomething_3(); //任务3
  8.         /*其他各种任务*/
  9.     }
  10.     return 0;
  11. } 52189630342bbb1f3d.png
 楼主| 药无尘 发表于 2022-8-22 16:49 | 显示全部楼层
4.2、只有中断
说明:在“只有中断“的系统中,主函数main的循环中是不做任何操作的。

优点:可以实时响应异常的任务(事件)

缺点:中断资源有限,当任务过多时会响应不及时。

伪代码实现:
  1. int main(void)
  2. {
  3.     while(1)
  4.     {
  5.         ;
  6.     }
  7. }

  8. /*中断服务函数1*/
  9. void ISR1_IRQHandler(void)
  10. {
  11.     doSomething_1();
  12. }

  13. /*中断服务函数2*/
  14. void ISR2_IRQHandler(void)
  15. {
  16.     doSomething_2();
  17. }
 楼主| 药无尘 发表于 2022-8-22 16:50 | 显示全部楼层
4.3、只有中断框架的变种
说明:采用状态机的机制来执行任务。中断函数中设置状态机的状态,而main函数主循环中根据不同的状态值执行不同的任务。这个其实不属于真正只有中断的形式。
  1. int main(void)
  2. {
  3.     while(1)
  4.     {
  5.         if(flag_1)
  6.         {
  7.             doSomething_1();
  8.         }
  9.         if(flag_2)
  10.         {
  11.             doSomething_2();
  12.         }
  13.         if(flag_3)
  14.         {
  15.             doSomething_3();
  16.         }
  17.         /*其他各种任务*/
  18.     }
  19.     return 0;
  20. }

  21. /*********中断服务函数1************/
  22. void ISR1_IRQHandler(void)
  23. {
  24.     flag_1 = ~flag_1;
  25. }

  26. /*********中断服务函数2************/
  27. void ISR2_IRQHandler(void)
  28. {
  29.     flag_2 = ~flag_2;
  30. }

  31. /*********中断服务函数3************/
  32. void ISR3_IRQHandler(void)
  33. {
  34.     flag_3 = ~flag_3;
  35. }
 楼主| 药无尘 发表于 2022-8-22 16:52 | 显示全部楼层
4.4、轮询有中断
说明:将一些周期性的任务放置在main函数中的主循环中执行:
74799630343724c342.png
优点:合理的利用资源,将常规任务与紧急任务分开来了。

缺点:程序结构与逻辑比较复杂,在任务分配以及协作之间需要花费很大精力。

伪代码实现:
  1. int main(void)
  2. {
  3.     while(1)
  4.     {
  5.         if(flag_1)
  6.         {
  7.             doSomething_1();
  8.         }
  9.         if(flag_2)
  10.         {
  11.             doSomething_2();
  12.         }
  13.         if(flag_3)
  14.         {
  15.             doSomething_3();
  16.         }
  17.         /*其他各种任务*/
  18.     }
  19.     return 0;
  20. }

  21. /*********定时器中断服务函数************/
  22. void ISR1_IRQHandler(void)
  23. {
  24.    
  25. }

 楼主| 药无尘 发表于 2022-8-22 16:53 | 显示全部楼层
4.5、轮询有中断——虚拟定时器
82306630343c559701.png
说明:利用不同的”虚拟定时器“的定时时间来调用不同任务,当定时器的定时时间到时则执行回调函数或者调用任务函数。

这对于一些周期性运行的任务是非常适合的,同时中断可以应对外界的突发事件。这样实时性也可以得到保障,但要注意不要使用等待式延时。一般虚拟定时器的时基为1ms。

优点:任务的时间间隔可以相对精确的控制,同时由于中断使用整个系统的实时性也很不错。

缺点:任务的执行时间无法掌控,当定时任务执行时间过长时会影响到虚拟定时器的定时精度。

虚拟定时器实现代码:

https://codeload.github.com/0x1abin/MultiTimer/zip/master
 楼主| 药无尘 发表于 2022-8-22 16:54 | 显示全部楼层
4.6、非抢占式实时操作系统

4713863034402870ab.png
说明:任务之间没有优先级之分,每个任务都是依次执行。但是任务的执行时间是由操作系统严格控制的。即使任务没有执行完,当时间片时间达到时任务便会被挂起。

优点:不用再处心积虑的减少任务中的延时,我们只需要将精力放置在业务逻辑上。

缺点:任务之间是平级的,这就会导致有些任务无法得到紧急处理。

伪代码实现:

https://blog.csdn.net/twx11213030422/article/details/104637273
 楼主| 药无尘 发表于 2022-8-22 16:55 | 显示全部楼层
4.7、抢占式实时操作系统
说明:每个任务之间是一个“死循环”同时任务都有一个优先级。高优先级的任务可以打断低优先级的任务,这个就类似于中断一样。所以整个系统的实时性就非常好,同时每个任务都还受时间片的控制也就是说它们的执行时间是可以预测的。它也支持中断可以响应紧急的事件。
474236303444d0985a.png
优点:实时响应,工程师只需要将精力放置在业务逻辑的实现上

缺点:需要移植且对单片机硬件资源有一定要求;使用比较复杂。

常用的抢占式实时操作系统:Keil RTX、FreeRTOS、uCosII/III等等。
 楼主| 药无尘 发表于 2022-8-22 16:56 | 显示全部楼层
4.8、回调函数
什么是回调函数?

答:函数指针作为函数的形参,然后函数的调用通过此函数指针来实现。

回调函数中注册与回调是什么?

答:注册其实就是使用一个全局的函数指针,然后给此函数指针赋值(将我们自定义的函数名称赋值给它)。然后在中断或者其他地方通过此全局的函数指针来调用我们原先自定义的函数且这个自定义的函数我们也叫回调函数。
37289630344aba5624.png
tpgf 发表于 2022-9-4 16:40 | 显示全部楼层
一个好的框架能节省很多后期的工作
qcliu 发表于 2022-9-4 19:43 | 显示全部楼层
这里的软件是说的单片机里边的程序是吗
drer 发表于 2022-9-4 20:12 | 显示全部楼层
嵌入式是必须要跑系统的吗
coshi 发表于 2022-9-4 20:35 | 显示全部楼层
实时响应的不错啊
kxsi 发表于 2022-9-4 20:41 | 显示全部楼层
目前我们常用的嵌入式软件都有哪些啊
wiba 发表于 2022-9-4 20:53 | 显示全部楼层
有时候自己不摸索 引脚就不深刻
您需要登录后才可以回帖 登录 | 注册

本版积分规则

79

主题

623

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部