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中的地址与参数,任何一方改动,另一方都可能需要同步调整。
五、实际配置时的检查顺序
面对一块新板,建议按以下顺序核对,避免“改了config.h却忘了Makefile”或“启动地址与内存布局冲突”:
- 确认
config.h中LOCAL_MEM_LOCAL_ADRS与LOCAL_MEM_SIZE是否与单板实际内存一致。 - 确认
ROM_BASE_ADRS、ROM_SIZE与Flash实际映射一致,且ROM_TEXT_ADRS留出足够头部空间。 - 确认
RAM_LOW_ADRS与RAM_HIGH_ADRS不重叠,且RAM_HIGH_ADRS位于可用RAM范围内。 - 检查
Makefile中CPU、TOOL是否与工具链匹配,MACH_EXTRA是否包含所有自定义源文件。 - 编译后查看
vxWorks与bootrom.bin是否生成,并用size或objdump确认入口地址与ROM_TEXT_ADRS一致。
CONSOLE_BAUD_RATE与CONSOLE_TTY是否与硬件一致;若系统在解压后跑飞,优先核对RAM_HIGH_ADRS是否落在有效RAM区间。
掌握BSP工程结构,本质上是在建立一张“配置—编译—启动—适配”的映射图。config.h是参数源,Makefile是构建规则,启动代码是执行起点,硬件适配层是功能落地。四者对齐,BSP才能稳定支撑VxWorks在目标板上运行。