Autosar 系列教程:小柴带你学 AutoSar 总目录

# 小柴冲刺软考中级嵌入式系统设计师系列四、嵌入式系统软件基础知识(1)嵌入式软件基础

随着技术发展,物理的计算、处理、存储等硬件资源越来越 “透明”、成熟和标准化,人们越来越关注人机界面和被控对象的软件控制规律。本章简要介绍嵌入式系统软件相关基础知识。

# 一、嵌入式软件基础

嵌入式软件是指应用在嵌入式计算机系统当中的各种软件。在嵌入式系统的发展初期,软件的种类很少,规模也很小,基本上都是硬件的附属品。随着嵌入式系统应用的发展,特别是随着后 PC 时代的来临,嵌入式软件的种类和规模都得到了极大的发展,形成了一个完整、独立的体系。

# 1、嵌入式系统

嵌入式计算机系统是与特定功能的设备集成在一起、且隐藏在这个功能系统内部为预定任务而设计的计算机系统。该计算机可对设备的状态进行采集,包括操作者的命令和受控对象的状态,按照设备所要求的、预先设定的特定规律进行计算,计算结果作为命令输出到设备的某些部件,控制某些操作,同时将人所关心的信息显示给操作者。个典型的嵌入式系统如图 4-1 所示。

image-20241014072511664

上述嵌入式系统的输入、处理、输出的各个部分,一般情况下都是通过软件运行完成的。因此嵌入式软件是嵌入式系统的重要组成部分,而且体现了系统的思想、方法和规律。

在当今社会中,嵌入式系统已经和我们的生活息息相关,人们每时每刻都离不了嵌入式系统,如图 4-2 所示。

嵌入式系统一般是实时系统,《牛津计算机字典》对实时系统解释是:“系统的输入对应于一个外部物理世界的运动,而系统输出对应着另外一个物理世界的运动,而这两个运动的时间差必须在可接受的足够小的范围内,实时性就体现在从输入到形成输出所需的时间。” 实时系统又进一步定义为硬实时系统和软实时系统两种,如表 4-1 所示。

image-20241014072613264

image-20241014072648666

般认为,嵌入式计算机相对于个人计算机或超级计算机,在软件或硬件上的资源是有限的,硬件资源体现在处理速度、功耗、存储空间等方面,软件资源指有限的应用、有限的操作系统支持、应用代码量少等方面。

第一款大批量生产的嵌入式系统是美国 1961 年发布的民兵 I 型导弹内嵌的 D-17 自动制导计算机。

随着 20 世纪 60 年代早期应用开始,嵌入式系统的价格迅速降低,同时处理功能和能力获得快速提高。以第一款单片机 Intel 4004 为例,在存储器和外围芯片的配套使用下实现了计算器和其他小型系统。1978 年,美国国家工程制造商协会发布了可编程单片机的 “标准”,涵盖了几乎所有以计算机为基础的控制器,如单板计算机、数控设备以及基于事件的控制器,使得微处理器得到了快速发展。

无一例外,不断发展中的嵌入式计算功能的实现都通过用户需求驱动、顶层定义、硬件定义开始,但核心是软件的算法处理,实际上类似硬件功能通过不同软件的控制就可以实现不同用户所需要的嵌入式功能,如图 4-3 所示。

image-20241014072757130

当基础硬件接口、计算和存储资源、总线与网络乃至各种传感器、作动器、液压等以模块化、通用化、组合化等变得越来越成熟,他们就可以方便地组合成硬件平台。而软件却恰恰相反,基本是为满足人类某种新的设想或应用要求开始进行新的设计。这些设计从诸如领域、实现功能、性能、可靠性、安全性等方面,可以是全新理念设备、或是适应性修改升级等途径,都会导致软件有不同程度的差异。

# 嵌入式系统具有以下特征:

# (1) 嵌入式系统的时间敏感性

嵌入式实时系统对时间响应都是有要求的。例如对于一个设备的运动控制系统,从操作指令发出,嵌入式计算机根据指令和外部条件计算并输出到动作器的动作,要保证在所有的条件下、在确定的时间内产生所需的输出。这对于设计者来说,一般的实时系统都会围绕这个关键需求进行系统设计。另外为了满足时间敏感性要求,确保在最复杂行为和最大延时情况下,系统操作不发生延迟,要求处理器的利用率要有 40% 左右的余量。有时为满足某些强实时嵌入式系统的应答时间限定在毫秒级或更低,需要在高级语言中嵌入低级语言编程实现。

