ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

VxWorks 6.9 i.MX31Lite BSP深度解析:启动链、寄存器驱动与NAND烧录

VxWorks 6.9 i.MX31Lite BSP深度解析:启动链、寄存器驱动与NAND烧录 简介本资源是面向嵌入式实时系统开发者的Freescale i.MX31Lite平台VxWorks 6.9板级支持包BSP专为ARM926EJ-S架构的低功耗高性能嵌入式应用设计适用于工业控制、通信设备等对实时性与稳定性要求严苛的场景适合具备VxWorks基础和ARM裸机开发经验的中高级工程师。压缩包共30个文件涵盖9个C源文件如imx31Spi.c、sysLib.c、9个头文件如usbImx31.h、fsl_imx31lite.h、2个汇编启动文件romInit.s、sysALib.s以及Makefile构建脚本、CDF配置描述、符号表vxWorks.sym、启动镜像bootrom.bin/vxWorks、硬件初始化文档README和Hex/Bin固件等完整支撑BSP编译、烧录、调试与驱动开发全流程。已有140人学习下载。读者可直接获取开箱即用的i.MX31Lite硬件适配能力包括GPIO/I2C/SPI/USB/ATA/NAND等全接口驱动实现、内存与中断配置模板、U-Boot兼容启动流程及图形子系统imx31Graphics.c参考代码显著降低VxWorks在该平台的移植门槛。1. 这不是普通 BSP 压缩包fsl_imx31lite.zip 是 VxWorks 6.9 在 i.MX31Lite 上的「硬件握手协议」全集你拿到fsl_imx31lite.zip第一反应可能是“又一个老 BSP 包”但实际它远不止驱动集合——它是 VxWorks 6.9 与 Freescale i.MX31LiteARM926EJ-S之间完成底层握手的完整契约。这个压缩包里没有 Linux 内核、没有 U-Boot 源码、也没有 GUI 框架只有最硬核的三件事让 CPU 能上电跳转到romInit.s、让中断控制器能响应sysLib.c注册的 ISR、让 NAND 控制器在nandCtl.c中完成页擦写校验。它解决的是嵌入式实时系统中最致命的问题启动失败、中断失能、存储不可靠。适合正在维护工业控制终端、医疗设备固件或通信协议栈的工程师尤其当你面对的是已停产但仍在产线运行的 i.MX31Lite 硬件平台——这里没有 SDK 更新、没有在线文档只有这个 ZIP 和你手里的 JTAG 调试器。它不面向初学者因为Makefile里没有make helpREADME里没有环境变量说明所有配置都默认你已熟读 VxWorks 6.9 BSP 开发手册第 3–7 章。2. 从 romInit.s 到 sysLib.ci.MX31Lite 启动链的四层初始化逻辑VxWorks 在 i.MX31Lite 上的启动不是单一线性流程而是由四个严格时序耦合的阶段组成。fsl_imx31lite.zip中的文件按此逻辑组织理解每层职责是修改 BSP 的前提。2.1 第一层ROM 初始化romInit.s——CPU 复位后的第一条指令romInit.s是整个启动链的入口它必须在未启用 MMU、未初始化堆栈、未配置时钟前完成三件事设置 ARM 模式寄存器、配置 i.MX31Lite 片内 ROM 映射、跳转至 C 代码入口sysInit()。该文件中关键汇编段如下.globl _romInit _romInit: mrs r0, cpsr bic r0, r0, #0x1f 清除模式位 orr r0, r0, #0xd3 设为 SVC 模式 IRQ/FIQ 禁用 msr cpsr, r0 ldr sp, _stack_start 使用链接脚本定义的栈顶地址 bl sysInit 跳转至 C 初始化函数注意_stack_start并非硬编码数值而是由bootrom.ld链接脚本导出的符号。若你修改了 RAM 分配如将 SDRAM 起始地址从0x80000000改为0x80010000必须同步更新bootrom.ld中的__stack_start定义并确保romInit.s中ldr sp, _stack_start引用正确。否则系统会在sysInit()执行前因栈溢出直接死机且无任何调试输出。2.2 第二层系统级初始化sysLib.c config.h——硬件资源注册中枢sysLib.c是 BSP 的心脏它调用各模块初始化函数并注册到 VxWorks 内核。其核心结构为void sysLibInit (void) { sysHwInit(); /* 硬件基础初始化 */ sysMmuInit(); /* MMU 表初始化若启用 */ sysClkInit(); /* 系统时钟源配置 */ sysIntInit(); /* 中断控制器i.MX31 的 AVIC注册 */ sysSerialInit(); /* UART0/1 初始化 */ sysNandInit(); /* NAND Flash 控制器初始化 */ sysSpiInit(); /* SPI 主机控制器初始化 */ }而config.h则通过宏开关控制上述函数是否编译。例如#define INCLUDE_NAND /* 启用 NAND 支持 */ #define INCLUDE_SPI /* 启用 SPI 支持 */ #define SYS_CLK_RATE_MIN 32000 /* RTC 时钟最低频率 */ #define SYS_CLK_RATE_MAX 533000000 /* ARM 最高主频 */提示config.h中#define INCLUDE_XXX不仅影响编译还决定sysLib.c中对应sysXXXInit()是否被调用。若你禁用了INCLUDE_SPI但应用层仍调用spiOpen()VxWorks 将返回S_ioLib_NO_DRIVER错误——这不是驱动缺失而是初始化函数根本未执行。验证方法在sysLibInit()开头插入printf(sysLibInit start\n);观察串口是否有输出。2.3 第三层外设驱动实现imx31Spi.c / nandCtl.c / usbImx31.h——寄存器级操作封装驱动文件不提供抽象 API而是直接操作 i.MX31Lite 特定寄存器。以imx31Spi.c为例其核心是spiTransfer()函数STATUS spiTransfer ( SPI_DEV_ID devId, char * pTxData, char * pRxData, int nBytes ) { UINT32 regVal; /* 1. 等待 SPI 模块空闲 */ while ((SPI_REG_READ(SPI_SR) SPI_SR_RDR) 0) ; /* 2. 设置传输长度 */ SPI_REG_WRITE(SPI_TCR, nBytes); /* 3. 启动传输 */ SPI_REG_WRITE(SPI_CR, SPI_CR_XCH | SPI_CR_EN); /* 4. 轮询接收完成 */ while ((SPI_REG_READ(SPI_SR) SPI_SR_RDR) 0) ; return OK; }其中SPI_REG_READ/SPI_REG_WRITE宏定义在imx31Spi.h中#define SPI_BASE_ADDR 0x10024000 #define SPI_REG_READ(off) (*(volatile UINT32*)(SPI_BASE_ADDR (off))) #define SPI_REG_WRITE(off,val) (*(volatile UINT32*)(SPI_BASE_ADDR (off)) (val))关键参数说明SPI_BASE_ADDR必须与硬件原理图一致。i.MX31Lite 的 SPI0 默认基址为0x10024000但若 PCB 设计中将 SPI0 地址线 A12 接地则实际基址变为0x10020000。此时必须同步修改imx31Spi.h中的SPI_BASE_ADDR否则所有 SPI 操作读写错误寄存器表现为spiTransfer()永远卡在轮询循环中。2.4 第四层网络与存储配置configNet.h / nandCtl.h——协议栈与介质适配层configNet.h定义网络接口参数nandCtl.h定义 NAND 页/块布局。二者共同决定 VxWorks 是否能挂载文件系统/* configNet.h */ #define END_TBL1 { fei, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } /* nandCtl.h */ #define NAND_PAGE_SIZE 2048 #define NAND_SPARE_SIZE 64 #define NAND_BLOCK_SIZE (64 * 2048) /* 128KB per block */ #define NAND_TOTAL_BLOCKS 2048 /* 256MB total */验证要点END_TBL1中fei表示 Fast Ethernet Interface对应feiEnd.c驱动。若你的硬件使用的是smc9118芯片而非 i.MX31 内置 MAC则必须将fei替换为smc9118并确保smc9118End.c已加入工程。否则ifconfig将无法列出任何网络接口tftp下载固件失败。3. Makefile 与构建系统如何从源码生成 bootrom.bin 和 vxWorks.stfsl_imx31lite.zip中的Makefile是 VxWorks 6.9 Tornado IDE 生成的标准 BSP 构建脚本但它不依赖 IDE可纯命令行构建。其核心逻辑是分阶段编译先生成bootrom.o再链接为bootrom最后转换为烧录格式。3.1 构建环境准备交叉工具链与路径映射VxWorks 6.9 要求使用diab编译器非 GCC。确认环境变量export WIND_BASE/opt/windriver/vxworks-6.9 export TOOL_PATH$WIND_BASE/host/resource/hc/arm/elf/diab/bin export PATH$TOOL_PATH:$PATH注意diab编译器对 ARM926EJ-S 的-cpu参数必须为arm926ej-s若误设为arm9romInit.s中的mrs r0, cpsr指令将被错误优化导致复位后 CPSR 模式位未清除系统卡死在未定义指令异常。3.2 Makefile 关键目标解析与自定义修改Makefile中以下目标必须理解其作用目标说明典型用途bootrom链接生成未格式化的 ELF 文件调试时加载到内存运行bootrom.hex转换为 Intel HEX 格式烧录到 NOR Flashbootrom.bin转换为原始二进制烧录到 NAND Flash 或通过串口下载vxWorks.st可加载的符号化 VxWorks 映像用于 WindSh 或远程调试构建bootrom.bin的关键命令链bootrom.bin: bootrom $(HOST_TOOLS)/objcopy -O binary $ $若需修改启动地址如将bootrom加载到0x80000000而非默认0x80001000需编辑bootrom.ldSECTIONS { . 0x80000000; /* 修改此处 */ .text : { *(.text) } .data : { *(.data) } }参数说明objcopy -O binary会剥离所有 ELF 头信息只保留.text和.data段的原始字节。因此bootrom.bin大小 ≈bootrom的.text .data段总和。若bootrom.bin大于 NAND Block Size128KB则烧录时需按块对齐否则nandCtl.c的nandWritePage()将返回ERROR。3.3 编译过程排错常见错误定位与修复当make bootrom.bin失败时按以下顺序排查检查config.h中INCLUDE_XXX与源文件存在性若config.h启用了INCLUDE_USB但usbImx31.h中声明的usbPciStub.c未被Makefile编译如usbPciStub.c不在SRCS列表中链接时将报undefined reference to usbStart。验证ioMux.c中引脚复用配置i.MX31Lite 的 UART1 功能引脚UART1_TXD,UART1_RXD需在ioMux.c中使能IOMUXC_SET_MUX(IOMUXC_UART1_TXD_SELECT_INPUT, 0x0); /* 选择 UART1_TXD */ IOMUXC_SET_PAD(IOMUXC_UART1_TXD, PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH);若遗漏IOMUXC_SET_PADUART1 将无信号输出printf()无任何串口打印。确认vxWorks.sym符号文件生成vxWorks.st依赖vxWorks.sym提供调试符号。若Makefile中SYM_FILE vxWorks.sym未正确定义WindSh 将无法解析函数名symFindByName(sysLibInit)返回NULL。4. 烧录与调试实战用 JTAG 加载 bootrom.bin 并验证 NAND 读写fsl_imx31lite.zip的最终价值体现在硬件上。以下是在真实 i.MX31Lite 板卡上完成首次启动的完整流程覆盖从烧录到功能验证。4.1 烧录 bootrom.bin 到 NAND Flash 的精确步骤i.MX31Lite 的 NAND 启动要求bootrom.bin必须位于第一个 BlockBlock 0的 Page 0。使用 Lauterbach TRACE32 执行// 1. 初始化 NAND 控制器 Data.Set D:0x10018000 %Long 0x00000001 // NAND_CTL_ENABLE // 2. 擦除 Block 0 Data.Set D:0x10018004 %Long 0x00000000 // NAND_CMD BLOCK_ERASE Data.Set D:0x10018008 %Long 0x00000000 // NAND_ADDR Block 0 Data.Set D:0x1001800C %Long 0x00000001 // NAND_EXEC_CMD 1 // 3. 写入 bootrom.bin假设文件大小为 0x1A2F0 字节 Data.Load.Binary bootrom.bin D:0x80000000 Mem.Copy D:0x80000000 %Long 0x1A2F0 D:0x10018010 // 写入 NAND 数据寄存器 Data.Set D:0x10018004 %Long 0x00000005 // NAND_CMD PAGE_PROGRAM Data.Set D:0x10018008 %Long 0x00000000 // NAND_ADDR Page 0 of Block 0 Data.Set D:0x1001800C %Long 0x00000001 // NAND_EXEC_CMD 1关键参数说明NAND_ADDR 0x00000000表示 Block 0 的 Page 0。i.MX31Lite 的 NAND 地址映射中低 6 位为 Page 内偏移中间 6 位为 Page 号高 10 位为 Block 号。因此0x00000000对应绝对地址0x00000000即 NAND 起始位置。4.2 启动后验证通过串口交互确认 BSP 功能完整性上电后若bootrom.bin正确执行串口将输出VxWorks 6.9 for i.MX31Lite Copyright 1984-2010 Wind River Systems, Inc. CPU: ARM926EJ-S Memory: 128MB SDRAM NAND: 256MB, 128KB/block此时执行以下命令验证核心模块- i // 查看任务列表确认 tUsrRoot 已创建 - sp sysNandTest // 运行 NAND 测试函数需在 sysLib.c 中启用 - nandShow 0 // 显示 Block 0 状态应返回 OK - ifconfig // 检查网络接口应显示 fei0 - ping 192.168.1.1 // 若网络连通证明 configNet.h 配置正确sysNandTest()函数在nandCtl.c中定义它执行擦除 Block 0 → 写入测试数据 → 读回比对 → 验证 ECC。若返回ERROR常见原因有二一是nandCtl.h中NAND_PAGE_SIZE与实际 NAND 芯片不符如误设为 512B 而芯片为 2048B二是nandCtl.c中nandWaitReady()超时值过短默认 100ms某些慢速 NAND 需设为 500ms。4.3 调试技巧用 romInit.s 中断点定位启动卡死位置当板卡上电无任何输出时最有效方法是在romInit.s关键位置设断点_romInit: mrs r0, cpsr bic r0, r0, #0x1f orr r0, r0, #0xd3 msr cpsr, r0 ldr sp, _stack_start bl sysInit 在此行设断点使用 JTAG 调试器连接后若程序停在此处说明romInit.s执行正常若停在bl sysInit后无响应则问题在sysLib.c的sysHwInit()中——常见为sysClkInit()中 PLL 配置错误导致 CPU 频率异常或sysIntInit()中 AVIC 寄存器写入非法值触发异常。实操技巧在sysHwInit()开头插入*(volatile UINT32*)0x10027000 0xDEADBEEF;写入 GPIO1_DR 寄存器点亮一个 LED若 LED 亮起证明 C 代码已执行若不亮问题在汇编到 C 的跳转环节需检查sysInit符号是否被正确导出nm bootrom | grep sysInit应返回T sysInit。5. 进阶将 fsl_imx31lite BSP 与现代开发工具链集成虽然fsl_imx31lite.zip原生适配 VxWorks 6.9 Tornado IDE但可通过标准化接口接入 VS Code CMake 工作流提升团队协作效率。5.1 生成兼容 CMake 的项目结构创建CMakeLists.txt将fsl_imx31lite源码纳入现代构建系统cmake_minimum_required(VERSION 3.10) project(fsl_imx31lite LANGUAGES ASM C) set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR arm) # 指定 diab 编译器路径 set(CMAKE_C_COMPILER $ENV{TOOL_PATH}/dcc) set(CMAKE_ASM_COMPILER $ENV{TOOL_PATH}/dcc) # 添加源文件按 config.h 宏开关条件过滤 file(GLOB_RECURSE SOURCES *.c *.s) list(FILTER SOURCES EXCLUDE REGEX .*usbPciStub.*) # 若未启用 USB add_executable(bootrom ${SOURCES}) target_include_directories(bootrom PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_compile_options(bootrom PRIVATE -cpuarm926ej-s -D_WRS_KERNEL)关键适配点-D_WRS_KERNEL宏启用 VxWorks 内核头文件路径-cpuarm926ej-s确保指令集兼容file(GLOB)需排除未启用模块的源文件避免链接错误。5.2 README 的实用化重构从说明文档到操作清单原README通常仅含版本信息应重写为可执行操作指南# fsl_imx31lite BSP 快速启动清单 ## 环境准备 - ✅ 安装 VxWorks 6.9 SP6 及 ARM Diab 工具链 - ✅ 设置 WIND_BASE 和 TOOL_PATH 环境变量 - ✅ 确认 JTAG 调试器支持 ARM926EJ-S如 Segger J-Link ## 首次构建 bash cd fsl_imx31lite make clean make bootrom.bin烧录验证用 JTAG 擦除 NAND Block 0将bootrom.bin写入 Block 0 Page 0上电观察串口输出VxWorks 6.9 for i.MX31Lite输入nandShow 0确认返回OK常见故障速查现象检查点修复命令串口无输出romInit.s中ldr sp, _stack_start地址修改bootrom.ld中_stack_startnandShow报错nandCtl.h中NAND_PAGE_SIZE改为实际 NAND 芯片规格2048 或 4096ifconfig无接口configNet.h中END_TBL1设备名改为硬件实际网卡型号fei/smc9118 **最后一行技术内容**在 VS Code 中安装 CMake Tools 插件后执行 CMake: Configure 即可生成 Ninja 构建文件make bootrom.bin 命令将被 ninja bootrom.bin 替代构建速度提升 40%且所有警告如 implicit declaration of function spiOpen实时高亮无需等待 make 结束。 p a hrefhttps://download.csdn.net/download/smartvxworks/33240622 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p
返回列表