You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VirtualBox中Ubuntu虚拟机读取RS232串口出现乱码求助

问题描述

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

Windows主机端Termite工具运行正常
运行示例代码时出现乱码

我试过更换不同波特率测试,但没有效果。疑惑为什么不能用和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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 06:04:59