STM32嵌入式系统设计与应用
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.6.2 软件层次

嵌入式系统软件可以是直接面向硬件的裸机程序开发,也可以是基于操作系统的嵌入式程序开发。当嵌入式系统应用功能简单时,硬件平台结构也相对简单,这时可以使用裸机程序开发方式,不仅能够降低系统复杂度,还能够实现较好的系统实时性,但是,要求程序设计人员对硬件构造和原理比较熟悉。如果嵌入式系统应用较复杂,相应的硬件平台结构也相对复杂,这时可能就需要一个嵌入式操作系统来管理和调度内存、多任务、周边资源等。在进行基于操作系统的嵌入式程序设计开发时,操作系统通过对驱动程序的管理,将硬件各组成部分抽象成一系列API函数,这样在编写应用程序时,程序设计人员就可以减少对硬件细节的关注,只专注于程序设计,从而减轻程序设计人员的工作负担。

嵌入式系统软件结构一般包含3个层面:设备驱动层、OS层、应用层(包括硬件抽象层、应用程序)。由于嵌入式系统应用的多样性,需要根据不同的硬件电路和嵌入式系统应用特点,对软件部分进行裁剪。现代高性能嵌入式系统的应用越来越广泛,嵌入式操作系统的使用成为必然发展趋势。

1.设备驱动层

设备驱动层一般由板级支持包和驱动程序组成,是嵌入式系统中不可或缺的部分,设备驱动层的作用是为上层程序提供外围设备的操作接口,并且实现设备的驱动程序。上层程序不必考虑设备内部的实现细节,只需调用设备驱动的操作接口即可。

应用程序运行在嵌入式操作系统上,利用嵌入式操作系统提供的接口完成特定功能。嵌入式操作系统具有应用的任务调度和控制等核心功能。根据不同的应用,硬件平台所具备的功能各不相同,而且各平台所使用的硬件也不相同,具有复杂的多样性,因此,针对不同硬件平台,进行嵌入式操作系统的移植是极为耗时的工作,为简化不同硬件平台间操作系统的移植问题,在嵌入式操作系统和应用程序之间增加了硬件抽象层(Hardware Abstraction Layer, HAL)。有了硬件抽象层,嵌入式操作系统和应用程序就不需要关心底层的硬件平台信息,内核与硬件相关的代码也不必因硬件的不同而修改,只要硬件抽象层能够提供必需的服务即可,从而屏蔽底层硬件,方便进行系统的移植。通常硬件抽象层是以板级支持包的形式来完成对具体硬件的操作的。

(1)板级支持包 板级支持包(Board Support Package, BSP)位于主板硬件层和嵌入式操作系统中驱动程序之间。BSP是所有与硬件相关的代码体的集合,为嵌入式操作系统的正常运行提供了最基本、最原始的硬件操作的软件模块,BSP和嵌入式操作系统息息相关,前者为上层的驱动程序提供了访问硬件的寄存器的函数包,使之能够更好地运行。

BSP具有以下三大功能:

1)系统启动时的硬件初始化。例如,对系统内存、寄存器及设备的中断进行设置。这是比较系统化的工作,硬件启动初始化后要根据嵌入式开发所选的CPU类型、硬件及嵌入式操作系统的初始化等多方面决定BSP应实现什么功能。

2)为嵌入式操作系统访问硬件驱动程序提供支持。驱动程序经常需要访问硬件的寄存器,如果整个系统为统一编址,那么开发人员可直接在驱动程序中用C语言的函数访问硬件的寄存器。但是,如果系统为单独编址,那么C语言将不能直接访问硬件的寄存器,只有汇编语言编写的函数才能对硬件的寄存器进行访问。BSP为上层的驱动程序提供了访问硬件的寄存器时所需的函数包。

3)集成硬件相关和硬件无关的嵌入式操作系统所需的软件模块。BSP是相对于嵌入式操作系统而言的,不同的嵌入式操作系统对应不同定义形式的BSP。例如,VxWorks的BSP和Linux的BSP相对于某一CPU来说尽管实现的功能一样,但是写法和接口定义是完全不同的,所以编写BSP一定要按照该系统BSP的定义形式(BSP的编程过程大多数是在某一个成型的BSP模板上进行修改的),这样才能与上层嵌入式操作系统保持正确的接口,为上层嵌入式操作系统提供良好的支持。