# (2) 嵌入式系统的可靠性和安全性

嵌入式计算机系统的失效带来的可能是个人娱乐系统故障的微小损失,可能是铁路信号失效的巨额经济损失,也可能是战略武器控制等经济损失以及重大的社会政治影响等。所以在某种设计缺陷被诱发后,对于不同的系统需要采取不同的策略,例如对具有重大影响的系统,要求计算机或计算机软件对设计缺陷、制造缺陷等失效采取 “永不放弃” 的安全性设计技术,将损失控制在可接受的范围内。在有人为输入情况下,嵌入式系统还需考虑最大可能地减少人为失误所引起的系统失效。这些算法或机制可以是输入有效性合理性检查、硬件容错、软件容错、错误后的系统缓慢降级、系统进入安全模式等。

# (3) 嵌入式软件的复杂性。

软件复杂度取决于问题规模和复杂度。简单问题的软件可由个人完成,甚至可以进行软件正确性证明;即使过程中更换人员,花费少许时间就可掌握和维护。但如汽车控制、飞机控制等大型复杂软件,其需要根据复杂的外部输入、按照多变量物理规律和人们的预期,实现预定的功能。软件需要根据系统的外部事件及其组合,考虑各种处理、逻辑、时序、边界、超出边界的鲁棒性等进行详细算法和策略研究。还需要考虑如安全性、可靠性、维护性等质量要求。更困难的是大规模软件需要团队联合定义、并行开发、持续维护,同时考虑处理平台限制条件。

# 二、嵌入式软件

软件实际上是客观世界问题空间与解空间的具体实现,也是人类知识的提炼、抽象和固化。软件是计算机相关的:

(1) 完成预定功能和性能的可执行的指令 (计算机程序) 序列。

(2) 程序操作的信息或数据结构。

(3) 描述程序操作、数据和使用的文档。

嵌入式软件是为完成某特定用途而开发的、驻留在预先定义的嵌入式计算机平台上的软件。随着微电子技术飞速发展带来的智能化需求的不断扩展,嵌入式软件无处不在,规模也越来越大。

近三十年来,随着现代化战争信息化程度的不断提高,随着装备由机械化向信息化的战略转型,军用软件已经渗透到军事应用的各个方面,成为装备及其体系中不可或缺的组成部分,其发展和应用水平代表着一个国家的装备实力。美国国防部在 2002 年的《国防科学技术领域计划》中就把军用软件设计和改进作为重要研究领域,制定了军用软件发展的近、中、远期目标。2011 年,美国政府、国防部、海陆空三军、洛克希德・马丁公司等 26 个组织组成工作组,专题研究军事装备中软件研制和部署存在的问题,形成《美国国防部与国防工业领域软件工程的重大问题报告》,对军用软件的发展提出建议。这些都说明了军用软件在现代化战争中的重要地位和作用。

随着飞机机载计算机的广泛使用,机载软件从无到有、规模从小到大、复杂度从低到高。软件负责数据的采集、存储和处理。实时进行各种逻辑判断、数学运算、行为推导、状态转换等处理,帮助飞行员优化各种操作,实现飞行航路计算、姿态控制、环境控制、燃油输送、任务计算、状态监控、信息显示报警、人机界面控制等功能,不夸张地说,飞行员每一个操作、飞机的每一个动作的完成都离不开软件运行。

# 而软件的复杂性、重要性还体现在:

(1) 从计算机理论和技术发展趋势来说,硬件和软件没有明确界限,原来使用硬件实现的功能在尽可能地向软件迁移,技术进步越来越显现在软件方面。

(2) 软件直接和飞机安全功能相关,而且这种相关性越来越高,如电传飞控软件。

(3) 软件的特殊性导致了需要有特殊的规则保证系统的安全性、可靠性。

与硬件不同,软件至今尚未摆脱手工方式。更严重的是,软件在开发过程中涉及到了各行各业的工作人员,其中包括业务定义人员、系统分析员、系统设计人员、软件架构师、软件工程师、软件测试工程师以及质量工程师等。实际上这些人员中只有软件工程师是专业软件开发人员,其他人员都需要同时具备软件和其他行业的背景。因此与其

