嵌入式开发的程序架构

news2025/1/12 18:42:33

前言

在嵌入式软件开发,包括单片机开发中,软件架构对于开发人员是一个必须认真考虑的问题。
软件架构对于系统整体的稳定性和可靠性是非常重要的,一个合适的软件架构不仅结构清晰,并且便于开发。
我相信在嵌入式或单片机软件开发的初期大多数开发者采用的都是简单的前后台顺序执行架构(我就是这样的)。在嵌入式软件开发中,程序架构主要分为三种,本篇文章将对这三种程序架构做出详解。

软件架构存在的意义

可以说一个好的程序架构,是一个有经验的工程师和一个初学者的分水岭。软件架构对于开发人员是友好的,你希望先执行什么任务后执行什么任务,或者这一个时间点执行什么任务下一个执行什么任务,又或者什么事件会同步到某个任务等等,在不同的软件架构下,解决上述问题的具体方法都是有所区别的。
软件架构对开发者最大的帮助是:帮助开发者掌控整个工程的框架,当你熟练使用其中某一个程序架构后,对于系统中出现的bug你一定能够快速的定位并解决。当然,我建议要根据需要选择合适的软件架构进行开发。

深入介绍三种不同的程序架构

三种常用的软件架构有:顺序执行的前后台系统、时间片轮询系统和多任务操作系统。为了让大家有一个更为清晰的认识,我分别用三种软件架构对一个实例进行介绍说明。这个实例如下:它有4个任务,这4个任务为按键扫描、声光报警、显示屏刷新和超声波测距。这个实例的具体功能是通过按键设置测量距离的阈值,当测距距离低于设置的阈值时,触发声光报警并且将测量距离实时显示在显示屏上(这个应用是汽车倒车雷达的具体体现)。

1、顺序执行的前后台系统
在顺序执行的前后台系统中,我会把键盘扫描用查询的方式放在while(1)中,而显示屏刷新和超声波测距使用中断,在中断服务函数中获取测量距离后进行显示,在主函数的循环中进行按键的检测,声光处理也放在主循环中。这样整个程序就以变量标志的同步方式在主循环和后台中断中执行,对应的程序代码如图所示:
在这里插入图片描述
上面代码是顺序执行前后台系统的主函数。
在这里插入图片描述
如上代码,顺序执行前后台系统的中断服务函数。
这种架构的优点是使用简单易于理解,而缺点是每个任务所占的CPU时间过长的话,会导致程序的实时性能差,就比如按键的检测等。

2、时间片轮询系统和多任务操作系统

时间片轮询法实际上通常出现在操作系统中,也就是说他属于操作系统,但在这里所说的是基于前后台系统的时间片轮询。时间片轮询法的实质其实就是选出一个定时器,每进一次定时中断对计数值进行自加,在主循环中根据这个计数值执行任务,这个计数值也就是任务轮询的时间片。
在这个实例中,如果采用时间片轮询系统的话,首先选用主控芯片的任一定时器,定时器定时时间周期由我们决定,为了保证实时性和运行效率,这个值通常取10ms、30ms、50ms等,我会将按键扫描轮值值设置为20ms,因为按键抖动的时长一般为20ms,这样处理既达到了消抖的目的,又不会漏掉按键的检测。而显示屏的刷新设置为30ms,如果你觉得刷新反应慢了也可以修改这一轮询值得到改善;而超声波测距的轮询值设置为100ms,即每隔100ms模式触发测距一次,这个测距频率已经能够满足大多数的情况了。
程序代码如下:
在这里插入图片描述
如上代码,时间片轮询系统的主函数。
在这里插入图片描述
如上代码,时间片轮询系统的定时器中断函数。
可以看出时间片轮询法相比顺序执行还是有很大优势的,既有顺序执行法的优点,也有操作系统的部分优点。

3、多任务操作系统

