
做嵌入式实时系统这些年VxWorks 是绕不开的一座山头。工业控制、航空航天、汽车电子、通信设备里大量设备跑的都是它。这次我把VxWorks 6.8和配套的Wind River Workbench 3.2从零开始装起来、把目标机跑通、把调试链路打通的全过程整理出来包括环境搭建的每一步、内核镜像的编译加载、Workbench连接目标机做调试以及我踩过的各种坑。如果你是刚接触VxWorks或者正准备搭这套经典组合这篇内容可以直接照着抄。1. 这套环境到底是什么为什么值得搭1.1 先说清楚VxWorks 6.8和Workbench 3.2的定位VxWorks 6.8是风河Wind River在2010年前后发布的实时操作系统版本到现在仍然是很多存量项目的主力系统。它的内核是微内核架构任务调度、中断响应、内存管理这些核心模块可以在编译时按需裁剪资源占用极低实时性非常确定。Workbench 3.2则是配套的集成开发环境基于Eclipse框架负责代码编辑、交叉编译、内核镜像配置、目标机连接和调试。这两个版本是一个强绑定的组合。VxWorks 6.8对应的开发工具就是Workbench 3.2旧版本不支持新内核的工程格式新版本又不向后兼容老BSP。网上能看到的资料里讨论最多的就是这两个版本的搭配。为什么到今天还有大量人在找怎么搭这套环境因为存量项目维护、旧设备维修、教材配套实验、军工和工业领域的合规需求都要求你还在用这套老工具链。1.2 搭好这套环境能做什么环境跑通之后你至少可以完成这几件事在虚拟机里启动一个完整的VxWorks目标系统看到shell控制台工作。用Workbench编写、交叉编译一个可下载内核模块DKM下载到目标机里动态运行。通过Workbench连接目标机查看任务列表、内存使用、信号量状态打断点调试。理解VxWorks系统的启动流程、BSP的作用、镜像加载机制这些都是入行的基本功。我遇到过很多刚入行的朋友卡在环境搭建这关就放弃了特别可惜。实际上这套环境搭建的难点不在操作复杂而在版本匹配、网络配置、串口通信这些细节上。把这些细节理清楚整个过程并不难。2. 动手前的准备清单2.1 物料清单与版本匹配在开始安装之前先把需要的东西列清楚缺一样都不行。我用的这套组合是组件版本说明宿主机操作系统Windows 10 专业版64位Workbench 3.2本身是32位程序64位Windows下跑没有大问题VxWorks6.8包含BSP、内核源码、组件库安装包一般在DVD镜像里Workbench3.2安装包通常在另一张DVD里或者与VxWorks同盘目标机VMware Workstation虚拟机模拟x86目标硬件省去真机调试的麻烦虚拟机串口工具第三方串口助手或Workbench自带终端用于查看bootrom输出和VxWorks控制台这里有一个版本匹配的关键点VxWorks 6.8自带的BSP包里x86系列BSP对应的是Pentium等老处理器平台VMware虚拟机默认的CPU模型完全兼容。但是虚拟网卡一定要选对后面我会详细说。2.2 宿主机环境准备Workbench 3.2对宿主机的路径和用户权限非常敏感我建议在正式安装之前先把这些做到位第一安装路径不要带空格不要带中文。比如C:\WindRiver是可以的C:\Program Files\WindRiver就很容易在后面编译阶段出诡异问题。第二Windows用户名最好是纯英文。如果你当前用户名是中文的Win10下可以新建一个英文管理员账户用那个账户来装。第三关闭UAC或者安装时右键“以管理员身份运行”。Workbench安装过程要写注册表、装服务权限不够时会静默失败后面启动时各种功能缺失。2.3 License环境配置VxWorks 6.8和Workbench 3.2使用风河的License机制安装完成后必须配置好License Server才能正常编译和调试。License文件一般在安装包附带或者由公司统一部署License Server。如果是个人学习安装包里通常带一个评估License或者教育用途的授权。配置License要注意的是环境变量。安装完成后需要检查系统环境变量里有没有WIND_LICENSE_FILE它指向许可证文件或License Server地址。如果指向的是文件路径里的反斜杠要转义建议直接写成绝对路径。我装的时候没注意这个变量结果Workbench能启动但只要一编译就弹License错误折腾了好久才发现是环境变量没生效。3. 安装Workbench 3.2遇到的几个细节3.1 安装顺序真的有讲究先装Workbench再装VxWorks还是反过来我个人的经验是先装Workbench 3.2再装VxWorks 6.8的板级支持包和镜像工程组件。因为Workbench安装过程会注册Eclipse插件和工具链VxWorks的BSP文件是作为组件被导入到Workbench中的。如果顺序反了可能会出现Workbench里新建VxWorks工程时找不到对应BSP模板的情况。网上很多人问“为什么我的Workbench 3.2新建工程没有VxWorks 6.8选项”大概率就是安装顺序或者组件勾选出了问题。3.2 组件勾选别偷懒Workbench 3.2安装过程中会让你选择安装哪些组件。很多人图省事全部默认结果后面要用某个功能时发现没有安装。我的做法是全部展开把VxWorks相关组件、所有架构的BSP、文档、示例工程都勾上。虽然占用磁盘空间大一些但后面做实验时不用再回头补装。这里特别提醒Workbench 3.2的组件管理是按功能模块来的如果你只装了基本IDE没有装对应BSP后面编译目标机镜像时会提示找不到config.h或者Makefile其实不是代码问题是组件没装全。3.3 安装完必做的三个验证安装完成后别急着建工程先在宿主机上做三件事验证安装一是检查C:\WindRiver\目录下有没有vxworks-6.8这个子目录BSP文件、内核源码都在这里。二是在命令行执行wrInstall或者workbench命令确认可执行文件能正常启动。三是打开Workbench点击菜单Help - About确认版本号是3.2并且能看到VxWorks 6.8相关插件。我第一次装完之后直接跳过验证开始建工程结果在编译阶段报出一堆莫名错误最后回头才发现是BSP组件没装进去。4. 创建VxWorks目标机镜像4.1 新建VxWorks Image工程环境装好之后核心工作就是生成一个目标机能启动的VxWorks镜像。在Workbench里操作的流程是这样文件 - 新建 - 项目选择VxWorks Image工程。这时需要选择BSPx86平台选哪个BSP要注意不同的BSP对应不同的网卡驱动和内存布局。我用VMware跑x86目标机选的是x86BSP。如果你选错了BSP编译出来的镜像在目标机上可能起不来串口输出会卡在很早期的地方。工程建好之后Workbench会生成一系列文件。核心的是config.h、configAll.h和用于生成镜像的Makefile。这里先不着急改代码重点是理解这几个文件的作用。4.2 内核组件配置IP、FTP和shellVxWorks 6.8的组件配置是在Workbench里通过图形化界面进行的。双击工程的project文件会打开内核配置窗口里面列出了所有可以裁剪的组件。第一次跑通最少要确保这几个组件是打开的组件作用开启原因INCLUDE_IPTCP/IP协议栈网络加载镜像必须INCLUDE_TFTP_CLIENTTFTP客户端用于从宿主机下载镜像INCLUDE_FTP_SERVERFTP服务器用于目标机向宿主机上传下载文件INCLUDE_SHELL目标机shell交互调试基本功能INCLUDE_DEBUG_AGENT调试代理Workbench连接目标机调试必须组件配置不是一个一个勾选那么随意。VxWorks的组件之间有依赖关系你勾了一个高层组件系统会自动勾选它依赖的低层组件。如果某些组件没勾上编译时通常会报“undefined symbol”之类的错误这个后面讲排查时再展开。4.3 配置网络参数VxWorks目标机启动时需要知道自己的IP、子网掩码、宿主机的IP、镜像文件名等。这些参数通常不是在config.h里写死的而是在bootrom引导时通过命令行交互设置或者预先写在config.h里作为默认值。我建议第一次先把默认值写进config.h减少启动时的交互输入。找到config.h里的DEFAULT_BOOT_LINE宏这是一行用空格分隔的配置项。我的配置内容是这样的boot device : elf unit number : 0 processor number : 0 host name : host file name : /vxWorks inet on ethernet (e) : 192.168.1.10:ffffff00 host inet (h) : 192.168.1.100 user (u) : target flags (f) : 0x0 target name (tn) : vxTarget这里每项的含义要搞清楚inet on ethernet后面的192.168.1.10是目标机自己的IPffffff00是子网掩码255.255.255.0的十六进制形式host inet是宿主机IPfile name是镜像文件在宿主机上的路径。多个参数用空格分隔顺序不能乱。4.4 编译生成bootrom和VxWorks镜像配置完成之后在Workbench里右键工程选择Build会编译生成两个关键文件bootrom和vxWorks。bootrom是引导程序负责初始化硬件、加载vxWorks主镜像vxWorks就是真正的内核镜像文件。编译过程中最容易遇到的问题就是少组件。比如你在配置里勾选了FTP服务器但对应的源码不在BSP目录里编译器会报找不到头文件。这种问题排查方法很直接先取消勾选报错相关的组件确保能编出一个最小系统再加回需要的组件一个一个加直到编译通过。我第一次编译时把能勾的组件全勾上了结果编译报了几十个错误排查到崩溃。后来改成“最小系统优先”的思路先把系统跑起来再逐步加功能效率高得多。5. 虚拟机目标机的配置与启动5.1 VMware创建虚拟机的关键选项目标机我用的是VMware Workstation虚拟机创建虚拟机时这几个参数要注意参数推荐值原因CPU1核心VxWorks 6.8不依赖多核单核兼容性最好内存256MBVxWorks很小256MB足够硬盘8GB IDE虽然VxWorks不用硬盘启动但要预留空间网卡桥接模式Intel PRO/1000MT桥接模式方便与宿主机直接通信串口命名管道\\.\pipe\com_1另一端是Workbench串口用于日志和控制台这里最容易被忽略的是网卡类型。VMware默认的e1000网卡对应VxWorks的end驱动但不同BSP的end驱动实现不一样。我用的x86 BSP对Intel PRO/1000MT支持很好如果你发现bootrom启动时检测不到网卡先换个网卡型号试试。5.2 串口配置看不到日志一切都是盲人摸象VxWorks的启动日志默认输出到串口。如果串口没配好目标机启动后你什么都看不到出了问题也完全无迹可寻。在VMware里给虚拟机添加串口设备选择“使用命名管道”管道名填\\.\pipe\com_1这一端是虚拟机另一端是“另一台应用软件”比如MobaXterm或Putty。宿主机上连同一命名管道这样虚拟机的串口输出就会直接显示在终端里。我建议启动目标机之前在宿主机上先把串口终端打开因为VxWorks启动很快几秒内bootrom就开始打印信息。错过打印内容就只能重启再看。5.3 bootrom启动与镜像加载配置好VMware和串口后启动虚拟机。bootrom会首先运行打印类似这样的信息VxWorks Boot ROM 6.8 Copyright 1984-2010 Wind River Systems, Inc. CPU: Intel x86然后进入启动参数交互模式它会问你“Press any key to stop auto-boot”。如果你在config.h里配好了默认启动行它会直接自动加载镜像。自动加载的过程是bootrom通过TFTP或FTP协议向宿主机请求镜像文件下载到内存指定地址然后跳转执行。所以宿主机上必须有TFTP服务或者FTP服务镜像文件要放在对应目录下。我踩过一个大坑宿主机Windows防火墙默认拦截了FTP和TFTP的端口目标机bootrom一直显示Link up但TTTTT超时就是连不上宿主机。后来在防火墙里放行了FTP端口21、TFTP端口69问题立刻解决。6. 用Workbench连接目标机做调试6.1 启动Target Server镜像跑起来之后Workbench还不能立刻调试需要先启动Target Server。Target Server是Workbench和目标机之间的桥梁它通过宿主机和目标机之间的网络或串口通道转发调试命令。在Workbench里点菜单Run - Debug Configurations选择Wind River Target Server新建一个配置。连接方式有两种网络连接和串口连接。网络连接填目标机IP串口连接选宿主机上的串口号和波特率一般是115200。建议首选网络连接速度比串口快很多。点启动后Target Server状态变成Running接着可以新建一个连接View。如果网络通畅Workbench会在几秒内连上目标机的调试代理然后自动同步目标机上的任务列表和内存信息。6.2 创建Downloadable Kernel Module工程连接上目标机接下来最常用的操作是编写一个可下载内核模块DKM并动态加载运行。在Workbench里新建一个Downloadable Kernel Module工程语言选C或CBSP继续选x86。DKM工程编译出来是.out文件并不是独立的系统镜像而是运行在VxWorks内核态的模块。它和内核共享地址空间可以调用内核函数这是做驱动开发和内核功能扩展最常见的方式。写一个最简单的模块测试#include vxWorks.h #include stdio.h void hello() { printf(Hello from DKM module!\n); }这个模块编译通过后在Workbench里右键工程选择Build Project生成.dkm文件。然后右键选择Download或To Target - Download把模块下载到目标机。下载完成后模块里的函数就被加载进内存了。6.3 断点调试和系统查看模块下载成功之后在源码里打断点然后启动调试Workbench会切换到调试透视图。当目标机上的代码执行到这个函数时会停在断点处你可以在Variables窗口里看变量值在Memory窗口中看内存数据在Registers窗口里看寄存器。VxWorks系统本身还提供了很多调试窗口。Workbench的System Viewer能看到任务创建、删除、抢占、信号量相关的事件Target Monitor能看到CPU负载和内存使用。这些工具对于分析实时系统的调度和资源竞争非常有用。我第一次在目标机上调试时发现断点根本不生效折腾了半天才发现问题我用的目标机没有把调试代理组件编译进镜像。Debug功能能不能用完全取决于内核里是否包含INCLUDE_DEBUG_AGENT组件而不是Workbench这边设置。7. 常见问题排查与避坑记录7.1 目标机启动卡在Attaching network interface附近这个场景非常多。bootrom已经启动但卡在网卡初始化或者网络连接环节。排查顺序是这样的先看串口输出里有没有检测到PCI设备、网卡型号对不对然后查虚拟机的网卡类型是否被BSP的end驱动支持最后确认宿主机和虚拟机的网络连通性ping一下目标机IP通不通。如果是VMware环境优先换Intel PRO/1000MT改桥接模式宿主机防火墙临时关闭测试。这三个动作做完90%的这类问题能解决。7.2 FTP连接失败导致镜像无法下载bootrom通过FTP下载镜像失败时会反复打印超时符号。除了防火墙问题还有可能是FTP服务端配置的问题。VxWorks 6.8自带的FTP客户端要求服务端支持被动模式和主动模式同时兼容某些Windows FTP服务器软件默认配置不兼容。我最后是用FileZilla Server解决了问题关键设置在被动模式监听端口范围并把防火墙里的对应端口放行。另外注意FTP的用户权限要保证能读取镜像文件所在目录。7.3 Target Server连接超时Workbench能ping通目标机但Target Server就是连接不上。这种问题一般是两个原因一是目标机镜像里没编译调试代理组件二是网络上有其他设备占用了目标机IP或Target Server使用的端口。排查调试代理是否存在可以在目标机shell里执行命令查看内核符号lkup debugAgent。如果显示找不到符号说明组件没编进去回到第4节检查组件配置。如果组件有再查Workbench连接配置里的端口号是不是默认的1534。7.4 串口只显示ROM信息没有VxWorks启动日志有时候bootrom信息能正常输出但之后串口就没动静了而虚拟机的CPU还在运行。这大概率是VxWorks接管串口后串口参数被重新配置了和WindShell波特率不匹配。VxWorks默认的shell波特率是9600而bootrom输出是115200。你需要在串口终端上切换波特率到9600再看就会看到shell提示符。这个问题很容易让人误以为是系统没起来实际上是两个阶段波特率不同导致的。7.5 最小系统优先原则再补充一个我个人的环境搭建经验总结可以归纳为“最小系统优先”。无论是在Workbench组件配置阶段还是在目标机硬件配置阶段都先搭建一个最精简、最可能成功的环境跑通了再逐步扩展。比如一开始只保留串口和网络组件确认系统能起来、能ping通、能连Target Server之后再加FTP、shell、调试代理这些功能。这样做的原因是VxWorks组件配置非常灵活但是组件之间的依赖关系也复杂。如果一上来就配全出了问题根本分不清是A组件的问题还是B组件的问题。而一个最小系统只需要极少的变量排查起来快得多了。我在指导同事搭建环境时也一直强调这一点后者按照这个思路操作基本都能在半天内跑通。8. 这套环境对学习VxWorks的价值环境搭建的最终目的是为了学系统。VxWorks 6.8作为一款经典的实时操作系统它的内核机制非常值得学习。运行环境跑通之后我建议从这几个方面推进第一用shell命令操作系统。VxWorks的shell支持任务创建、信号量操作、内存查看、系统信息显示等命令完全是内核调试级的体验。比如用taskCreate创建一个新任务再用i命令查看任务列表。这个过程能建立对任务管理最直观的认识。第二阅读BSP代码。VxWorks的BSPBoard Support Package是理解硬件与系统如何对接的最佳教材。从sysLib.c里的板级初始化代码开始看它是如何初始化内存、初始化中断控制器、注册网卡驱动的这一块啃下来嵌入式底层开发能力会有质的提升。第三动手写一个字符设备驱动。VxWorks的设备框架、I/O系统与规则和Linux有相似之处但实现细节完全不同。写一个简单的设备驱动在应用程序里open、read、write它能同时锻炼DKM编程、系统调用和驱动框架三方面的能力。第四调试一个多任务的并发场景。用Workbench的System Viewer观察两个任务竞争信号量时的调度行为。这种图形化的观察方式比单纯看代码理解要深刻得多。这套环境搭建完成其实就相当于有了一个实验台。后续很多VxWorks相关的知识点都可以在这个实验台上直接验证。9. 最后的几点个人心得这套VxWorks 6.8和Workbench 3.2的环境在整个嵌入式生态里确实算老古董了但它背后代表的那套实时系统设计思想并不过时——确定性调度、微内核裁剪、静态配置优先、调试代理机制这些理念直到今天依然在大量嵌入式RTOS中延续。搭好这一套环境你学到的不只是如何点按钮、敲命令更是一种系统级的思维习惯。另外再分享一个小技巧保存虚拟机配置的最佳实践。当你辛辛苦苦把VxWorks给调通了马上用VMware的“快照”功能保存一份理想状态的虚拟机状态。因为VxWorks镜像工程和配置都改起来很快但是一旦你改坏了某个参数就别再想快速回到上次可用状态了。我有一次把目标机镜像的网络驱动换成不兼容的型号结果系统彻底起不来重新配置加重新编译花了整整一个下午。早知道随手拍个快照一分钟就能恢复。环境搭建是一个需要耐心的地方但它也是学习VxWorks最值得投入时间的前置工作。环境通了后面所有的学习都会顺畅很多。