2. BSP(板级支持包)基础

2.1 BSP 定义与核心职责

BSP(Board Support Package,板级支持包)是介于 VxWorks 内核与目标硬件平台之间的软件层。它封装了特定硬件平台的初始化、驱动和配置细节,为上层 RTOS 提供统一的硬件访问接口。BSP 的核心目标是实现操作系统的硬件无关性,使得同一份 VxWorks 内核镜像可以在不同架构的板卡上运行,只需更换对应的 BSP。

BSP 的核心职责:
  • 硬件初始化: CPU 复位向量、MMU/Cache、内存控制器、中断控制器、定时器、串口等最小系统初始化。
  • 设备驱动 stub: 提供时钟、定时器、中断、串口、以太网等基础外设的底层驱动例程。
  • 系统配置封装: 内存映射表、中断向量表、I/O 地址空间、时钟频率等硬件参数的静态定义。
  • 启动加载: 从 ROM/Flash 加载 VxWorks 内核到 RAM,并跳转到内核入口。
关键概念: BSP 不是设备驱动框架,而是“板级”的适配层。一个 BSP 可以包含多个设备驱动,但驱动本身属于 I/O 系统;BSP 负责在系统启动阶段将这些驱动与硬件实例绑定。

2.2 BSP 与硬件抽象层(HAL)的关系

在 VxWorks 7 及后续版本中,BSP 与 HAL(Hardware Abstraction Layer)共同构成硬件适配体系。两者分工明确,层次清晰:

维度 BSP(板级支持包) HAL(硬件抽象层)
抽象粒度 板级(特定 PCB、外设布局) 架构级(CPU 核、中断模型、Cache 模型)
主要职责 板级初始化、外设寄存器映射、时钟源选择、Flash 分区 上下文切换、异常/中断入口/出口、MMU 页表操作、Cache 刷新指令
可移植性 同一 CPU 架构下不同板卡需更换 BSP 同一 CPU 架构下所有板卡共享同一 HAL
代码位置 target/config/bspname/ target/h/arch/archName/
典型文件 sysLib.c, config.h, romInit.s archLib.c, excArchLib.c, cacheArchLib.c

下图展示了 BSP 与 HAL 在 VxWorks 软件栈中的位置关系:

VxWorks 软件栈:BSP 与 HAL 层次关系 用户应用程序 / POSIX API VxWorks 内核(任务调度、IPC、文件系统、网络协议栈) I/O 系统 | 设备驱动框架 | 内存管理 BSP(板级支持包) sysLib.c / config.h / romInit.s 板级初始化 / 外设寄存器映射 HAL(硬件抽象层) archLib.c / excArchLib.c 上下文切换 / 中断入口 / Cache 操作 目标硬件平台(CPU + SoC + 外设) ARM Cortex-A / x86 / PowerPC / RISC-V BSP 调用 HAL 接口 sysHwInit → HAL 中断/定时器
常见误区: 初学者常将 BSP 与 HAL 混为一谈。实际开发中,BSP 开发者需要调用 HAL 提供的架构级接口(如 intContext()、cacheLib),但 HAL 本身不包含任何板级外设寄存器地址。修改板级外设映射只需改 BSP,无需动 HAL。

2.3 BSP 在 VxWorks 启动流程中的作用

VxWorks 的启动流程可分为三个阶段,BSP 在每个阶段都承担关键角色:

  1. ROM 阶段(预内核): CPU 复位后执行的第一段代码,位于 romInit.s。BSP 负责设置 CPU 模式、关闭中断、初始化栈指针,并跳转到 romStart()。
  2. ROM 阶段(解压缩与重定位): romStart() 将 VxWorks 内核镜像从 Flash 复制到 RAM,必要时解压缩。BSP 在此阶段完成内存控制器、串口等最小系统初始化,以便输出调试信息。
  3. RAM 阶段(内核初始化): 跳转到 RAM 中的 sysInit(),随后进入 usrInit() → usrKernelInit() → sysHwInit()。BSP 的 sysHwInit() 完成所有板级外设的初始化,包括时钟定时器和中断控制器。

下表总结了 BSP 在启动各阶段的关键文件与职责:

启动阶段 入口函数 BSP 关键文件 BSP 核心动作
ROM 入口 _romInit() romInit.s 设置 CPU 模式、栈指针、关闭中断
ROM 解压缩 romStart() romStart.c 初始化内存控制器、串口、复制/解压镜像
RAM 初始化 sysInit() sysALib.s 设置 MMU/Cache、中断向量表基址
内核启动 usrInit() usrConfig.c 调用 BSP 的 sysHwInit() 初始化外设
系统就绪 usrRoot() configAll.h 启动 tRootTask,挂载文件系统,使能中断

下图以流程图形式展示 BSP 主导的 VxWorks 启动序列:

VxWorks 启动流程:BSP 主导阶段 CPU 复位 → _romInit() BSP: 设置CPU模式/栈/关中断 romStart() BSP: 初始化内存/串口/解压镜像 sysInit() BSP: MMU/Cache/中断向量表 usrInit() → kernelInit() 内核对象/任务调度器初始化 sysHwInit() BSP: 时钟/定时器/中断控制器初始化 usrRoot() → 系统就绪 使能中断 / 启动网络 / 挂载文件系统 BSP 关键时间点 • 串口输出最早可用 • 时钟/定时器初始化 • 中断控制器使能
性能调优切入点: 时钟定时器与中断响应性能的调优工作主要集中在 sysHwInit() 阶段。BSP 开发者在此处配置系统时钟节拍(tick)、定时器工作模式(周期/单次)、中断优先级和嵌套策略。这些配置直接影响后续所有实时任务的调度精度和中断延迟。

2.4 BSP 文件结构速览

一个典型的 VxWorks BSP 目录包含以下核心文件,开发者应熟悉其功能定位:

文件/目录 功能描述 与时钟/中断相关性
romInit.s CPU 复位入口汇编代码 低(仅关中断)
sysALib.s 系统汇编例程(中断向量表安装) 高(中断向量基址)
sysLib.c 板级初始化主文件(含 sysHwInit()) 高(时钟/定时器初始化)
config.h 系统配置宏定义(时钟频率、中断栈大小) 高(SYSCLK_RATE、ISR_STACK_SIZE)
sysSerial.c 串口驱动(调试输出) 低
sysTffs.c Flash 文件系统驱动 低
Makefile 编译规则与依赖 中(决定哪些驱动被编译)
BSP 开发黄金法则:
  • 不要修改 HAL 层代码来适配板级差异——这是 BSP 的职责。
  • 时钟定时器的初始化顺序必须在中断控制器使能之前完成,避免未初始化的定时器触发意外中断。
  • 所有硬件寄存器地址、中断号、时钟源选择必须在 config.h 或 sysLib.c 中以宏定义形式集中管理,便于后续调优。