做嵌入式或者工控开发的朋友都有体会,调试串口通信的时候最烦的就是手边没有一台带串口的物理机。前阵子我要模拟两个设备通过UART交互,手头只有一台笔记本,索性在VMware里装了一个Win7一个Ubuntu16.04,用Virtual Serial Port Driver Pro 9.0在宿主机上生成一对虚拟串口,然后把两个虚拟机的串口分别接到这对虚拟串口的两端,实现虚拟机之间的串口互通。整个过程看起来绕,实际上逻辑很清晰,配好一次就再也回不去物理串口了。这篇文章把完整配置流程、踩过的坑和排查思路都整理出来,给同样需要在虚拟机环境里做串口联调的朋友参考。
1. 项目背景与方案选型
1.1 为什么要在虚拟机里做串口通信
做串口开发的人一定经历过这种场景:程序写好了,想跑一下和串口设备的联调,结果翻遍整个办公室找不到一台带COM口的电脑。现在的轻薄本基本不预留串口,USB转串口模块也无非是临时方案,驱动装来装去很折腾。再加上嵌入式Linux开发经常需要模拟两个进程通过串口交换数据,或者验证一个应用程序对接虚拟串口设备的行为,这时候虚拟机加虚拟串口就很有用了。
Win7和Ubuntu16.04这两个系统组合在老旧设备和工业项目里出现频率非常高。Windows侧有大量现成的串口调试工具,Linux侧方便跑脚本和自动化测试,两者通过串口联调,基本上可以覆盖大部分教学、测试、逆向和工控场景。特别是当你需要模拟一台终端设备和一个上位机软件交互时,一边Windows一边Linux,中间走串口,效果和真实硬件几乎一样。
1.2 三条可行路径的对比
在VMware里打通两个虚拟机的串口,业界常见三种做法。第一种是VMware的命名管道,两个虚拟机都指向同一个管道路径,省掉第三方软件,但配置起来比较绕,而且管道方式在不同VMware版本之间有兼容性问题。第二种是买一个USB转串口模块再接根杜邦线,把两个物理串口交叉相连,最后分别映射给两个虚拟机。这样成本不高,但桌面会堆线缆,而且插拔容易把USB口弄松,笔记本用户尤其不方便。第三种就是本篇文章要讲的,在宿主机上装Virtual Serial Port Driver Pro 9.0创建一对虚拟串口,再把这对虚拟串口分别映射给Win7和Ubuntu16.04虚拟机。
| 方案 | 成本 | 灵活性 | 适用场景 |
|---|---|---|---|
| VMware命名管道 | 免费 | 方案间兼容性一般 | 只在VMware虚拟机之间快速通信 |
| USB转串口模块+杜邦线 | 几十元 | 受物理接线限制 | 需要同时接入真实硬件外设 |
| VSPD虚拟串口对 | 软件授权 | 高,可灵活模拟 | 虚拟联调、教学演示、自动化测试 |
从长期维护的角度看,第三种方案胜在干净利落。虚拟串口对不占用物理资源,可以随时增加、删除、模拟断开,而且对波特率、数据位等参数没有限制,几乎就是一条理想化的串口线路。实际做联调时,想测异常断线重连,直接在VSPD里把串口对Disconnect再Connect就能模拟,这在物理串口环境里要拿着螺丝刀拆线才做得到。
1.3 为什么选定Virtual Serial Port Driver Pro 9.0
VSPD Pro 9.0是老牌串口虚拟化工具,安装后会在系统设备管理器里增加虚拟串口设备。它最核心的功能就是创建“串口对”,比如把COM3和COM4绑定成一对,往COM3写入的任何数据会从COM4读出,反过来也一样。整个过程对上层应用完全透明,虚拟机和宿主机上的软件都把它当作真实串口来用。
为什么不用免费开源的com0com?当然能用,com0com同样能创建串口对,但对新手不太友好,命令行的配置方式以及“修改串口配置后需要禁用再启用设备”的机制,在实际测试中很容易把人绕晕。VSPD Pro 9.0是GUI操作,点几下就能搞定,而且自带串口监视和分析工具,调试时可看的细节更多。在涉及虚拟串口的教学或者联调场景里,工具稳定比省一点授权费重要得多。
2. 环境准备:镜像、VMware与虚拟机创建要点
2.1 宿主机与VMware版本选择
宿主机我用的是Windows 11,内存32GB,CPU八核。跑两个虚拟机其实要求不高,建议至少16GB内存,两个虚拟机各分2GB,加上宿主机自身占用,8GB会有点紧张。CPU分配上,每个虚拟机给2到4个核心足够,串口通信几乎不占CPU,除非你要在虚拟机里跑编译。
VMware版本我选的是Workstation 15.5。这个版本对Win7、Ubuntu16.04的支持都很成熟,安装包体积适中。如果用的是VMware 16或者17,安装Win7时要注意虚拟机固件类型选择,建议在新建虚拟机的时候选择BIOS而不是UEFI,否则Win7安装阶段容易卡在“启动Windows”的Logo处。
额外提醒一下:装虚拟机之前,宿主机BIOS里一定要开启Intel VT-x或者AMD-V虚拟化,否则后续装64位系统会报“此主机不支持64位客户机操作系统”,这个基础问题很多人容易忽略。
2.2 Win7虚拟机安装要点
Win7镜像我推荐用原始ISO。网络上的“win7系统镜像iso下载”资源很多,但优先选择MSDN版本,避免各种预装软件和驱动捆绑。安装Win7时,虚拟机硬件兼容性选Workstation 15.x,内存2GB,磁盘40GB精简置备。装完系统后不要急着下载软件,先把VMware Tools装上,它能让虚拟机实现自适应分辨率和宿主机剪贴板共享,否则后面复制串口数据会很痛苦。
Win7系统比较老,浏览外部网页时问题比较多,建议在虚拟机里离线安装Chrome 109的离线安装包,这是最后一个支持Win7的Chrome版本。Edge也提供109离线包,可以在老系统上正常搜资料、下载补丁。对于只做串口通信的开发机来说,浏览器不是关键,但能上网查资料会方便很多。
关于Win7驱动的问题,虚拟机环境里一般很少遇到,但如果你添加了某些半虚拟化设备,偶尔会提示“INF不包含数字签名信息”。这个有经典解法:开机时按F8选择“禁用驱动程序签名强制”,或者临时进入测试模式。在虚拟机里操作时因为不涉及物理硬件,实际遇到的概率比物理机小很多,但有个心理准备总是好的。
2.3 Ubuntu16.04虚拟机创建要点
Ubuntu16.04虽然是老版本,但它在很多嵌入式开发和通信协议测试场景里依然是稳定之选。创建虚拟机时系统类型选Linux -> Ubuntu 64-bit,内存建议2GB,磁盘20GB。
一个关键点是源的问题。Ubuntu16.04官方源已停止支持,安装完第一件事是替换成可用镜像源。编辑/etc/apt/sources.list,把http://archive.ubuntu.com替换成阿里云或华为云的镜像地址,然后sudo apt update。不换源的话,后面安装minicom、cutecom等串口工具都会失败。
Ubuntu虚拟机里建议直接安装open-vm-tools,命令是sudo apt install open-vm-tools。这个软件包比VMware自带VMware Tools更稳定,分辨率自适应、剪贴板共享等功能都能正常使用。装完之后再安装minicom和pyserial,后面测试串口要用到。
3. Virtual Serial Port Driver Pro 9.0核心配置
3.1 安装时注意哪些细节
VSPD Pro 9.0的安装过程比较常规,但安装的时候务必右键选择“以管理员身份运行”。它会向系统注册一个虚拟串口驱动,权限不足可能导致驱动加载失败,到时候打开主界面报错再排查会绕一大圈。
安装过程中安全软件可能会把驱动拦截下来,建议安装前暂时关闭实时保护,装好后再打开,否则会出现虚拟串口创建成功但打开串口时提示“拒绝访问”的怪问题。
装完之后打开主界面,你会看到两个区域:左侧是已有虚拟串口列表,右侧是系统物理串口情况。物理串口没有也没关系,我们要创建的虚拟串口对不依赖物理硬件。
3.2 创建COM3/COM4虚拟串口对
在VSPD主界面的“Manage Virtual Ports”标签下,点击“Add pair”按钮,会弹出窗口让你选择一对串口号。默认情况下软件会挑选两个空闲的串口号,比如COM3和COM4。如果没有冲突,直接点确定就行。
生成之后,设备管理器里会多出两个端口,名称是“Virtual Serial Port (COM3)”和“Virtual Serial Port (COM4)”。记住重点:这两个端口是绑定的,COM3收到数据会转发给COM4,COM4收到数据会转发给COM3。中间的传输完全在内存里完成,所以数据速率上限远高于串口的115200,不用担心瓶颈。
如果默认的COM3和COM4被宿主机上某些蓝牙驱动或者读卡器占用了,可以手动指定成COM5和COM6,后续VMware映射时选对应端口即可。VMware对串口序号的2位数字和3位数字都能识别,不过尽量别选COM1/COM2,这两个在很多系统里有特殊含义。
3.3 虚拟串口的管理技巧
VSPD Pro 9.0的串口对支持Connect和Disconnect两个状态。Connect表示两边数据通路是连通的,Disconnect就相当于物理上拔掉了串口线。这个功能在测断线重连时特别好用,比如在Win7虚拟机里打开串口连接后,VSPD这边Disconnect,Win7串口调试助手立刻会报错“串口打开失败”,再恢复Connect,不用重建串口就能重新打开。
另外,VSPD Pro 9.0还自带串口监视功能,可以记录某个虚拟串口上流过的数据。实际调测时可以开着它观察Win7和Ubuntu之间到底交换了什么内容,不用在每一端分别抓包。小规模数据量下这个监视器足够用,复杂的再考虑Serial Port Monitor之类专门工具。
如果虚拟串口对中的某一个端口被宿主机程序占用(比如打开了串口调试器),那么在VMware里对应的虚拟机启动时就会报“无法打开串口”。所以在做虚拟机串口映射之前,一定要保证宿主机上没有任何程序占用COM3或COM4,VSPD本身会“虚拟”占用它们,但不会阻止虚拟机打开。
4. 虚拟机串口映射配置
4.1 Win7虚拟机添加串口
操作路径:关闭Win7虚拟机(不是挂起),在VMware Workstation主界面右键虚拟机 -> 设置 -> 添加 -> 串行端口。弹出的向导里选择“使用物理串行端口”,端口下拉框选COM3,勾选“启动时连接”。
这里有个典型的认知偏差需要纠正:VMware把宿主机的COM3映射给Win7虚拟机之后,Win7里面看到的并不是COM3,而是虚拟机自己的逻辑串口COM1。所以Win7设备管理器里看到的是“通信端口(COM1)”,对应VMware设置里的“Physical serial port: COM3”。你用串口调试助手打开COM1,实际上就是在操作宿主机的COM3。
如果你希望Win7虚拟机里显示的串口号是COM2,可以在VMware的虚拟机配置文件.vmx中增加serial0.fileName之类的参数,但一般没有必要,保持默认COM1最省心。Win7虚拟机里如果没有串口,还可以在VMware里添加多个串口,比如serial0、serial1,每个对应不同物理端口,多串口联调场景按同样方式操作。
4.2 Ubuntu16.04虚拟机添加串口
Ubuntu虚拟机的添加流程和Win7一样,添加串行端口,选择宿主机的COM4,勾选“启动时连接”。Linux虚拟机里对应的串口设备文件一般是/dev/ttyS0。可以用命令确认:
dmesg | grep ttyS
ls -l /dev/ttyS*
如果没有任何输出,可能串口没被识别,先检查VMware设置里的“连接”是否勾选,再虚拟机内执行
sudo modprobe 8250
加载标准串口驱动,一般默认都有。
4.3 启动顺序:串口必须先于虚拟机
这套方案最大的启动陷阱就是顺序。VSPD创建的COM3/COM4串口对必须处于Connect状态,而且两个虚拟机启动时要能正常打开各自对应的物理串口,如果VSPD还没运行,VMware会提示“未能连接到物理串口”。我踩过的坑就是先开了虚拟机,再回头装VSPD,结果Win7和Ubuntu都打不开串口。
正确的流程是:先启动VSPD并确认串口对Connect,再启动两个虚拟机。如果虚拟机已经启动完毕才发现串口没映射,可以在VMware菜单栏VM -> Removable Devices里重新连接串口,或者直接重启虚拟机。在多个虚拟机同时运行的情况下,建议先启动Ubuntu再启动Win7,保持固定顺序能减少VMware串口资源抢占的偶发问题。
5. 通信实测:从单发到双向
5.1 先用宿主机自环验证虚拟串口对
进了VSPD配好串口对,不要急着开虚拟机,先在宿主机上把链路验证一下。方法很简单,打开两个串口调试助手,一个绑定COM3,一个绑定COM4,在COM3里发送字符串,看COM4能不能收到。我用的是“格西烽火串口助手”,界面清爽,支持HEX和字符串收发。如果两个调试助手能互相收发,说明VSPD串口对工作正常,后面虚拟机映射的所有问题都可以隔离在虚拟机一侧排查。
自环测试时可以顺便测一下“断开/连接”功能:在VSPD里把串口对Disconnect,COM4的调试助手立刻收不到数据,重新Connect后恢复。这个行为要记住,因为它会导致后面虚拟机里串口异常。
5.2 Win7侧发送,Ubuntu侧接收
进入正题。启动两个虚拟机后,在Win7虚拟机里打开串口调试助手,选择COM1,波特率115200,数据位8,停止位1,无校验,点击打开。然后在发送框输入“Hello Ubuntu from Win7”,点击发送。
再看Ubuntu16.04虚拟机。在终端里执行:
sudo cat /dev/ttyS0
如果你看到“Hello Ubuntu from Win7”被打印出来,恭喜,这条串口链路从Win7到Ubuntu已经通了。
要注意的是,cat命令读取串口会一直阻塞等待数据。如果终端里没有动静,先确认有没有输错设备名,再用
ls -l /dev/ttyS*
看看是不是ttyS0。Ubuntu里读写串口需要root权限,sudo别忘了。
5.3 Ubuntu侧回发,Win7侧接收
单向通只算完成一半,再测反向。Ubuntu终端执行:
echo "Hello Win7 from Ubuntu" > /dev/ttyS0
Win7的串口调试助手里应该能看到这行文字。如果你用的是SSCOM,界面里显示内容会直接打印出来;如果用的是支持时间戳的工具,还能看到接收时间,方便后续分析。
这里提一个细节:echo默认会追加一个换行符,所以Win7侧看到的是“Hello Win7 from Ubuntu”后面带一个换行。如果你不想要换行,可以用
printf "Hello Win7 from Ubuntu" > /dev/ttyS0
。串口通信里换行符的处理本身就能引起一堆沟通问题,双向收发时养成用HEX模式观察的习惯会少很多麻烦。
5.4 用Python做自动化收发验证
字符串收发测完,最好写一个自动化脚本来验证长时间链路的稳定性。Ubuntu16.04自带Python,安装pyserial后可以用下面的脚本监听串口并自动回发确认。
import serial
ser = serial.Serial(
port='/dev/ttyS0',
baudrate=115200,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=1
)
print("Listening on /dev/ttyS0 ...")
while True:
data = ser.read(1024)
if data:
print("Rx:", data)
ser.write(b"ACK: " + data)
Win7侧用串口调试助手的“自动发送”功能,每隔200ms发送一次“ping”。如果Ubuntu侧打印出的“Rx: ping”次数连续增加,同时Win7侧能不断收到“ACK: ping”,说明链路在持续收发过程中没有丢包和锁死。跑个几千包没问题,基本可以放心用于后续开发。
这个脚本在某些老旧的Ubuntu16.04上如果pyserial版本过旧,需要先升级:sudo pip install --upgrade pyserial。如果连pip都没有,先sudo apt install python-pip。
5.5 数据校验与乱码排查
串口通信最容易出的现象就是乱码。虚拟机虚拟串口的信号质量是完美的,出现乱码基本不是电平问题,而是参数不匹配。检查顺序如下:第一,两边的波特率是否都是115200;第二,数据位、停止位、校验位是否一致,尤其是校验位,很多老工具默认“无校验”,但十六进制视图下一旦开了其他校验,数据会整体偏移;第三,是否有多个程序同时打开了同一侧串口,例如宿主机还开着串口调试助手盯着COM3,Win7虚拟机里的程序也打开COM1,会导致数据乱掉或者打开失败。
另外一个容易被忽略的点是文本编码。Win7的串口调试助手发送的是GBK编码的字符串,Ubuntu终端默认UTF-8,如果发送中文字符,接收端看到的可能是乱码,这个不是串口链路问题,而是编码问题。解决方法是统一用ASCII字符串或HEX模式测试,正式数据传输建议约定好编码再做。
6. 常见问题与排查技巧实录
6.1 常见问题速查表
| 现象 | 常见原因 | 解决方法 |
|---|---|---|
| VMware提示无法连接串口 | VSPD未运行或串口对处于Disconnect状态 | 打开VSPD,确认COM3/COM4为Connect状态 |
| Win7虚拟机没有COM1 | 未添加串口或未勾选启动时连接 | 在VMware设置中检查串行端口是否配置 |
| Ubuntu下/dev/ttyS0不存在 | 虚拟机未添加串口或8250驱动未加载 | 添加串口,执行sudo modprobe 8250 |
| 数据乱码 | 波特率或其他串口参数不一致 | 统一两端的波特率、数据位、校验位 |
| 发送正常但接收不到 | 两个虚拟机映射到了同一个COM口 | 分别使用COM3、COM4 |
| 串口调试助手无法打开串口 | 端口被其他程序占用 | 关闭占用程序,检查VSPD串口对状态 |
| 虚拟机启动卡住 | 旧系统镜像与VMware固件类型不匹配 | 虚拟机设置改为BIOS引导,关闭UEFI |
6.2 几个容易踩的小坑
第一个坑是VSPD串口对的Disconnect状态。我有一次调试到一半虚拟机串口掉线,一开始怀疑VMware坏了,折腾半天才发现是手滑点击了VSPD里的Disconnect。这个状态会导致虚拟机内的串口设备依然存在,但数据链路已然断裂,表现非常迷惑。
第二个坑是宿主机串口调试工具占用端口。如果你习惯先开一个宿主机串口助手监听着COM3,再去启动Win7虚拟机,VMware会直接报“无法打开串口”。宿主机工具和虚拟机不能同时占用同一个物理端口,测试时要么用宿主机工具做自环,要么让虚拟机去映射,不能同时进行。
第三个坑是Win7虚拟机里的串口号认知偏差。Win7里看到的是COM1,但它在VMware配置项对应的是COM3。如果你需要多个串口,在VMware里添加多个串行端口,然后注意每个虚拟串口对应的宿主机端口不要重复。很多人在这一步会把映射关系和虚拟机内串口号搞混,导致配置了COM3/COM4却始终连不上。
第四个坑是启动顺序不对。如果VSPD没先开,虚拟机启动时映射串口就会失败,而且VMware启动时如果检测不到端口,可能直接跳过串口初始化,虚拟机打开后不会重试。正确做法是VSPD先启动、串口对Connect、再启动虚拟机。
6.3 如何验证整条链路确实走了虚拟串口
做串口联调,很多人只满足于“两端能通信”,但有时候需要确认数据确实经过了预期链路。两个办法可以验证。
第一个办法是用VSPD自带的串口监视功能。在VSPD主界面上开启某个串口的数据监控,立刻能看到读写的数据内容。这个方式最直观,适合确认宿主机的COM3/COM4上是否有流量经过。
第二个办法是HEX模式比对。在Win7串口助手里用HEX发送一串固定数据,比如0A 0B 0C 0D,Ubuntu侧用hexdump命令接收:
hexdump -C /dev/ttyS0
如果打印出来的十六进制和发送端一致,说明链路无干扰、无格式转换。用这个方法还可以验证不同的串口参数(比如7位数据位、偶校验)下的数据形态,方便排查二进制协议问题。
我在实际使用中最深的一个体会是:这种“宿主机虚拟串口对 + 双虚拟机映射”的方案,本质上是把一条逻辑串口链路拆成了三段——Win7到COM3、COM3到COM4、COM4到Ubuntu。任何一段出问题,表象都是串口不通。排查的时候不要盯着某一端反复试,而是用自环测试先把每一段分开验证。先测VSPD的COM3/COM4自环,再测单虚拟机到宿主机端口的连通性,最后测双虚拟机互通,基本十分钟就能定位问题在哪一段。这套思路后来我在多串口项目中一直沿用,确实省了不少时间。
1559



被折叠的 条评论
为什么被折叠?



