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

带COBS的USB串口:如何实现完整数据包的回调?

串口通信与COBS数据包回调触发问题

背景

我基于COBS协议实现了数据编码/解码逻辑,用printf封装后测试验证功能正常。现在要将该实现用于USB串口设备通信,参考相关技术文档编写了串口配置代码,但对部分配置选项仍有疑问,同时当前的回调触发机制不符合业务需求。

串口配置代码

#include <termios.h>
...
bool Serial::SerialPort_Open(const char* portname, int speed, __sighandler_t signal_handler_IO)
{
    m_serialport_fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);

    struct termios portSettings;
    tcgetattr(m_serialport_fd, &portSettings);

    cfsetspeed(&portSettings, speed);

    portSettings.c_iflag = 0;
    portSettings.c_oflag = 0;
    portSettings.c_cflag = CS8;
    portSettings.c_lflag = 0;

    //no special characters
    portSettings.c_cc[VINTR]    = 0;
    portSettings.c_cc[VQUIT]    = 0;
    portSettings.c_cc[VERASE]   = 0;
    portSettings.c_cc[VKILL]    = 0;
    portSettings.c_cc[VEOF]     = 0;
    portSettings.c_cc[VTIME]    = 0;    //don't wait for more data to add to the same buffer
    portSettings.c_cc[VMIN]     = 1;    //require *something* in the buffer before triggering an event
    portSettings.c_cc[VSWTC]    = 0;
    portSettings.c_cc[VSTART]   = 0;
    portSettings.c_cc[VSTOP]    = 0;
    portSettings.c_cc[VSUSP]    = 0;
    portSettings.c_cc[VEOL]     = 0;
    portSettings.c_cc[VREPRINT] = 0;
    portSettings.c_cc[VDISCARD] = 0;
    portSettings.c_cc[VWERASE]  = 0;
    portSettings.c_cc[VLNEXT]   = 0;
    portSettings.c_cc[VEOL2]    = 0;

    tcsetattr(m_serialport_fd, TCSANOW, &portSettings);

    /* install the signal handler before making the device asynchronous */
    struct sigaction saio;
    saio.sa_handler = signal_handler_IO;
    sigemptyset(&saio.sa_mask);
    saio.sa_flags = 0;
    saio.sa_restorer = NULL;
    sigaction(SIGIO, &saio, NULL);

    /* allow the process to receive SIGIO */
    fcntl(m_serialport_fd, F_SETOWN, getpid());
    /* Make the file descriptor asynchronous (the manual page says only
        O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
    fcntl(m_serialport_fd, F_SETFL, FASYNC);

    return true;
}

(注:为简化展示,代码中已移除错误检查逻辑)

当前问题与疑问

当前配置可正常传输通用测试数据,但回调触发逻辑存在问题:回调会针对每个非空USB数据包触发一次,这和COBS数据包的边界不匹配:

  • 单个大COBS数据包可能被拆分到多个USB数据包中传输
  • 单个USB数据包可能包含多个完整的小COBS数据包

COBS数据包为二进制数据(非ASCII字符串),特性是以空字符结尾,且数据包内容中不会出现空字符。想咨询:能否仅通过检测ASCII空字符作为终止符,实现每个完整COBS数据包触发一次回调?


内容的提问来源于stack exchange,提问作者AaronD

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 04:57:26