跳过正文

VxWorks BSP 开发:移植自定义 ARM 开发板

VxWorks BSP ARM 开发板 板级支持包 嵌入式系统 VxWorks 7 设备树 MMU 驱动程序开发
目录

在生产项目中使用 VxWorks 7 时,最关键的任务之一是 BSP (板级支持包) 开发。BSP 负责将内核适配到您的自定义 ARM 硬件上,确保引导启动、内存映射和外设初始化都能正确执行。

在本文中,我们提供了一个详尽的分步指南,用于将 VxWorks 移植到自定义 ARM 开发板。无论您使用的是 Cortex-A8、Cortex-A53 还是多核 SoC,本指南都将帮助您完成开发板的适配工作。


什么是 VxWorks BSP?
#

板级支持包 (Board Support Package) 是操作系统与硬件之间的粘合剂。它提供:

  • 引导和初始化代码
  • MMU 设置和缓存策略
  • 设备树和硬件描述
  • 特定于开发板的驱动程序 (UART, Ethernet, I2C, SPI, GPIO)
  • 系统库 (sysLib.c, sysHwInit.c)
  • 内核配置参数

没有 BSP,VxWorks 就无法在您的开发板上运行。有了一个设计良好的 BSP,操作系统才能可靠地启动、运行,并充分利用所有硬件功能。


步骤 1:准备开发环境
#

  1. 安装工具链: 使用 Wind River Workbench 或 ARM 交叉编译器(ARMv7 使用 arm-wrs-linux-gnueabi-gcc,ARMv8 使用 aarch64-wrs-linux-gcc)。

  2. 设置源码树: VxWorks BSP 位于以下路径:

    $WIND_HOME/vxworks-7/bsps/arm/<board_name>/
    
  3. 收集硬件文档

    • SoC 参考手册
    • 开发板原理图
    • 现有的 U-Boot/Linux 设备树(供参考)

步骤 2:BSP 目录结构
#

一个典型的 ARM BSP 目录结构如下:

board/
├── Makefile          # BSP 构建规则
├── config.h          # 内核和开发板配置
├── sysHwInit.c       # 硬件初始化
├── sysLib.c          # 板级系统调用
├── sysClk.c          # 时钟/定时器支持
├── sysSerial.c       # UART/控制台驱动
├── fdt/              # 扁平设备树文件
├── linkscript.ld     # 内存映射
└── drivers/          # 自定义设备驱动

📌 提示:从一个相似的参考 BSP(例如 ARMv8 Cortex-A53)开始,复制并根据您的硬件进行定制。


步骤 3:引导加载程序和启动代码
#

大多数 ARM 开发板使用 U-Boot。BSP 必须定义:

  • 链接器脚本 (Linker Script):定义内存区域(DDR, SRAM, 外设)。
  • 启动汇编代码:设置异常向量、堆栈、MMU 和缓存。
  • sysHwInit():在内核启动前运行。

内存映射示例 (linkscript.ld):

MEMORY
{
    SRAM (rwx) : ORIGIN = 0x00000000, LENGTH = 256K
    DDR  (rwx) : ORIGIN = 0x80000000, LENGTH = 1G
}

SECTIONS
{
    .text : { *(.text*) } > DDR
    .data : { *(.data*) } > DDR
    .bss  : { *(.bss*)  } > DDR
}

硬件初始化示例 (sysHwInit.c):

void sysHwInit(void)
{
    /* 为 DDR 和外设设置 MMU */
    armMmuInit();

    /* 初始化系统时钟 */
    sysClkInit();

    /* 使能 UART 控制台 */
    sysSerialHwInit();

    /* 使能中断 */
    intLibInit();
}

步骤 4:设备树 (FDT)
#

VxWorks 使用扁平设备树 (Flattened Device Tree, FDT) 来描述硬件。

示例 (custom-board.dts):

/ {
    model = "vendor,custom-arm-board";
    compatible = "vendor,custom";

    memory@80000000 {
        device_type = "memory";
        reg = <0x80000000 0x40000000>; /* 1GB DDR */
    };

    soc {
        uart0: serial@101f1000 {
            compatible = "arm,pl011";
            reg = <0x101f1000 0x1000>;
            clock-frequency = <24000000>;
        };

        eth0: ethernet@10100000 {
            compatible = "snps,designware-eth";
            reg = <0x10100000 0x2000>;
        };
    };
};