(2)驱动程序 只有安装了驱动程序,嵌入式操作系统才能操作硬件平台,驱动程序控制嵌入式操作系统和硬件之间的交互。驱动程序提供一组嵌入式操作系统可理解的抽象接口函数,例如,设备初始化、打开、关闭、发送和接收等。一般而言,驱动程序和设备的控制芯片有关。驱动程序运行在高特权级的处理器环境中,可以直接对硬件进行操作,但正因为如此,任何一个设备驱动程序的错误都可能导致嵌入式操作系统的崩溃,因此好的驱动程序需要有完备的错误处理函数。

2.OS层

嵌入式操作系统是一种支持嵌入式系统应用的操作系统软件,是嵌入式系统的重要组成部分。嵌入式操作系统通常包括与硬件相关的底层驱动软件、系统内核、设备驱动接口、通信协议、图形界面和标准化浏览器等。嵌入式操作系统具有通用操作系统的基本特点,例如,能有效管理越来越复杂的系统资源;能把硬件虚拟化,使开发人员从繁忙的驱动程序移植和维护中解脱出来;能提供库函数、驱动程序、工具集及应用程序。与通用操作系统相比较,嵌入式操作系统在系统实时高效性、硬件的相关依赖性、软件固态化及应用的专用性等方面具有较为突出的特点。嵌入式操作系统具有通用操作系统的基本特点,能够有效管理复杂的系统资源,并且把硬件虚拟化。

在一般情况下,嵌入式开发操作系统可以分为两类,一类是面向控制、通信等领域的嵌入式实时操作系统(RTOS),如VxWorks、PSOS、QNX、μC/OS-Ⅱ、RT-Thread、FreeRTOS等;另一类是面向消费电子产品的嵌入式非实时操作系统,如Linux、Android、iOS等,这类产品包括智能手机、机顶盒、电子书等。

3.应用层

(1)硬件抽象层 硬件抽象层本质上就是一组对硬件进行操作的API,是对硬件功能抽象的结果。硬件抽象层通过API为嵌入式操作系统和应用程序提供服务。但是,在Windows和Linux操作系统下,硬件抽象层的定义是不同的。

Windows操作系统下的硬件抽象层定义:位于嵌入式操作系统的最底层,直接操作硬件,隔离与硬件相关的信息,为上层的嵌入式操作系统和驱动程序提供一个统一的接口,起到对硬件的抽象作用。硬件抽象层简化了驱动程序的编写,使嵌入式操作系统具有更好的可移植性。

Linux操作系统下的硬件抽象层定义:位于嵌入式操作系统和驱动程序之上,是一个运行在用户空间中的服务程序。

Linux和所有的UNIX一样,习惯用文件来定义抽象设备,任何设备都可以是一个文件,如/dev/mouse是鼠标的设备文件名。这种方法看起来不错,每个设备都有统一的形式,但使用起来并没有那么容易,设备文件名没有规范,用户从简单的一个文件名,无法得知它是什么设备,具有什么特性。形式不一的设备文件,让设备的管理和应用程序的开发变得很麻烦,所以有必要提供一个硬件抽象层,来为上层应用程序提供一个统一的接口,Linux的硬件抽象层就这样应运而生了。

(2)应用程序 应用程序是为完成某项或某几项特定任务而被开发运行于嵌入式操作系统之上的程序,如文件操作、图形操作等。在嵌入式操作系统上编写应用程序一般需要一些应用程序接口。应用程序接口(Application Programming Interface, API)又称为应用编程接口,是软件系统不同部分衔接的约定。应用程序接口的设计十分重要,良好的接口设计可以降低系统各部分的相互依赖性,提高组成单元的内聚性,降低组成单元间的耦合程度,从而提高系统的维护性和扩展性。

根据嵌入式系统应用需求,应用程序通过调用嵌入式操作系统的API函数操作系统硬件,从而实现应用需求。一般而言,嵌入式应用程序建立在主任务基础之上,可以是多任务的,通过嵌入式操作系统管理工具(信号量、队列等)实现任务间通信和管理,进而实现应用需要的特定功能。