3. BSP工程结构导览

BSP(Board Support Package)是VxWorks从“通用内核”落到“具体单板”的桥梁。理解BSP工程结构,核心不是记住目录名字,而是搞清楚三件事:哪些文件描述硬件、哪些文件决定编译与裁剪、启动代码在什么时刻调用硬件适配层。本节以常见的wrSbc8548类PowerPC BSP为例,说明其组织方式与关键配置项,示例参数仅用于教学说明。

一、BSP目录组织:按“职责”而非“文件类型”划分

一个典型BSP位于$WIND_BASE/target/config/<bspName>/下,其目录与文件大致按职责分层:

  • 顶层源码:sysLib.c、sysSerial.c、sysNet.c、sysTimer.c等,构成硬件适配层主体,向内核提供统一接口。
  • 启动代码:romInit.s(汇编,上电入口)、romStart.c(C语言,搬运与解压)、sysALib.s(系统级汇编例程)。
  • 配置头文件:config.h(BSP级参数)、configAll.h(全系统默认值)、bsp.h(板级寄存器与地址宏)。
  • 构建文件:Makefile与Makefile.inc,决定编译哪些文件、生成什么镜像。
  • 子目录:hwconfig/(硬件配置工具)、bootrom/(引导镜像)、vxworks/(系统镜像)、archive/(归档)。

这种划分的意义在于:启动代码负责“把系统拉起来”,硬件适配层负责“让系统认识板子”,config.h与Makefile负责“决定编译出什么”。三者通过统一的宏和函数接口耦合。

二、config.h:BSP级参数的集中入口

config.h是BSP的“参数面板”,它通常先包含configAll.h获得默认值,再按本板情况覆盖。关键配置项可分为几类:

类别典型宏作用
内存布局LOCAL_MEM_LOCAL_ADRS、LOCAL_MEM_SIZE、RAM_LOW_ADRS、RAM_HIGH_ADRS定义RAM起始、大小及镜像加载/运行地址
启动参数ROM_BASE_ADRS、ROM_SIZE、ROM_TEXT_ADRS定义BootROM在Flash中的位置与大小
串口控制台CONSOLE_TTY、CONSOLE_BAUD_RATE指定控制台串口与波特率
组件裁剪INCLUDE_*系列决定网络、文件系统、调试等组件是否编入
中断与时钟INT_NUM_IRQ0、SYS_CLK_RATE中断向量基址与系统时钟频率

例如,若单板DDR2容量为256MB、起始地址0x00000000,BootROM位于Flash起始0xFFF00000,则常见写法为:

#define LOCAL_MEM_LOCAL_ADRS   0x00000000
#define LOCAL_MEM_SIZE          0x10000000   /* 256 MB */
#define ROM_BASE_ADRS           0xFFF00000
#define ROM_SIZE                0x00100000   /* 1 MB */
#define ROM_TEXT_ADRS           (ROM_BASE_ADRS + 0x100)
#define RAM_LOW_ADRS            0x00010000
#define RAM_HIGH_ADRS           0x01000000
#define CONSOLE_BAUD_RATE       115200

这些宏并非孤立存在:romInit.s会用ROM_TEXT_ADRS确定上电入口,romStart.c会用RAM_HIGH_ADRS决定解压目标,sysLib.c会用LOCAL_MEM_SIZE初始化内存池。改错一个,启动链就会在对应环节断裂。

三、Makefile:决定“编什么、怎么编、生成什么”

BSP的Makefile通常包含Makefile.inc,并定义MACH_EXTRA、MACH_EXTRA_OBJS等变量。关键配置项包括:

  • CPU与TOOL:指定处理器架构与工具链,如CPU = PPC32、TOOL = gnu。
  • EXTRA_DEFINE:向编译命令追加宏,例如-DINCLUDE_DEBUG。
  • MACH_EXTRA:追加BSP私有源文件,如自定义的myBoardInit.c。
  • vxWorks与bootrom目标:分别生成系统镜像与引导镜像。

一个常见的追加写法如下,用于把自定义硬件初始化文件编入:

MACH_EXTRA = myBoardInit.o
EXTRA_DEFINE = -DINCLUDE_MY_BOARD_FEATURE

执行make vxWorks时,构建系统会先编译BSP源码,再链接内核与组件,最终生成vxWorks;执行make bootrom则生成bootrom.bin。因此,Makefile是“配置意图”到“可烧录镜像”的转换器。

四、硬件适配层与启动代码的关联

启动代码与硬件适配层并非两个独立模块,而是通过调用时序和共享宏紧密关联。上电后,romInit.s先完成最底层的CPU初始化(如关闭看门狗、设置初始栈),随后跳转到romStart.c;romStart.c根据config.h中的地址宏,把ROM中的压缩镜像搬运到RAM并解压,最后跳转到sysInit()。而sysInit()正是sysLib.c提供的硬件适配层入口,它依次初始化内存、时钟、串口、中断控制器等。

换句话说:启动代码负责“把控制权交给系统”,硬件适配层负责“让系统能操作硬件”。两者共享config.h中的地址与参数,任何一方改动,另一方都可能需要同步调整。

BSP工程结构与启动链关联示意 config.h 内存布局 / 启动地址 / 控制台 / 组件裁剪 启动代码 romInit.s(汇编入口) romStart.c(搬运/解压) sysALib.s(系统汇编例程) 职责:把系统拉起来 硬件适配层 sysLib.c(sysInit) sysSerial.c / sysNet.c sysTimer.c / bsp.h 职责:让系统认识板子 Makefile / Makefile.inc CPU / TOOL / MACH_EXTRA / EXTRA_DEFINE 生成 vxWorks 与 bootrom 地址宏 参数宏 跳转 sysInit() 编译/链接 编译/链接 config.h 提供参数 → 启动代码与适配层共享 → Makefile 决定编译产物

五、实际配置时的检查顺序

面对一块新板,建议按以下顺序核对,避免“改了config.h却忘了Makefile”或“启动地址与内存布局冲突”:

  1. 确认config.h中LOCAL_MEM_LOCAL_ADRS与LOCAL_MEM_SIZE是否与单板实际内存一致。
  2. 确认ROM_BASE_ADRS、ROM_SIZE与Flash实际映射一致,且ROM_TEXT_ADRS留出足够头部空间。
  3. 确认RAM_LOW_ADRS与RAM_HIGH_ADRS不重叠,且RAM_HIGH_ADRS位于可用RAM范围内。
  4. 检查Makefile中CPU、TOOL是否与工具链匹配,MACH_EXTRA是否包含所有自定义源文件。
  5. 编译后查看vxWorks与bootrom.bin是否生成,并用size或objdump确认入口地址与ROM_TEXT_ADRS一致。
提示:若启动后串口无输出,优先检查CONSOLE_BAUD_RATE与CONSOLE_TTY是否与硬件一致;若系统在解压后跑飞,优先核对RAM_HIGH_ADRS是否落在有效RAM区间。

掌握BSP工程结构,本质上是在建立一张“配置—编译—启动—适配”的映射图。config.h是参数源,Makefile是构建规则,启动代码是执行起点,硬件适配层是功能落地。四者对齐,BSP才能稳定支撑VxWorks在目标板上运行。