超详细解析!嵌入式开发中的三种程序构架
扫描二维码
随时随地手机看文章
嵌入式软件开发是一门应用广泛且不断发展的技术领域,为了满足不同应用场景的需求,开发人员可以采用多种架构方法。
0、前言
在嵌入式软件开发,包括单片机开发中,软件架构对于开发人员是一个必须认真考虑的问题。软件架构对于系统整体的稳定性和可靠性是非常重要的,一个合适的软件架构不仅结构清晰,并且便于开发。
我相信在嵌入式或单片机软件开发的初期大多数开发者采用的都是简单的前后台顺序执行架构(我就是这样的)。
在嵌入式软件开发中,程序架构主要分为三种,本篇文章将对这三种程序架构做出详解。
1、软件架构存在的意义
可以说一个好的程序架构,是一个有经验的工程师和一个初学者的分水岭。软件架构对于开发人员是友好的,你希望先执行什么任务后执行什么任务,或者这一个时间点执行什么任务下一个执行什么任务,又或者什么事件会同步到某个任务等等,在不同的软件架构下,解决上述问题的具体方法都是有所区别的。软件架构对开发者最大的帮助是:帮助开发者掌控整个工程的框架,当你熟练使用其中某一个程序架构后,对于系统中出现的bug你一定能够快速的定位并解决。当然,我建议要根据需要选择合适的软件架构进行开发,具体原因在文章后面会进行介绍。
2、深入介绍三种不同的程序架构
三种常用的软件架构有:顺序执行的前后台系统、时间片轮询系统和多任务操作系统。为了让大家有一个更为清晰的认识,我分别用三种软件架构对一个实例进行介绍说明。这个实例如下:它有4个任务,这4个任务为按键扫描、声光报警、显示屏刷新和超声波测距。这个实例的具体功能是通过按键设置测量距离的阈值,当测距距离低于设置的阈值时,触发声光报警并且将测量距离实时显示在显示屏上(这个应用是汽车倒车雷达的具体体现)。
2.1顺序执行的前后台系统
在顺序执行的前后台系统中,我会把键盘扫描用查询的方式放在while(1)中,而显示屏刷新和超声波测距使用中断,在中断服务函数中获取测量距离后进行显示,在主函数的循环中进行按键的检测,声光处理也放在主循环中。这样整个程序就以变量标志的同步方式在主循环和后台中断中执行,对应的程序代码如图所示:
顺序执行前后台系统的主函数
顺序执行前后台系统的中断服务函数
在本文中,我们将探讨嵌入式软件开发中常用的三种架构:前后台顺序执行法、时间片法和操作系统。
01.
前后台顺序执行法
前后台顺序执行法也称为单任务执行法,是最简单、最常见的嵌入式软件架构之一。
在这种架构中,系统按照程序代码的顺序依次执行任务。所有任务都在一个循环中执行,每次只执行其中一个任务,其余任务被挂起。这种架构适用于简单的应用,如传感器数据采集、控制器等。
然而,前后台顺序执行法有一定的局限性。
首先,它无法充分利用处理器资源,因为每次只执行一个任务,其他任务处于挂起状态。其次,任务之间无法灵活共享资源,容易造成资源浪费和效率低下。在一些对实时性要求较高的场景中,这种架构无法满足要求。
02.
时间片法
时间片法是一种多任务执行法,它通过为每个任务分配一定的执行时间片,使得所有任务都能够按照一定的时间间隔交替执行。
任务执行的时间片是固定的,当一个任务的时间片用完后,系统切换到下一个任务执行。这种方式使得多个任务能够并行执行,提高了系统的资源利用率和效率。
时间片法适用于中等复杂度的嵌入式系统,可以满足对实时性要求较高的场景。它需要合理设置任务的优先级和时间片大小,以确保重要任务优先执行,并且每个任务都能在适当的时间内完成。
03.
操作系统
操作系统是一种更为复杂和强大的嵌入式软件架构。它能够管理和协调多个任务的执行,并提供一系列的系统服务,如任务调度、内存管理、设备驱动、通信机制等。操作系统为开发人员提供了更高层次的抽象,使得软件开发更加灵活、高效。
在操作系统架构下,每个任务都有自己的优先级和状态,操作系统通过任务调度算法决定哪个任务优先执行。任务之间可以共享资源,通过互斥机制来实现对共享资源的访问控制,确保系统稳定和安全。
操作系统适用于复杂度较高、实时性要求严格的嵌入式应用,如智能手机、工业自动化控制系统等。它提供了更大的灵活性和可扩展性,使得开发人员能够更容易地实现复杂的功能和算法。
综上所述,嵌入式软件开发中常用的三种架构分别是前后台顺序执行法、时间片法和操作系统。
选择适合的架构取决于应用的复杂性、实时性要求和资源限制等因素。开发人员需要根据具体情况,灵活选择合适的架构,并结合系统要求进行合理的设计和优化,以确保嵌入式系统的稳定性、可靠性和高效性。
嵌入式软件,受限于硬件资源,时常会出现驱动与应用紧密耦合的情况。然而,对于大型项目而言,充足的资源使得我们能够采用更为复杂的架构模式来应对业务逻辑的复杂性以及后续的扩展维护需求。这些架构模式,如分层架构、多层架构、管道-过滤器架构等,都是为了解决特定问题而设计的。
在众多架构模式中,分层架构是最为常见的一种。它主要由展现层、业务层、持久层和数据库层四个部分组成,通过这种方式,软件能够更加清晰地分离不同的功能模块,从而提高代码的可读性和可维护性。
1)背景
随着系统复杂性的增加,各个部分的需求和衍化往往独立发展。为了更好地管理和维护这样的系统,开发者需要明确地分离关注点,使各个模块能够独立进行开发和演进。
2)挑战
软件架构需要设计成一种方式,使得各个模块能够单独开发和变化,同时减少模块间的交互,从而确保系统的可移植性、可修改性和复用性。
3)解决方案
分层架构模式应运而生,它将软件划分为不同的逻辑单元,即“层”。每一层都包含一组高度内聚的模块,提供特定的服务,并且其使用是单向的。通过分层,软件被划分为多个独立的分区,每个分区都暴露一个公开的接口。
在分层架构中,每一层都扮演着特定的角色和职责。例如,展现层专门负责处理用户界面相关的事务。这种明确的角色和职责划分,使得构建高效的系统变得简单明了。
此外,分层架构还是一种技术性的分区方式,而非领域性的。它由组件而非领域来组成,这意味着不同层之间的交互更加清晰和简洁。
最后,分层架构中的每一层都被明确标记为封闭或开放。封闭层意味着请求必须经过它下面的层次才能传递到下一层,从而保证了请求不会跳过任何层次。这种设计使得系统更加稳健和可预测。
4)潜在问题
采用分层架构虽然有助于提高系统的模块化和可维护性,但也可能面临性能方面的挑战。在高性能应用程序中,由于业务请求需要经过架构中的多层处理,这可能会降低响应效率。此外,分层架构的实施还可能增加系统的初期成本和整体复杂性。
5)适用范围
尽管存在上述潜在问题,分层架构仍然是一种非常有用的设计模式。对于小型或简单的应用程序而言,这种模式能够有效地帮助开发者明确模块间的职责和边界,从而简化开发和维护过程。因此,在适当的情况下,我们应该考虑采用分层架构来构建高效、可维护的软件系统。
许多系统的执行结构都采用了逻辑组件的分组方式,这些分组被称作“层”。在分布式部署的环境中,经常需要将系统的基础设施拆分成不同的子集。这就引出了一个问题:如何合理地将系统分割成多个计算上独立、又通过通信媒介相连的软件和硬件组件?然而,这种分割方式也面临一些挑战,包括前期投入的大量成本和系统整体复杂性的增加。尽管如此,管道-过滤器(pipe-filter)架构在软件架构中仍是一种常见的模式,它为这类问题提供了有效的解决方案。
1)背景
在许多系统中,离散数据流从输入到输出的转换是一个核心需求。由于这类转换在实践中经常重复出现,因此将其模块化并创建成可复用的组件,是提高效率和灵活性的理想选择。
2)挑战
为了实现这种模块化,系统需要被分割成松耦合的组件,这些组件之间通过简单通用的交互机制进行连接。这样的设计使得组件能够灵活地组合与复用,同时支持并行的执行方式。
3)架构解析
管道-过滤器架构为此类需求提供了一种解决方案。在这种架构中,管道充当了过滤器之间的通信通道。每个管道都是非定向和点对点的,它们接受来自一个源的输入,并直接将输出传递给另一个源,从而确保了数据流的高效传输。
此外,该架构还定义了四种关键角色:producer(或source)作为过程的起点,transformer(或map)负责对数据进行转换,tester(或reduce)用于测试条件,而consumer(或sink)则作为终点处理数据。
4)局限性
尽管管道-过滤器架构具有诸多优点,但它也有其适用范围。对于需要高度交互性的系统来说,这种架构可能不太适合。此外,过多的解析和反解析操作也可能导致性能损失,并增加编写过滤器的复杂性。
5)应用场景
管道-过滤器架构在各种应用程序中都有广泛的应用,特别是那些需要简化单项处理任务的系统。通过合理运用这种架构,可以有效地提高系统的可维护性、灵活性和性能。