操作系统的本身是一个比较复杂的东西,任务的管理和调度实现的底层是很复杂和困难的。但是,我们一般都是把操作系统本身作为一个工具一个平台,我们的目的是使用它的功能而不是开发一个操作系统。有了操作系统,不管是对于程序的稳定性和开发的效率都会好很多。我们在使用操作系统的时候更多的需要去学习和理解它的一些调度和通信的方式。实际上真正能使用操作系统的人并不多,反而是跑裸机的占大多数,这也和产品的具体要求有关,很多简单的系统只需要裸机即可满足。
在这里本我不过多的介绍操作系统本身,因为操作系统确实挺复杂的,下面图例中的代码是在freertos中创建按键控制LED亮灭的程序结构,大家可以对比一下:
在这里插入图片描述如上,freertos多任务系统中主函数。
在这里插入图片描述
如上,freertos多任务操作系统中的任务回调函数。

我认为没有最好的软件架构(程序架构),而是只有最合适的。因为在不同的应用场景中适合采用不同的程序设计,而单纯的去比较哪种程序架构是最好的没有什么实际的意义。

那接下来我们来对具体的应用场景进行分析:

  • 在一些逻辑清晰功能单一的系统中就很适合选择顺序执行的前后台架构,这个软件架构往往能够满足我们大部分的需求,比如电饭煲、电磁炉和声控灯泡等;
  • 在一些资源缺乏的单片机并且对系统可靠性要求较高的情况下非常适合,因为这种方法的系统耗费比较小,只是牺牲了一个定时器而已,但是选择此种程序架构需要我们对时间片进行深思熟虑的划分;
  • 最后,在一些功能复杂,逻辑控制较为困难的系统中就适合选择多任务操作系统,比如视频监控系统、无人机等等应用场景。
  • 要想成为嵌入式软件工程师,掌握这三种软件架构是非常有必要的,它们可以让我们在设计程序时拥有更多的选择和思考,而每一种不同的程序架构都具备它自己的优势与不足,这需要我们去用心实践方可体会到它的奥妙。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/156628.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

聚焦云原生安全|安全狗亮相云原生产业联盟年会

1月9日,云原生产业联盟年会成功举办。 作为国内云原生安全领导厂商,安全狗也受邀参与此次大会。 安全狗高级副总裁陈荣有发表寄语 在此次线上会议中,安全狗凭借突出的云原生安全整体实力,通过层层筛选与审核,入选成为…

OpenCV从3D-2D 点对应中查找对象姿势solvePnP

1.概述:在使用相机拍照片时,大多数人会考虑拍的好不好看,关注相机中物体坐标的并不多,但是对于地信学科来说,如果能从照片中获取物体的真实位置,对地理信息获取大有帮助,在这里面,十…

深入分析Linux PCI驱动框架(三)

说明: Kernel版本:4.14ARM64处理器使用工具:Source Insight 3.5, Visio 1. 概述 先回顾一下PCIe的架构图: 本文将讲PCIe Host的驱动,对应为Root Complex部分,相当于PCI的Host Bridge部分&…

Vue 总结四 (ref, mixin, 插件, 插槽, VueX)

目录 ref 混入 mixin 插件 插槽 使用插槽的情景 使用方法 VueX 使用场景 使用 state 存放共享数据 actions 操作共享数据的API mutations 操作共享数据的API 生命周期图 ref 和id的区别 对于传统标签来说没有区别 都拿到的是 html内容 对于自定义的vue 的标签…

Spring事务源码分析

1. 前言 Spring支持两种事务管理的方式:声明式事务和编程式事务。编程式事务的优点是可以在代码里控制事务的粒度,实现细粒度的事务控制,缺点是对业务代码存在侵入性,代码复杂度较高,一般很少使用。声明式事务的优点是…

Linux下的动静态库

目录 认识动静态库 如何制作动静态库? 静态库 动态库 使用库 使用静态库 使用动态库 为什么动态链接是如此呢? 认识动静态库 我们在使用标准库的时候,需要有系统的头文件和系统的库文件,这个库文件是什么呢? …

Databend 借助对象存储帮你实现降本增效

本篇文章围绕着: 什么是对象存储当 Databend 遇到对象存储2022 年 Databend 利用对象存储降本的案例国内优秀的对象存储产品基于对象存储创业的产品 什么是对象存储 对象存储是一种可以非结构化存储和管理数据的技术。 可以简单理解为 NoSQL 接口方式存储和访问数…

linux系统中使用QT实现多媒体的功能方法