# 他行业比较,软件行业具有以下鲜明的特点:

(1) 抽象性:软件直接反映了人的思维逻辑实体,同时几乎没有具体物理实体,且没有明显的制造过程。

(2) 客观问题越来越复杂,软件也随之越来越复杂,而且软件技术的进步速度落后于需求增长的速度。

(3) 相对于通用硬件,软件开发成本昂贵,随着问题规模的加大、成本急剧增加。

(4) 软件运行和使用没有磨损或老化现象。

(5) 软件对硬件和环境有着不同程度的依赖性。

(6) 大多数软件是新开发的,通过已有构件组装技术尚不成熟。

(7) 软件工作结果涉及到许多社会因素。

以上特点使得软件开发进展情况较难衡量,软件质量不易评价,从而使软件产品的生产管理、过程控制及质量保证都相当困难。

# 对于嵌入式软件而言,它除了具有通用软件的一般特性,同时还具有一些与嵌入式系统密切相关的特点。这些特点包括:

(1) 软件受资源的限制。由于嵌入式系统的资源一般比较有限,所以嵌入式软件必须尽可能地精简,才能适应这种状况。

(2) 开发难度大。嵌入式软件的运行环境和开发环境一般比较复杂,从而加大了它的开发难度。首先,由于硬件资源有限,使得嵌入式软件在时间和空间上都受到严格的限制,但要想开发出运行速度快、存储空间少、维护成本低的软件,需要开发人员对编程语言、编译器和操作系统有深刻的了解。其次,嵌入式软件一般都要涉及到底层软件的开发,应用软件的开发也是直接基于操作系统的,这就需要开发人员具有扎实的软、硬件基础,能灵活运用不同的开发手段和工具,具有较丰富的开发经验。最后,对于嵌入式软件来说,它的开发环境与运行环境是不同的。嵌入式软件是在目标系统上运行,但开发工作要在另外的开发系统中进行,当编程人员将应用软件调试无误后,再把它放到目标系统上去。

(3) 实时性和可靠性要求高。实时性是嵌入式系统的一个重要特征,许多嵌入式系统要求具有实时处理的能力,这种实时性主要是靠软件层来体现的。软件对外部事件做出反应的时间必须要快,在某些情况下还要求是确定的、可重复实现的,不管系统当时的内部状态如何,都是可以预测的。同时,对于事件的处理一定要在限定的时间期限之前完成,否则就有可能引起系统的崩溃。例如,火箭飞行控制系统就是实时的,它对飞行数据采集和燃料喷射时机的把握要求非常的准确,否则就难以达到精确控制的目的,从而导致飞行控制的失败。

与实时性相对应的是可靠性,因为实时系统往往应用在一些比较重要的领域,如航天控制、核电站、工业机器人等等,如果软件出了问题,那么后果是非常严重的,所以要求这种嵌入式软件的可靠性必须非常高。

(4) 要求固化存储。为了提高系统的启动速度、执行速度和可靠性,嵌入式系统中的软件一般都固化在存储器芯片或单片机本身中,而不是像通常的计算机系统那样,存储在磁盘等载体中。

# 三、嵌人式软件分类

按通常的分类方法,嵌入式软件可以分为三大类:

  • 系统软件、
    • 系统软件:控制和管理嵌入式系统资源,为嵌入式应用提供支持的各种软件,如设备驱动程序、嵌入式操作系统、嵌入式中间件等。
  • 应用软件和
    • 应用软件:嵌入式系统中的上层软件,它定义了嵌入式设备的主要功能和用途,并负责与用户进行交互。应用软件是嵌入式系统功能的体现,一般面向于特定的应用领域,如飞行控制软件、手机软件、MP3 播放软件、电子地图软件等。
  • 支撑软件。
    • 支撑软件:辅助软件开发的工具软件,如系统分析设计工具、在线仿真工具、交叉编译器、源程序模拟器和配置管理工具等。

在嵌入式系统当中,由于它的硬件配置一般比较低,无法运行太多、太复杂的软件。因此,对于系统软件和应用软件来说,它们是运行在目标平台,即嵌入式设备上。而对于各种软件开发工具来说,它们大部分都运行在开发平台上。本章主要讨论的是运行在嵌入式设备上的软件,即系统软件和应用软件。

