嵌入式软件架构层次

软件层次架构

在嵌入式系统开发中,常见的软件架构会把代码分为多个”层”(Layer),以便于管理、移植和维护。不同项目可能会有不同的划分,但主流嵌入式系统常见的层主要有:

应用层中间件层操作系统层驱动层/硬件抽象层硬件层

以下是对各层的详细介绍

应用层

介绍应用层(Application layer),有时也叫业务层,一般是实现产品的业务逻辑和最终功能,由开发者根据具体需求编写,比如界面、控制逻辑、协议处理等。

包含内容

  • 主程序入口(如main函数、app_main)
  • 各种业务模块(如任务管理、UI界面、页面管理、控制流程)
  • 设备/算法应用(如温度采集、数据上传、蓝牙通信等)
  • 通常只通过中间件或驱动API访问下层,不直接操作硬件。

典型文件/模块

  • main.c、app.c、tasks.c、ui_app.c、page_manager.c等

中间件层

介绍中间件(Middleware),中间件层是为应用层提供通用功能的支撑库或协议栈,起到“工具箱”作用,帮助应用层快速实现复杂功能。常见的中间件为为协议栈文件系统GUI库音频库等。

包含内容

  • RTOS(如FreeRTOS、CMSIS-OS等,部分项目归为中间件)
  • 网络协议栈(如LwIP、MQTT、HTTP)
  • 文件系统(如FATFS、LittleFS等)
  • 图形库(如LVGL、uGFX)
  • 通信协议栈(如BLE/WIFI/USB/Modbus等)

典型文件/模块

  • freertos.c、cmsis_os.c、lwip.c、fatfs.c、lvgl.c

操作系统层

介绍操作系统层(OS层),在项目中会把它归于中间件的部分。主要就是提供多任务调度、时间管理、线程/任务通信、同步机制等操作系统功能。

包含的内容

  • 任务/线程管理
  • 信号量、消息队列、定时器、互斥锁
  • 系统tick、内存管理

典型文件/模块

  • FreeRTOS、RT-Thread、Zephyr、CMSIS-OS等相关代码(通常中间件目录下)

板级支持包

介绍:板级支持包(BSP),是针对具体开发板/硬件平台的初始化,也包含设备驱动程序(存储设备显示器传感器等)。

BSP严格来说不是一个层,但是一般包含HAL层/Driver层,,通常与HAL层/Driver层放到一起。

包含内容

  • 硬件平台的初始化,如CPU主频时钟引脚映射启动文件等。以及启动操作系统的引导程序(Bootloader)。

  • 板级外设初始化,如lcd、key、sensor等的初始化

  • 设备驱动程序,是指让上层能通过API直接操作板载各种芯片、模块、外设的代码,这部分程序和本板强相关。如传感器相关的操作等

典型文件/模块

  • lcd.c、key.c、mpu6050.c、aht21.c、board_init.c、system_stm32f4xx.c

驱动层/硬件抽象层

介绍驱动层(Driver)/硬件抽象层(HAL),直接或间接对硬件资源进行操作,封装寄存器操作,向上提供通用API。

包含内容

  • HAL库(如STM32 HAL、esp-idf的gpio、uart等API)
  • 低层驱动(LL库,Low Layer,直接操作寄存器)
  • 驱动接口(如I2C、SPI、UART、ADC、PWM、GPIO初始化与读写函数)
  • 一些传感器/外设的基础驱动(如iic_hal.c、spi_hal.c)

典型文件/模块

  • stm32f4xx_hal_gpio.c、hal_uart.c、driver/gpio.c、driver/uart.c

硬件层

介绍:硬件层(Hardware layer),实际的物理硬件,包括单片机本身、各种外设芯片、电路板、传感器、显示屏、无线模块等。

包含内容

  • MCU(如STM32、ESP32、NXP等)
  • 板载传感器、外设芯片
  • 电子元器件、电路板设计实现

典型文件/模块

  • 无实际代码文件,对应为原理图、PCB、芯片数据手册等

层级合并

  1. RTOS一般可归为中间件或单独一层,视项目管理而定。
  2. BSP/Driver/HAL常合并,如果项目较小或板载驱动和HAL紧密结合,直接放在Drivers或BSP文件夹。
  3. 很小的项目可能只有应用+驱动+硬件三层结构

那么我们从上到下就5层:应用层中间件OS层BSP(包括HAL、Driver)、硬件层

img

Driver、BSP、HAL层的关系

驱动(Driver)

驱动(Driver),就是把硬件的底层细节寄存器时序等用软件代码封装起来,直接通过寄存器与硬件交互,负责初始化、读写、控制硬件等,为上层提供标准接口。

我们最底层的驱动是:I2C外设驱动、SPI外设驱动、UART外设驱动、GPIO驱动等,通过对寄存器进行操作进行初始化和基本通信。因为是操作寄存器,在HAL层之下,HAL层是对其的封装。

然后是具体芯片的驱动,比如:传感器芯片(mpu6050、AHT20等)、存储芯片(EEPROM芯片等)、LCD屏幕等,我们需要调用HAL库的I2C、SPI外设等与其完成通信。这就相当于对HAL层的应用,在HAL层之上,一般由用户来完成。

驱动既可以是单片机外设的底层寄存器操作,也可以是对复杂外设协议的实现。

硬件抽象层HAL

HAL是介于底层硬件和上层软件之间的一层抽象层,用于隐藏底层寄存器的操作细节,提供统一的API。可以对不同芯片进行适配。

主要是对芯片固定的片上资源(各外设)的抽象层接口函数,例如GPIO、UART、I2C、SPI等。可以调用这些API直接对外设操作,而不用知道其底层细节。

因为HAL层包含底层驱动,所以通常与最底层的驱动层(Driver)合并为Driver层

BSP

BSP-板级支持包,是用于特定硬件平台/芯片的一组软件组件,通常包括启动代码驱动程序HAL等。确保操作系统能够正确识别和使用硬件功能(跑起来)。

启动代码:负责系统上电后的硬件初始化,如设置时钟、初始化存储器等。

硬件抽象层(HAL):提供硬件接口的抽象层。

设备驱动:针对特定硬件的驱动程序。

所以BSP则更像是一个包裹/集合(package),它打包了启动代码、硬件初始化、驱动HAL等所有让“这块板子能跑起来”的内容。

联系

驱动与HAL: HAL可以调用底层驱动程序实现硬件操作,驱动实现硬件的具体操作,HAL则提供更高层次的抽象接口。

BSP与驱动: BSP包含了驱动程序,驱动是BSP中的一部分,通过BSP,操作系统可以调用驱动程序来控制硬件。

BSP与HAL: BSP包含HAL,HAL是BSP的一部分,提供硬件访问的抽象接口。

这些关系就造成了在分层时我们通常将 HAL与驱动层分到一起, 如果有BSP的话,因为BSP包含了HAL与驱动,所以我们统一把他们分到一起叫做:DriverBSP

如图是把BSP放在Driver中架构图:

image-20250728195537458

北京联盛德微电子芯片原厂的芯片架构:将Driver放在BSP中

45880747e079737b0ff72442cf9576a

这两种方法并没有绝对对错,关键看你的项目需求和团队习惯。主流做法是Driver层包含BSP,建议优先采用这种分法。

架构图

这是我在北京联盛德微电子芯片原厂实习时了解到的的芯片架构,以后产品开发的时候绘制软件架构图的时候可以参考一下:

45880747e079737b0ff72442cf9576a