[Linux][虚拟串口]0x03一个特殊的字节

首先要啰嗦一段话,介绍一下项目背景,基于Linux异核架构平台实现高精度的电机控制。虚拟串口成为Linux和M4的一个很好的"沟通桥梁",首先编写好驱动生成设备,然后就是像读写普通串口一样对M4发送指令、接收指令。我把电机实际脉冲数int类型拆分成了4个char,类似于(以下为示例代码不可运行,大端模式)

复制代码
int value;
uint8_t buf[4];
// 大端序拆分
buf[0] = (value >> 24) & 0xFF;
buf[1] = (value >> 16) & 0xFF;
buf[2] = (value >> 8) & 0xFF;
buf[3] = value & 0xFF;

  然后有趣的事情开始了,开始时简单测试收发一切正常,然后机器开始自主运行,每当机器运行超过20W个脉冲之后就会莫名奇妙的停止,通过打印日志发现M4会发送一些不符合通信协议的数据过来,导致Linux发现接收的数据不对一直在重复请求数据重发,可是M4那边发送的数据是写的固定长度。这就有点莫名奇妙。经过不断测试之后,发现每当Linux发送的指定脉冲数协议中出现"0003"这个特殊字符时候,机器必定故障。更加巧合的是20W的16进制是"30D40",于是0x03这个罪魁祸首浮出水面。

  在串口默认模式下,Linux 会启用的规范模式将 0x03 当作中断字符,一旦遇到这个字符便会舍弃0x03之前的内容,导致出现数据丢失。至于解决方案就非常简单了,在Linux打开串口之后把它设置成原始模式即可。(以下为示例代码不可运行)

复制代码
bool RPMsg::Create()
{
    /*already opened*/
    if(m_fd >= 0)
        return true;
    /*open virtual serial port*/
    m_fd = open(VSP, O_RDWR | O_NOCTTY);
    if (m_fd < 0)
    {
        printf("open VSP failed!\n");
        return false;
    }
    /*non-blocking*/
    int flags = fcntl(m_fd, F_GETFL, 0);
    if (flags == -1 || fcntl(m_fd, F_SETFL, flags | O_NONBLOCK) == -1)
    {
        close(m_fd);
        m_fd = -1;
        return false;
    }
    //raw mode
    struct termios tty;
    if (tcgetattr(m_fd, &tty) != 0)
    {
        close(m_fd);
        return false;
    }
    cfmakeraw(&tty);
    tty.c_iflag &= ~(IXON | IXOFF | IXANY);
    cfsetispeed(&tty, B115200);
    cfsetospeed(&tty, B115200);
    if (tcsetattr(m_fd, TCSANOW, &tty) != 0)
    {
        close(m_fd);
        return false;
    }
    this->start();
    return true;
}
相关推荐
万联WANFLOW2 分钟前
海外网络故障怎么排查?Cloudflare 三季度断网报告解读与 mtr 实战
运维·网络·故障分析
Ruiery2 小时前
Linux 6.6内核内存管理深度解析(十三):slab/slub 分配器
linux·运维·服务器
乌恩大侠3 小时前
从 AI-RAN 到 AI Agent:基于 NVIDIA Nemotron 构建 5G/6G 智能网络故障诊断系统
服务器·人工智能·5g·o-ru·ai-ran·电信大模型
Decay__3 小时前
04_MySQL DBA 日常运维手册 —— 会话管理、锁与阻塞、事务监控、慢查询与日志巡检
运维·数据库·sql·mysql·架构
丰锋ff4 小时前
压缩命令笔记
linux
江华森4 小时前
数据中心基础设施运维实战:概述与实验环境搭建
运维
迪菲赫尔曼5 小时前
【基础篇 11】把官方源码放到服务器:版本、解压层级和安装位置,一次弄清楚
运维·服务器·开发语言·人工智能·python·yolo·目标检测
GeW6 小时前
产业新优势基础软件的人才底盘,从Linux与数据库开始
linux·数据库
by209996 小时前
Linux GCC/G++ 编译与 Makefile 构建
linux·运维·服务器·经验分享
螺丝钉tina6 小时前
[Playwright][08] Upload 模块自动化:如何设计真实业务测试用例?
运维·自动化·测试用例