# 四、嵌入式软件体系结构

# 1、无操作系统的情形

在嵌入式系统的发展初期,由于硬件的配置比较低,而且系统的应用范围也比较有限,主要集中在控制领域,对于是否有系统软件的支持,要求还不是很强烈。所以在那个阶段,嵌入式软件的设计主要是以应用为核心,应用软件直接建立在硬件上,没有专门的操作系统,软件的规模也较小,基本上属于硬件的附属品。在具体实现上,无操作系统的嵌入式软件主要有两种实现方式:循环轮转和前后台系统。

# 1) 循环轮转方式

如图 4-4 所示,循环轮转方式的基本思路是:把系统的功能分解为若于个不同的任务,然后把它们包含在一个循环语句当中,按照顺序逐一执行。当执行完一轮循环后,又回到循环体的开头重新执行。

image-20241014074043999

循环轮转方式的优点是简单、直观、开销小、可预测。软件的开发就是一个典型的基于过程的程序设计问题,可以按照自顶向下、逐步求精的方式,将系统要完成的功能逐级划分成若干个小的功能模块,像搭积木一样搭起来。由于整个系统只有一条执行流程和一个地址空间,不需要任务之间的调度和切换,因此系统的管理开销很少。循环轮转方式的缺点是过于简单,所有的代码都必须按部就班地顺序执行,无法处理异步事件,缺乏并发处理的能力。另外,这种方案没有硬件上的时间控制机制,无法实现定时功能。

# 2) 前后台系统

前后台系统就是在循环轮转方式的基础上,增加了中断处理功能,如图 4-5 所示。

image-20241014074132692

图 4-5 中的中断服务程序负责处理异步事件,这部分可以看成是前台程序。而后台程序一般是一个无限的循环,负责掌管整个嵌入式系统软、硬件资源的分配、管理以及任务的调度,是一个系统管理调度程序。在系统运行时,后台程序会检查每个任务是否具备运行条件,通过一定的调度算法来完成相应的操作。而对于实时性要求特别严格的操作通常由中断来完成。为了提高系统性能,大多数的中断服务程序只做一些最基本的操作,例如,把来自于外设的数据拷贝到缓冲区、标记中断事件的发生等,其余的事情会延迟到后台程序去完成。

实际上,前后台系统的实时性比预计的要差。这是因为前后台系统认为所有的任务具有相同的优先级别,而且任务的执行又是通过先进先出的队列排队,因而对那些实时性要求很高的任务不能立刻得到处理。但由于这类系统的结构比较简单,几乎不需要额外开销,因而在一些简单的嵌入式应用中被广泛地使用,如微波炉、电话机、电子玩具等。

# 2、有操作系统的情形

从 20 世纪 80 年代开始,嵌入式软件进入了操作系统的阶段。这一阶段的标志是操作系统出现在嵌入式系统上,程序员在开发应用程序的时候,不是直接面对嵌入式硬件设备,而是在操作系统的基础上编写,嵌入式软件开发环境也得到了一定的应用。如今,嵌入式操作系统在嵌入式应用中使用得越来越广泛,尤其是在功能复杂、系统庞大的应用中显得愈来愈重要。这种开发方式主要有以下三个优点:

(1) 提高了系统的可靠性。在控制系统中,出于安全方面的考虑,要求系统起码不能崩溃,而且还要有自愈能力。这就需要在硬件设计和软件设计这两个方面来提高系统的可靠性和抗干扰性,尽可能地减少安全漏洞和不可靠的隐患。

(2) 提高了系统的开发效率,降低了开发成本,缩短了开发周期。

在嵌入式操作系统环境下,开发一个复杂的应用程序,通常可以按照软件工程的思想,将整个程序分解为多个任务模块。每个任务块的调试、修改几乎不影响其他模块,而且商业软件一般都提供了良好的多任务调试环境,这样就大大提高了系统的开发效率

(3) 有利于系统的扩展和移植。

在嵌入式操作系统环境下开发应用程序具有很大的灵活性,操作系统本身可以剪裁外设、相关应用也可以配置,软件可以在不同的应用环境、不同的处理器芯片之间移植,软件构件可复用。

