VirtualBox中Ubuntu虚拟机读取RS232串口出现乱码求助
我在Windows主机上用VirtualBox运行Ubuntu虚拟机,尝试读取RS232串口数据。Windows主机端用Termite工具能正常显示正确信息,但Ubuntu虚拟机里用调试工具和示例代码时,只能看到乱码。


我试过更换不同波特率测试,但没有效果。疑惑为什么不能用和Windows主机端相同的波特率(也就是Termite里正常显示的波特率),请问应该从哪些方面排查问题?
以下是我在Linux中使用的示例代码:
/************************************************** file: demo_rx.c purpose: simple demo that receives characters from the serial port and print them on the screen, exit the program by pressing Ctrl-C compile with the command: gcc demo_rx.c rs232.c -Wall -Wextra -O2 -o test_rx **************************************************/ #include <stdlib.h> #include <stdio.h> #ifdef _WIN32 #include <Windows.h> #else #include <unistd.h> #endif #include "rs232.h" int main() { int i, n, cport_nr=2, /* /dev/ttyS2 (COM3 on windows) */ bdrate=921600; /* 9600 baud */ unsigned char buf[4096]; char mode[]={'8','N','1',0}; if(RS232_OpenComport(cport_nr, bdrate, mode, 0)) { printf("Can not open comport\n"); return(0); } else { printf("Open COM %d on Windows\n", cport_nr+1); } while(1) { printf("RS232_PollComport...\n"); n = RS232_PollComport(cport_nr, buf, 4095); if(n > 0) { buf[n] = 0; /* always put a "null" at the end of a string! */ for(i=0; i < n; i++) { if(buf[i] < 32) /* replace unreadable control-codes by dots */ buf[i] = '.'; } printf("received %i bytes: %s\n", n, (char *)buf); } #ifdef _WIN32 Sleep(100); #else usleep(100000); /* sleep for 100 milliSeconds */ #endif } return(0); }
虚拟机串口映射参数一致性检查
打开VirtualBox虚拟机设置→串口,确认波特率、数据位(8位)、停止位(1位)、奇偶校验(无)这些参数和Windows端Termite完全匹配,同时和代码里的mode[]={'8','N','1',0}保持一致。部分串口设备需要勾选“保持DTR/RTS”选项,可尝试开启。Linux串口设备路径验证
代码中cport_nr=2对应/dev/ttyS2,但VirtualBox映射的串口可能是/dev/ttyUSB0或/dev/ttyACM0(若使用USB转RS232适配器)。在Ubuntu中执行ls /dev/tty*,插拔串口设备对比前后变化,找到正确设备路径后,修改代码中的cport_nr(比如/dev/ttyUSB0对应端口号0)。串口权限修复
Ubuntu普通用户默认无串口访问权限,执行sudo usermod -aG dialout $USER,注销重新登录后再运行程序;或直接用sudo ./test_rx临时以 root 权限测试,排查是否是权限导致的问题。波特率配置正确性确认
注意到代码中注释标注/* 9600 baud */,但实际变量bdrate=921600,若Termite使用的是9600波特率,这会直接导致乱码,需修正波特率数值。此外,可在Ubuntu中用stty -F /dev/xxx speed 目标波特率手动设置串口波特率后再运行程序。原始数据接收验证
代码中会将小于32的控制字符替换为.,若设备发送二进制数据,会导致显示异常。可注释掉替换逻辑,改用printf("%02X ", buf[i]);打印原始字节的十六进制值,对比Windows端Termite的十六进制输出,判断是接收错误还是显示问题。VirtualBox串口模式切换
若当前使用“主机管道”等转发模式,尝试切换为“直接连接到物理串口”,避免中间转发层干扰。同时将VirtualBox更新至最新版本,修复旧版本可能存在的串口转发bug。
内容的提问来源于stack exchange,提问作者Emily Lin