📌 专业提示:如果已有 Linux DTS 文件,可以从它开始,然后精简并适配给 VxWorks 使用。


步骤 5:编写自定义驱动程序
#

并非所有外设都有现成的支持。对自定义设备,请使用 VxBus 驱动模型

UART 驱动示例 (sysSerial.c):

STATUS sysSerialHwInit(void)
{
    UART_REG->LCR = 0x3;   /* 8 位数据位, 无校验, 1 位停止位 */
    UART_REG->DLL = 13;    /* 波特率除数 */
    UART_REG->IER = 0x1;   /* 使能接收中断 */
    return OK;
}

📌 驱动集成:

  • 使用 VxBus 注册设备。
  • 通过内核 Shell 进行测试 (-> printf("Hello from UART\n"))。

步骤 6:MMU 和缓存设置
#

MMU (内存管理单元) 确保内存属性正确配置。属性示例:

  • DDR → 可缓存 (Cacheable), 可缓冲 (Bufferable)
  • 外设 I/O → 强序 (Strongly-Ordered), 不可缓存 (Non-Cacheable)
  • 引导 ROM → 只读 (Read-Only)

sysLib.c 中配置:

VM_STATE sysPhysMemDesc[] = {
    { 0x80000000, 0x80000000, 0x40000000, VM_STATE_CACHEABLE },
    { 0x10100000, 0x10100000, 0x00100000, VM_STATE_IO }
};

步骤 7:测试与调试
#

  1. 引导测试 通过 U-Boot 中的 TFTP 加载 VxWorks 镜像:

    => tftpboot 0x80000000 vxWorks
    => go 0x80000000
    
  2. 控制台测试 验证 UART 输出:

    VxWorks Bootrom 7.x
    >
    
  3. 外设测试

    • UART:发送/接收测试
    • 以太网:ifconfig, ping
    • 定时器:检查系统时钟节拍
  4. 调试工具

    • Workbench Debugger:加载符号表,设置断点
    • JTAG:用于引导失败时的底层调试
    • 内核 Shell:使用 peekpoke 检查内存/寄存器

最佳实践
#

  • 最少功能开始(例如 UART + 定时器)。
  • 使用参考 BSP(可以节省数周的开发时间)。
  • 保持驱动程序的模块化和可重用性
  • 详细记录 MMU 属性和设备映射
  • 使用脚本自动化构建和测试流程。

常见问题 (FAQ)
#

问:我可以在 VxWorks 中重用 Linux 设备树吗? 答:可以,但只能作为参考。您必须调整绑定 (bindings) 以适配 VxWorks 的驱动程序。

问:我需要一个自定义的引导加载程序吗? 答:通常不需要。U-Boot 得到广泛支持,但您可能需要打一些小补丁。

问:如何调试 BSP 在引导过程中挂起的问题? 答:使用 JTAG,或者在 sysHwInit() 中添加调试串口打印来跟踪执行流程。


BSP 架构概览
#

以下是 VxWorks 中 BSP 的一个简单分层视图:

+--------------------------+
|       应用程序           |
+--------------------------+
|       VxWorks 内核       |
+--------------------------+
|   BSP (驱动, 初始化)     |
+--------------------------+
|  引导加载程序 (U-Boot)   |
+--------------------------+
|      自定义 ARM 硬件     |
+--------------------------+

结论
#

为自定义 ARM 开发板移植 VxWorks 7 的 BSP 是一个多步骤的过程,需要对硬件、引导加载程序、内存管理和驱动程序有深入的理解。通过正确的方法——引导代码、设备树配置、驱动集成和系统性调试——您可以成功地启动您的开发板,并充分利用 VxWorks 的实时性能。

📌 在下一篇文章中,我们将重点介绍 VxBus 驱动程序开发,届时我们将从零开始构建一个完整的自定义驱动程序。


相关文章
#

相关文章

VxWorks 7开发用户指南
VxWorks 7
VxWorks 编程终极指南
VxWorks RTOS 嵌入式系统 RTP 设备驱动
VxWorks 与 Linux 的 BSP 开发对比分析
VxWorks Linux BSP 嵌入式系统 设备驱动 RTOS