嵌入式软件的体系结构如图 4-6 所示。

image-20241014074655639

在如图 4-6 所示的嵌入式软件体系结构中,

  • 最底层是嵌入式硬件,包括嵌入式微处理器、存储器和键盘、输入笔、LCD 显示器等输入 / 输出设备。
  • 硬件层之上是设备驱动层,它负责与硬件直接打交道,并为上层软件提供所需的驱动支持。
  • 设备驱动层的上面是操作系统层,它可以分为基本部分和扩展部分。前者是操作系统的核心,负责整个系统的任务调度、存储管理、时钟管理和中断管理等功能,这一部分是基础和必备的;后者则是系统为用户提供的一些扩展功能,包括网络、文件系统、图形用户界面 GU、数据库等,这一部分的内容可以根据系统的需要来进行裁剪。
  • 在操作系统的上面,是中间件软件,
  • 再上面就是各种应用软件了,如网络浏览器、MP3 播放器、文本编辑器、电子邮件客户端、电子游戏等。对于嵌入式系统的用户来说,就是通过这些应用软件来跟系统交互。

# 五、设备驱动层

大多数的嵌入式硬件设备都需要某种类型的软件进行初始化和管理,这部分工作是由设备驱动层来完成的,它负责直接与硬件交互,对硬件进行管理和控制,并为上层软件提供所需的驱动支持。

# 1、板级支持包

设备驱动层也称为板级支持包 (Board Support Package,BSP),它包含了嵌入式系统中所有与硬件相关的代码。BSP 的基本思想是将嵌入式操作系统与具体的硬件平台隔离开来。也就是说,在 BSP 当中,把所有与硬件相关的代码都封装起来,并向上提供一个虚拟的硬件平台,而操作系统就运行在这个虚拟的硬件平台上,它使用一组定义好的编程接口来与 BSP 进行交互,并通过 BSP 来访问真正的硬件。BSP 在嵌入式系统中的角色,类似于 PC 系统中的 BIOS 和驱动程序。

对于一个成熟的商用操作系统而言,为了在业界得到广泛应用,就必须要能够支持种类众多的硬件平台,并实现应用程序的硬件无关性。一般来说,这种无关性是由操作系统来实现的。但是对于嵌入式系统来说,它没有像 PC 那样具有广泛使用的各种工业标准和统一的硬件结构。变化众多的硬件环境就决定了无法完全由操作系统来实现上层软件与底层硬件之间的无关性。因此各种商用的嵌入式操作系统都采用了分层设计的思想将系统中与硬件直接相关的一层软件独立出来,称之为板级支持包。

对于不同的嵌入式操作系统,BSP 的具体结构和组成也各不相同。一般来说,BSP 主要包括两个方面的内容:引导加载程序 BootLoader 和设备驱动程序。

# 1) 引导加载程序

引导加载程序 BootLoader 是嵌入式系统加电后第一时间运行的软件代码。在桌面 PC 中的引导加载程序是由位于只读存储器 ROM 中的 BIOS 和位于硬盘的主引导记录 (Master Boot Record,MBR) 中的 BootLoader 引 | 导程序 (如 LILO 和 GRUB) 两部分代码组成的。BIOS 在完成硬件检测和资源分配后,将硬盘 MBR 中的引导程序读到系统的内存当中,然后由 MBR 负责启动操作系统。但是在嵌入式系统当中,通常没有像 BIOS 那样的固件程序,因此整个系统的加载启动任务就完全由 BootLoader 来完成。例如,在一个基于 ARM7TDM 内核的嵌入式系统中,系统在上电或复位时一般都从地址 0x00000000 处开始执行,而在这个地址处安排的通常就是系统的 BootLoader 程序。

简单地说,BootLoader 就是在操作系统内核运行之前运行的一小段程序。通过这段程序,可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境配置为定的状态,以便为最终调用操作系统内核做好准备。

在嵌入式系统中,BootLoader 的实现高度依赖于具体的硬件平台,对于不同的 CPU 体系结构和板级设备配置,需要不同的 BootLoader。因此,要想建立一个通用的 BootLoader 几乎是不可能的。但是,一般来说,它主要包含以下基本功能:

(1) 片级初始化。片级初始化主要完成微处理器的初始化,包括设置微处理器的核心寄存器和控制寄存器,微处理器的核心工作模式及其局部总线模式等。片级初始化把微处理器从上电时的缺省状态逐步设置成系统所要求的工作状态。

(2) 板级初始化。通过正确地设置各种寄存器的内容来完成微处理器以外的其他硬件设备的初始化。例如,初始化 LCD 显示设备,初始化定时器,设置中断控制寄存器等。

(3) 加载内核。将操作系统和应用程序的映像从 Flash 硬盘拷贝到系统的内存当中,然后跳转到系统内核的第一条指令处继续执行。

# 2) 设备驱动程序

在一个嵌入式系统当中,设备驱动程序是必不可少的。所谓的设备驱动程序,就是 - 组库函数,用来对硬件进行初始化和管理,并向上层软件提供良好的访问接口。对于不同的硬件设备来说,设备驱动程序也是不一样的。但是一般来说,设备驱动程序都会具备以下的基本功能。

(1) 硬件启动:在开机上电或系统重启的时候,对硬件进行初始化。

(2) 硬件关闭:将硬件设置为关机状态。

(3) 硬件停用:暂停使用这个硬件。

(4) 硬件启用:重新启用这个硬件。

(5) 读操作:从硬件中读取数据。

(6) 写操作:往硬件中写入数据。

除了以上这些普遍适用的功能之外,设备驱动程序还可能有很多额外的、特定的功能。在具体实现的时候,这些功能一般是用函数的形式来实现的。这些函数主要有两种组织结构,即分层结构和混合结构,如图 4-7 所示。

image-20241014075238182

所谓分层结构,就是把设备驱动程序当中的所有函数分为两种类型,一种是直接跟硬件交互,直接去操纵和控制硬件设备的,这些函数称为硬件接口;另一种是跟上层软件交互,作为上层软件的调用接口。分层结构的优点是:把所有与硬件有关的细节都封装在硬件接口当中,硬件升级时,只需要改动硬件接口当中的函数,而上层接口当中的函数不用做任何的修改。

所谓混合结构,就是在设备驱动程序当中,上层接口和硬件接口的函数是混在一起、相互调用的,它们之间没有明确的层次关系。无论是分层结构还是混合结构,它们给上层软件提供的调用接口都应该是明确而稳定的,即便设备驱动程序的内部有任何的变化,也不会影响到上层软件,这样,在移植操作系统和应用程序的时候,就非常方便。

# 六、嵌入式中间件

近年来,在嵌入式系统中,处理器的性能不断提高,系统的功能更为复杂,嵌入式软件对可靠性、实时性的要求越来越高,因此,中间件技术也被引入到嵌入式系统的设计当中,并与实时多任务操作系统紧密结合。这种全新的软件设计方法,可以使用户把精力集中到系统功能的实现上,从而真正实现嵌入式系统的软硬件协同设计。当然,在一个实际的嵌入式系统当中,对于是否要采用嵌入式中间件,这完全取决于具体的应用需求。

所谓嵌入式中间件,简单地说,就是在操作系统内核、设备驱动程序和应用软件之外的所有系统软件。嵌入式中间件的基本思路是:把原本属于应用软件层的一些通用的功能模块抽取出来,形成独立的一层软件,从而为运行在它上面的那些应用软件提供一个灵活、安全、移植性好、相互通信、协同工作的平台。这样,就可以有效地实现软件的可重用,降低应用软件的复杂性,提高系统的开发效率,缩短系统的开发周期,节约开发成本和维护费用,同时还保证了系统的高伸缩性、易升级性和稳定性。当然如果在嵌入式系统中引入中间件,将会带来额外的开销,可能会对系统的性能造成定的影响。

嵌入式中间件可以分为不同的类型,如

  • 消息中间件、
  • 对象中间件、
  • 远程过程调用、数据库访问中间件、
  • 安全中间件等。

有些嵌入式系统较为复杂,单个的中间件可能无法满足应用的需求,这时就需要将多种中间件集成在一起。这样的集成解决方案如 Sun 公同的嵌入式 Java、微软的.NET Compact Framework、OMG (Object Management Group) 的嵌入式 CORBA 等。

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

flechazo 微信支付

微信支付

flechazo 支付宝

支付宝

flechazo 贝宝

贝宝