目录
23考纲
考点1 嵌入式软件的特点
(1)软件与硬件一体化
(2)软件效率要求高,实时性要求高
(3)软件可裁剪
(4)软件安全性和可靠性要求高
(5)软件开发难度大
(6)软件需求多样化
(7)软件产业高度分散
(8)软件具有较长的生命周期
考点2 嵌入式系统的软件结构
(1)简单的轮询结构
①轮询结构的软件结构
最简单的软件结构是轮询(Round-Robin)结构,应用程序重复循环检査每个外部输入条件,一旦有需要处理的任务,则进行相应的处理。
②特点
优点是程序结构简单,便于编程。没有中断机制,不会出现程序随机切换带来的潜在问题。
③适用情况
适用于系统的任务数量较少、任务处理简单且实时性要求不高的场景。
(2)带中断的轮询结构
①介绍
这种结构在简单的轮询结构的“主循环”基础上增加中断服务程序(ISR),中断服务程序处理特别紧急的服务请求,然后没置状态标志;循环主程序轮询这些状态标志,并进行后续的处理。
②结构
a.简介
这种结构也被称为中断驱动结构或前后台结构。后台是一个循环执行的轮询程序,前台则由若干中断服务程序组成。当有外部事件(例如温度传感器报警)发生时,外部事件提出中断请求,暂停后台运行的主循环,进行前台处理,处理完成后又回到后台继续运行主循环。
b.紧急事件的及时中断
如果所有的外部事件处理操作都是由中断服务程序完成的,那么后台程序除了初始化操作外并不做任何事情。这是一种极端的情况。一般情况下,中断服务程序只进行紧急事件的处理,对于非紧急的处理操作,通过设置状态标志由后台循环程序处理。这样可以保证紧急事件能够及时得到中断服务。
④带中断轮询结构的特点
与简单的轮询结构相比,中断驱动结构提高了系统对紧急事件的响应速度,可以并发处理不同的异步事件,因而在一些小型的简单嵌入式系统中应用广泛。由于中断的引入,使得系统软件复杂度明显提高,必须谨慎处理中断嵌套、中断服务程序与主程序的同步协调等问题。
(3)监控式操作系统+应用软件的结构
①嵌入式操作系统的特点
复杂的嵌入式系统要求嵌入式软件必须以多任务方式运行。为了合理地调度多任务和利用系统资源,通常要选配(Embedded Operating System,EOS),这样才能保证程序执行的实时性、可靠性和可维护性,并减少开发时间,降低系统的复杂性,保障软件质量。
②嵌入式操作系统的功能
对于中端嵌入式系统,小型的监控式嵌入式操作系统就可以满足需求。这类嵌入式操作系统通常只包含内核(kernel),仅实现任务调度、任务间通信和中断管理等最基本功能,以多个并发的任务(task)取代“主循环”,其结构如图所示。操作系统内核负责多任务处理,执行任务创建与初始化、任务调度、存储管理、时钟管理和中断管理等。
③多任务系统的特点
实际上是由多个任务、多个中断服务程序和嵌入式操作系统组成的有机整体。操作系统通过任务调度和任务切换保证任务的并行运行,各任务之间以及任务与中断服务程序之间的通信、同步和互斥也需要操作系统的支持。
④监控式操作系统+应用软件的结构的优点
引入操作系统增加了系统的开销。但嵌入式操作系统结构允许多个任务在一个CPU上并行运行,将复杂的系统分解成相对独立的多个任务,从而降低了用户开发嵌入式软件的复杂度,并有效保证系统的实时性和可维护性。
(4)通用嵌入式操作系统+应用软件的结构
①高端嵌入式系统的软件层次结构
a.三层结构
如图所示高端嵌入式系统(如基于 Android或iOS的智能手机系统)实例。其中,嵌入式系统软件控制和管理系统中的资源,为嵌入式应用提供支持,通常又可分为硬件抽象层(驱动层)、操作系统层和中间件层。
b.中间件
中间件(middleware)软件是指除了操作系统内核、设备驱动程序和应用软件之外的系统软件。中间件是具有标准程序接口和协议的通用服务。应用程序共享这些服务,既可减轻开发难度并减少工作量,又获得了相对稳定的应用软件开发和运行环境,当底层的软、硬件变化时仍能保证应用软件的稳定。通用的中间件有Java 虚拟机中间件、数据库访问中间件、图形和图像处理中间件等,面向特定应用领域的有数字电视中间件、嵌入式 RFID中间件等。
②支撑软件
由于嵌入式系统通常是在开发主机上进行交叉开发的,所以在开发主机和嵌入式目标机上还运行着大量的支撑软件。支撑软件指辅助嵌入式系统设计、开发及测试的工具软件,包括系统分析设计工具、在线仿真工具、交叉编译器、源程序模拟器和配置管理工具等。大部分支撑软件都运行在开发平台上。在调试阶段,嵌入式系统目标平台上也会运行一些开发工具的代理程序(agent)。
考点3 硬件抽象层与板级支持包
(1)硬件抽象层和板级支持包的概念
①硬件抽象层(HardwareAbstractLayer,HAL)
a.概念
HAL是在操作系统层与硬件之间设置的独立的接口软件层,是所有直接依赖于硬件的软件,包括引导程序、硬件配置程序和硬件访问代码等。
b.引入的目的
引入HAL的目的是对硬件进行抽象,即将控制所有硬件电路的软件代码封装起来,通过硬件抽象层应用编程接口(HALAPI)向操作系统以及应用程序提供服务,使上层软件开发入员无须关心底层硬件的具体细节和差异,并且支持上层软件在不同体系结构和硬件平台之间的移植。
②板级支持包(Board Support Package,BSP)
a.BSP的特点
板级支持包屏蔽了其所支持的嵌入式操作系统与底层硬件平台之间的相关性,使嵌入式操作系统能够通用于BSP所支持的不同硬件平台,实现嵌入式操作系统的可移植性和跨平台性。BSP的特点是与硬件和操作系统都关系紧密,既有硬件相关性,又有操作系统相关性。BSP规范是 OS相关的,支持不同 OS的BSP的组织结构、向上层提供的功能以及服务接口定义都不相同;而 BSP 代码则必须针对特定硬件专门编写。
b.BSP的功能
BSP在系统复位之后负责系统软硬件环境的初始化,其功能可以分为三部分:
第一,系统复位时的硬件初始化
包括处理器芯片的初始化和电路板的初始化。通常在系统复位时只需对操作系统运行所必需的硬件进行初始化操作,并不需要对系统中的所有硬件都进行初始化。由于在BSP运行之前,操作系统及其附带的调试工具还无法运行,因此 BSP的开发是嵌入式软件开发的难点之一。
第二,为操作系统提供硬件相关的驱动程序支持
BSP 中包含硬件相关的设备驱动程序,这些驱动程序为操作系统和/或应用程序访问硬件提供支持,对系统硬件进行管理,并实现数据的输入输出操作。但是,除了与在引导和加载操作系统过程中所需的硬件环境相关的设备驱动程序之外,BSP包含的其他设备驱动程序通常不直接由BSP使用,而是在系统初始化过程中由BSP将其与操作系统中的通用设备驱动程序关联起来,并在随后操作系统运行之后由操作系统和/或应用程序调用,实现对硬件设备的管理。
第三,引导加载操作系统
在初始化必要的硬件环境之后,BSP还需要进行系统级的初始化。这包括设置软件的基本数据结构和参数操作系统自身工作环境的初始化、定制操作系统的功能等,为操作系统的正常运行做好准备。BSP 随后会加载操作系统,将嵌入式系统的控制权转交给操作系统。操作系统继续完成余下的初始化操作。最后,操作系统为软件系统提供多任务的运行环境,创建应用程序的运行实例,并将控制权交给应用程序。
(2)HAL和BSP实例
①Nios II HAL
a.NiosIIHAL的介绍
NiosⅡ是 Altera 公司推出的 32 位哈佛结构用户可配置的通用RISC软核处理器,用于支持在 FPGA 器件上实现可编程片上系统(SOPC)。其最大优势是模块化的硬件结构,以及由此带来的灵活性和可裁剪性。
b.Nios II系统的软件结构
在NiosⅡ系统硬件之上就是硬件抽象层HAL。应用程序可以直接运行在 HAL 之上,也可以运行在 μC/OS-Ⅱ等嵌入式操作系统之上。
HAL系统库是NiosⅡ处理器系统的轻量级运行环境,提供了简单的设备驱动程序接口和HALAPI(应用程序接口)。
c.NiosIIHAL的特点
由于 SOPC 系统的软件和硬件都是借助集成的 SoPC开发平台统一配置开发的,所以软硬件开发工具之间的紧密集成使得特定硬件系统的 HAL可以由开发工具自动生成。当硬件开发工具产生了硬件系统配置之后,NiosⅡ软件开发工具可以生成与硬件配置相匹配的定制的 HAL 系统库。如果底层硬件做了改动,则 HAL 设备驱动配置会自动更新。应用程序和底层硬件的通信依靠统一的接口函数,底层硬件的改动对应用程序的代码没有影响。
d.HAL系统库提供的服务
第一,ANSIC标准库
HAL系统库集成了适用于嵌入式环境的开源 NewLib ANSI C标准库,向用户提供熟知的标准库函数支持。
第二,外设驱动
HAL,为每一个设备实例化一个驱动程序。应用程序使用设备驱动程序接口同底层硬件进行通信第
三,HALAPI
NiosⅡ上的应用软件可以通过 HAL接口函数直接访问外设、处理中断,或调用 HAL,提供的 alarm 等其他支持,从而将硬件细节抽象出来。
第四,系统初始化
在应用程序执行之前完成处理器和运行库环境的初始化任务。
第五,设备初始化
在应用程序运行之前完成每个设备的实例化和初始化。
在开发应用软件时,可以通过 HALAPI访问硬件资源,也可以调用ANSIC标准库实现相应的功能。而 ANSIC标准库中的函数也会调用 HALAPI。因此,用户程序可以通过printf()、fopen()、fwrite()等C标准库函数访问外设和文件,而无须直接调用 HALAPI。
②Windows Embedded Compact 7(WEC7)BSP
a.简介
Windows Embedded Compact7(WEC7)是微软公司 WindowsEmbedded CE(WinCE)的后续产品,是专门为小型网络设备设计的安全、组件化的实时操作系统。
b.软件结构
WEC7由三层构成。如图所示,最顶层是应用(application)和服务(service),这两个组件与下一层的操作系统内核(kernel)层交。在硬件和内核层之间的就是BSP。
c.BSP的组成
WEC7的BSP由引导加载程序(BootLoader)、OEM适配层(OAL)、设备驱动程序、配置文件和内核无关的传输层(KITL)组成。
第一,OAL层的功能是将与处理器体系结构无关的内核适配到特定处理器或硬件平台上,它包含支持定时器、存储管理、Cache 管理等硬件相关操作的代码,也为电源管理器提供支持,并实现中断服务程序。第二,KITL层是用于开发的宿主机(host)与运行 WEC7操作系统的设备之间的通信通道,它由 OAL调用用于系统调试时的信息传输。配置文件则用于创建操作系统的运行映像。
(3)BSP的开发和移植
①BSP 开发的特点
BSP既要与特定电路板相匹配,又必须按照操作系统所要求的接口方式为其提供服务。BSP是操作系统正常运行的前提,BSP程序的效率和稳定性直接影响整个系统的性能及稳定性。
②BSP 的调试步骤
a.最小系统的调试
最小系统通常包括处理器、RAM、bootROM 等最基本的系统部件,以及串口、网口等输入/输出端口。要借助在线仿真器或片上仿真器等调试设备辅助调试操作或者使用 LED 显示灯亮灭、串口显示等方法间接跟踪程序的执行流程。
b.外围设备驱动程序的调试
最小系统之外其他部件可以在此阶段进行调试。操作系统启动后,各种操作系统提供的调试工具都能使用的因此外围设备驱动程序的调试与应用程序调试的方式类似,可以借助网口或串口把目标机(嵌入式系统)与宿主机(调试主机)相连,进行交叉调试。
考点4 引导加载程序
(1)引导加载程序的概念和功能
(引导加载程序的介绍
引导加载程序(引导程序)bootoader是底层软件的一部分。嵌入式系统上电复位后首先运行引导加载程序,它负责系统的上电自检、硬件初始化、建立存储空间映射、配置系统参数、建立上层软件的运行环境,并加载和启动操作系统。
bootloader 依赖于具体的硬件结构。支持不同硬件结构的 bootloader程序有不同的版本。bootloader 移植是在特定硬件系统上进行操作系统移植的关键步骤。
②bootROM
与 bootloader 相关的一个术语是 bootROM(引导只读存储器)。一般而言,bootROM 是指用来存储 bootloade程序的非易失存储器,当前使用最多的类型是NORFlash ROM。在大多数嵌入式系统中,bootROM 内不仅存储bootoader 程序,还存储操作系统映像、应用程序代码和用户配置数据等信息,即使系统断电,信息也不会丢失。
③bootloader 程序的功能
不同的 bootloader 程序功能虽有差别,但都需要支持核心的操作系统引导(boot)和加载(load)功能。复杂的 bootloader 程序还支持简单的用户命令交互、设置操作系统启动参数、fash ROM 编程下载、读写内存、系统自检、硬件调试等监控程序(monitor)功能。
(2)嵌入式操作系统的加载方式
①在 ROM 中直接运行操作系统代码
传统的嵌入式系统较少配置外存储器,而是将操作系统和应用程序的映像预先烧录在ROM存储器中(通常是 NOR Fash ROM)。ROM存储器可以随机读出,不论是在 ROM 中在线执行代码,还是从 ROM 中读出信息,都不需要额外的驱动程序。嵌入式处理器复位后,执行 bootoader 代码,完成必要的硬件初始化等操作后,直接跳转到ROM存储器中操作系统入口函数处继续执行。
②在 RAM 中运行操作系统代码
a.执行过程
操作系统的映像和应用程序映像同样已经预先烧录到ROM中。不同的是,bootloader 代码在完成必要的硬件初始化等操作后,需把存放在 ROM 存储器中的操作系统和应用程序映像拷贝到 RAM 存储器中,然后跳转到RAM存储器中操作系统入口函数处继续执行。
b.执行条件
这种方式需要在嵌入式系统中配置较大的 RAM 存储器。在有的系统中,烧录到ROM 中的操作系统和应用程序代码是经过压缩的,因而在 bootloader 运行时需要把这些代码解压缩后再写入到 RAM 中。ROM 存储空间需求的降低是以增加解压缩时间为代价的。
c.优点
第一,由于 RAM 的访问速度通常要比 ROM 快很多,因而在这种方式中操作系统和应用程序的代码取指令的速度提高了。
第二,又因为 RAM 存储单元中的信息可以很方便地改写,故可以实现程序代码的动态修改,有利于采用更灵活的程序结构,方便程序调试。
③从外存储器加载操作系统代码运行
a.运行过程
在这种方式中,操作系统映像和应用程序映像预先存放在基于外存储器的文件系统中。为了加载操作系统bootloader 中必须要有访问外存储器所需的驱动程序。处理器复位后,执行bootROM 中存放的 bootloader 代码完成必要的硬件初始化等操作后,通过外存驱动程序读取外存储器中存放的操作系统和应用程序映像,并将其复制到RAM中,然后跳转到操作系统入口运行。
b.优点
由于外存容量较大,因而这种方式可以方便地在外存中存放不同版本的操作系统和应用程序映像,根据需要选择不同配置的软件运行。操作系统和应用程序的在线升级也更方便。
④从通信端口加载操作系统代码运行
可以从串口、以太网接口等通信端口加载操作系统和应用程序。与从外存加载相似,这种加载方式需要在bootoader中增加通信端口驱动程序,往往还要有相应的通信协议软件以支持通信端口上的数据传输。在这种方式下,嵌入式系统不能独立工作,需要有服务器提供相应的支持。
⑤四种加载方式的工作模式
a.启动加载模式
前面三种加载方式属于启动加载(bootoading)模式,这是嵌入式系统正常工作时使用的启动方式,bootloader从非易失存储介质中引导和加载操作系统代码。
b.下载模式
第四种加载方式则属于下载(downloading)模式,这是在调试或维护更新阶段使用的系统启动方式。在下载模式下,bootoader通过通信端口从调试主机(或服务器)上下载操作系统映像,暂存到 RAM 中,然后将其烧录到 fash ROM 等非易失性存储器中。工作于下载模式的 bootoader 通常会通过显示界面(例如串口通信界面)向用户提供简单的命令行交互机制。
c.两种模式的混合
一些功能强大的 bootloader 能同时文持这两种工作模式。典型的做法是:在进入启动加载模式之前延迟数秒钟并通过终端界面给出提示,如果用户按任意键则切换到下载模式,否则继续进行正常的启动加载。
(3)引导加载程序的执行过程
①bootloader 的第一阶段(stage1)
a.第一阶段的目的
第一阶段的目的是让嵌入式系统能正常运行起来,并为第二阶段以及随后操作系统内核的运行准备好基本的硬件环境。与处理器体系结构相关的硬件初始化和板级初始化等操作通常都在第一阶段完成。有些系统把这部分程序称为引导程序(bootstrap)或OEM启动代码。
b.第一阶段的代码特点及功能
第一阶段的代码通常用汇编语言实现,一方面可以提高代码的时空效率,另一方面可以更方便地实现对硬件的操作。一般而言,第一阶段的代码包含最基本的系统引导初始化功能。根据系统功能不同可能包括以下操作:
第一,关闭中断。在 bootloader 执行的全过程中一般不应响应任何中断请求,故可通过设置处理器内部的状态条件寄存器中的中断使能位屏蔽所有的中断请求。
第二,处理器内部的基本寄存器设置、系统基本参数设置、时钟初始化。
第三,存储器初始化。包括存储器控制器的设置、存储器自检、初始化 Cache 和存储器管理部件、关闭看门狗定时器等。
第四,初始化相关的硬件设备等。
第一阶段的代码通常还需要为高级语言程序的运行建立环境,第一阶段的功能完成后,程序将跳转到第二阶段的C程序入口点继续执行。
②bootloader 的第二阶段(stage 2)
a.第二阶段的功能
第二阶段的代码通常用C语言实现,以便实现操作系统加载的功能。具体包括建立系统配置信息交互通道和映像下载通道、校验内核映像、解压缩内核映像、复制内核映像到 RAM、为内核执行提供合适的上下文环境等。
b.第二阶段步骤
第一,进一步完成系统初始化任务。包括处理器初始化、板级初始化、中断初始化等。
第二,初始化本阶段要使用到的硬件设备。
第三,如果在RAM 中运行操作系统内核,则需将内核代码和根文件系统映像从ROM存储器复制到RAM存储器。
第四,向操作系统内核传递启动参数。例如,将系统内存的具体安排、终端串口的波特率、数据位位数等参数以特定的方式传递给操作系统内核。
第五,调用内核代码。
(4)U-Boot 支持的主要功能
③U-Boot 移植
步骤:
a.从 U-Boot 源码发布平台获得官方发布的最新版本 U-Boot 源码并解