大家好,今天主要和大家聊一聊,如何使用QT中的多媒体的功能。 目录 第一:多媒体基本简介 第二:应用实例实现 第三:程序运行效果 第一:多媒体基本简介 QT的多媒体模块提供了音频,视频&#xff…

分布式系统-CAP 理论

在前一篇分布式系统–拜占庭将军问题(The Byzantine Generals Problem) 我们理解了共识问题的背景,这一节主要讨论如何解决或者理解自己系统中的共识问题,通过什么来分辨自己的系统需要哪一种共识。 这个理论就是 CAP 理论,先想下面几个问题…

linux 线程详解

前言 程序运行在内存空间中叫进程,进程中包含有若干线程,线程是系统调度和执行的基本单位。线程才是程序运行的实体,通常程序里的main()函数就相当于主线程,把进程理解成一个容器,里面可以包含有若干线程和若干资源&am…

6)Mybatis启动流程

1. 首先Mybatis会加载配置文件mybatis-config.xml, 主要实现在Mybatis的builder模块,包路径org.apache.ibatis.builder,解析入口XMLConfigBuilder private void settingsElement(Properties props) {configuration.setAutoMappingBehavior(Au…

指针进阶篇(2)

进阶指针 🤔前言🤔 一、😊函数指针😊 二、😜函数指针数组😜 三 、😝指向函数指针数组的指针😝 四、🌝回调函数🌝 🍀小结🍀 &…

摩丝-题解

看到题目,怀疑是莫尔斯电码,打开发现果然是莫尔斯电码的点和划.. .-.. --- ...- . -.-- --- ..-简单说一下电报的原理最简单的电报模型就是一个电源,一个开关和一个电磁铁当需要长距离使用时候,需要用到继电器按下开关&#xff0c…

【BP靶场portswigger-服务端10】XML外部实体注入(XXE注入)-9个实验(全)

前言: 介绍: 博主:网络安全领域狂热爱好者(承诺在CSDN永久无偿分享文章)。 殊荣:CSDN网络安全领域优质创作者,2022年双十一业务安全保卫战-某厂第一名,某厂特邀数字业务安全研究员&…

C#【必备技能篇】使用NPOI实现对excel的读取和写入

文章目录1、Winform界面布局2、引用NPOI的dll3、源码4、运行效果5、NPOI的dll下载地址6、补充【以上步骤只能打开.xls文件(97-2003版本),打不开.xlsx文件(2007版本)】1、Winform界面布局 2、引用NPOI的dll 3、源码 us…

(十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置

前言 本节内容我们主要介绍一下在jenkins中如何集成sonar qube代码质量检查工具,sonar qube可以在流水化项目集成部署前对我们的代码质量检查。开始本节内容前我们需要先搭建好sonar qube服务,关于sonar qube服务的搭建可参考作者往期博客内容&#xff…

P4391 [BOI2009]Radio Transmission 无线传输

题目描述 给你一个字符串 s_1s1​,它是由某个字符串 s_2s2​ 不断自我连接形成的。但是字符串 s_2s2​ 是不确定的,现在只想知道它的最短长度是多少。 输入格式 第一行一个整数 LL,表示给出字符串的长度。 第二行给出字符串 s_1s1​ 的一个子…

【linux入门】基础知识学习笔记

文章目录【第一章-宏观知识】1.硬件和软件的关系2.操作系统 是什么、作用是什么3.常见的操作系统4.Linux的诞生5.Linux内核 是什么6.Linux发行版 是什么7.WSL是什么8.虚拟机快照9.FinalShell(Xshell替代品)【第二章-Linux基础命令】1.Linux目录结构2.什么…

Linux---权限

目录 1.文件访问者的分类(人/用户) 2.文件类型和访问权限(事物属性) 3.文件权限值的表示方法 a)字符表示方法 b)8进制数值表示方法 4.文件访问权限的相关设置方法 4.1 改属性 4.2 改人(改拥有者/所属组)…

数组常用方法总结 (3) :map / forEach / every / some

map 遍历数组的每一项。如果是简单数组,不改变原始数组(值类型)。如果是对象数组,原始数组可以被改变(引用类型)。遍历原始数组,返回值为原始数组的每一项,最终可组合成新数组。 简…