当前位置:首页 > 技术 > 正文内容

Linux环境下串口数据收发监控实践

访客 技术 2026年7月14日 4

虚拟串口环境搭建

借助 socat 工具可快速构建成对的伪终端设备,无需硬件即可模拟完整双工通信场景:

# 安装工具
sudo apt-get install socat

# 创建互联的虚拟串口对
socat -d -d PTY,link=/tmp/vcom0,raw,echo=0 PTY,link=/tmp/vcom1,raw,echo=0

执行后会得到类似 /dev/pts/5/dev/pts/6 的设备路径,两者形成数据通路。

Qt端代码重构示例

以下采用异步信号槽机制,分离读写端口职责:

#include <QCoreApplication>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>

class CommAgent : public QObject {
    Q_OBJECT
public:
    explicit CommAgent(const QString &port, QObject *parent = nullptr) 
        : QObject(parent), m_channel(new QSerialPort(this)) {
        
        m_channel->setPortName(port);
        m_channel->setBaudRate(QSerialPort::Baud115200);
        m_channel->setDataBits(QSerialPort::Data8);
        m_channel->setParity(QSerialPort::NoParity);
        m_channel->setStopBits(QSerialPort::OneStop);
        m_channel->setFlowControl(QSerialPort::NoFlowControl);
    }

    bool activate(QIODevice::OpenMode mode) {
        if (!m_channel->open(mode)) {
            qWarning() << "端口开启失败:" << m_channel->errorString();
            return false;
        }
        connect(m_channel, &QSerialPort::readyRead, this, &CommAgent::onInbound);
        return true;
    }

    void dispatch(const QByteArray &payload) {
        m_channel->write(payload);
        m_channel->flush();
    }

private slots:
    void onInbound() {
        auto chunk = m_channel->readAll();
        qDebug() << "[" << m_channel->portName() << "] 收到:" << chunk;
    }

private:
    QSerialPort *m_channel;
};

主程序调用逻辑

int main(int argc, char *argv[]) {
    QCoreApplication app(argc, argv);

    CommAgent upstream("/tmp/vcom0", &app);
    CommAgent downstream("/tmp/vcom1", &app);

    if (!upstream.activate(QIODevice::WriteOnly) || 
        !downstream.activate(QIODevice::ReadOnly)) {
        return -1;
    }

    // 延迟发送确保下游就绪
    QTimer::singleShot(500, &upstream, [&]() {
        upstream.dispatch("HelloVirtualPort");
    });

    return app.exec();
}

硬件环回测试方法

对于实体串口,采用短接法验证通路完整性:

引脚定义连接方式
TXD (发送)→ RXD (接收)
GND (地)→ GND (地)

同一端口同时承担收发角色,配置为 ReadWrite 模式:

QSerialPort loopback;
loopback.setPortName("/dev/ttyUSB0");
loopback.open(QIODevice::ReadWrite);

connect(&loopback, &QSerialPort::readyRead, [&]() {
    qDebug() << "回显数据:" << loopback.readAll();
});

loopback.write("LoopCheck");
loopback.flush();

辅助诊断工具集

终端监控:

# 十六进制模式查看原始字节流
minicom -D /dev/ttyUSB0 -b 115200 --hex

# 使用 picocom 替代方案
picocom --baud 115200 --imap lfcrlf /dev/pts/5

权限快速修复:

# 当前用户加入 dialout 组,注销后生效
sudo usermod -a -G dialout $USER
# 临时提权
sudo chmod 666 /dev/ttyUSB0

异常排查要点

  • 确认端口未被占用:lsof | grep /dev/ttyUSB0
  • 校验波特率、数据位、停止位、校验位四元组一致性
  • 流控设置为 NoFlowControl 避免 RTS/CTS 信号阻塞
  • 适当追加 QThread::msleep(20) 等待硬件缓冲排空
标签: QtQSerialPort

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。