C++ boost::asio是否干扰我的串行端口通信?

C++ boost::asio是否干扰我的串行端口通信?,c++,serial-port,boost-asio,embedded-linux,C++,Serial Port,Boost Asio,Embedded Linux,短版: 我有一个代码a,允许我通过串口(UART)读/写字节,该串口通过了单元测试 我编写了一些代码B,使用boost asio(从技术上讲,是独立asio)在TCP/IP上读/写字节,它也通过了单元测试 当我尝试将A和B放在一起时,A开始接收没有发送的消息 我想知道的是为什么,以及我能做些什么 有关代码A的更多详细信息: 代码A主要是C代码,使用ioctl、fnctl和unistd 首先,我打开序列号: // Flag explanation: // - O_RDWR // =

短版:

  • 我有一个代码a,允许我通过串口(UART)读/写字节,该串口通过了单元测试
  • 我编写了一些代码B,使用boost asio(从技术上讲,是独立asio)在TCP/IP上读/写字节,它也通过了单元测试
  • 当我尝试将A和B放在一起时,A开始接收没有发送的消息
  • 我想知道的是为什么,以及我能做些什么

有关代码A的更多详细信息:

代码A主要是C代码,使用ioctl、fnctl和unistd

首先,我打开序列号:

// Flag explanation:
//  - O_RDWR
//     = read & write
//     (O_RDONLY = read-only)
//     (O_WRONLY = write-only)
//  - O_NOCTTY
//     = if the path points to a terminal, that terminal will
//       not become the controlling terminal for the process
//  - O_NONBLOCK
//     = read/write requests are non-blocking, and return failure status instead of waiting
_filestream = ::open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NONBLOCK);
在检查串口是否成功打开后,我配置了UART

// Get options currently used by the USART
termios options;
tcgetattr(_filestream, &options);

// Set control options
{
    // Set baudrate
    cfsetispeed(&options, static_cast<speed_t>(baudrate));
    cfsetospeed(&options, static_cast<speed_t>(baudrate));

    // Enable receiver (those flags must always be set)
    //  CLOCAL  = ignore modem status lines
    //  CREAD   = enable receiver
    options.c_cflag |= (CLOCAL | CREAD);

    // Set character size
    //  CSIZE   = bitmask for all sizes
    //  CS8     = specific flag for 8-bit
    options.c_cflag &= ~static_cast<unsigned int>(CSIZE);
    options.c_cflag |= CS8;

    // Disable parity bit
    //  PARENB = parity enable flag
    options.c_cflag &= ~static_cast<unsigned int>(PARENB);

    // Set number of stop bits
    //  CSTOPB = use 2 stop bits insteqd of 1
    options.c_cflag &= ~static_cast<unsigned int>(CSTOPB);
}


// Set local options
{
    // Make sure to use raw input (pass character exactly as they are received)
    // and not canonical input (which is line-oriented)
    //  ICANON  = enable canonical input
    //  ECHO    = enable echoing input characters
    //  ECHOE   = make echo erases some characters
    //  ISIG    = enable some signals
    options.c_lflag &= ~static_cast<unsigned int>(ICANON | ECHO | ECHOE | ISIG);
}


// Set input options
{
    // Enable software flow control
    //  IXON    = Enable software flow control (outgoing)
    //  IXOFF   = Enable software flow control (incoming)
    //  IXOFF   = Allow any character to start flow again
    options.c_iflag |= (IXON | IXOFF | IXANY);
}


// Set output options
{
    // Choose raw output
    //  OPOST = choose postprocess output
    options.c_oflag &= ~static_cast<unsigned int>(OPOST);
}


// Set options to use for the USART
//  TCSANOW = change attributes immediately
tcsetattr(_filestream, TCSANOW, &options);
然后查看状态,检查一切是否正常

要知道有多少字节可供读取,我执行以下操作:

int status = write(_filestream, &byte_array, array_size);
int nbAvailable = 0;
ioctl(_filestream, FIONREAD, &nbAvailable);
uint8_t c;
auto status = ::read(_filestream, &c, 1);
asio::io_context _ioContext;
asio::ip::tcp::resolver::query query(remoteIP, remotePort);
asio::ip::tcp::resolver resolver (_ioContext);

asio::error_code errCode;
asio::ip::tcp::resolver::results_type _endPoints = resolver.resolve(query, errCode);

if (errCode)
{
    std::cerr << "Cannot resolve IP/port for the connection" << std::endl;
        exit(0);
}
要实际读取这些字节,我需要执行以下操作:

int status = write(_filestream, &byte_array, array_size);
int nbAvailable = 0;
ioctl(_filestream, FIONREAD, &nbAvailable);
uint8_t c;
auto status = ::read(_filestream, &c, 1);
asio::io_context _ioContext;
asio::ip::tcp::resolver::query query(remoteIP, remotePort);
asio::ip::tcp::resolver resolver (_ioContext);

asio::error_code errCode;
asio::ip::tcp::resolver::results_type _endPoints = resolver.resolve(query, errCode);

if (errCode)
{
    std::cerr << "Cannot resolve IP/port for the connection" << std::endl;
        exit(0);
}
然后查看状态,检查一切是否正常

完成后,我只需关闭文件流:

close(_filestream);

有关代码B的更多详细信息:

没什么好说的,首先我这样做:

int status = write(_filestream, &byte_array, array_size);
int nbAvailable = 0;
ioctl(_filestream, FIONREAD, &nbAvailable);
uint8_t c;
auto status = ::read(_filestream, &c, 1);
asio::io_context _ioContext;
asio::ip::tcp::resolver::query query(remoteIP, remotePort);
asio::ip::tcp::resolver resolver (_ioContext);

asio::error_code errCode;
asio::ip::tcp::resolver::results_type _endPoints = resolver.resolve(query, errCode);

if (errCode)
{
    std::cerr << "Cannot resolve IP/port for the connection" << std::endl;
        exit(0);
}
线程本身是一个循环,在该循环中,使用
\u套接字读取字节。读取某些()
然后移动到受互斥保护的数组,或从另一个受互斥保护的数组移动,然后使用
\u套接字发送。写入某些()


当我将这两个代码放在一起时会发生什么:

串行端口设备当前已拔出,我希望每次检查串行端口有多少字节可用时,
nbAvailable
都为0,但事实并非如此,在不应该的情况下会收到很多字节

据我所知,这似乎是
asio
对我正在使用的序列进行操作的结果。这并不是那么牵强,因为除了TCP/IP功能外,
asio
还具有串行端口i/o功能,所有证据都表明:

  • 这些问题仅在TCP/IP通信开始时出现
  • 对_socket.write_some()调用进行注释可消除此问题

我想知道的:


为什么
asio
会干扰我的串行端口通信,而我只使用它的TCP/IP设备?有什么办法可以解决这个问题吗?

“为什么asio会干扰……”——你对情况的分析可能是错误的,因为你所说的不应该有“干扰”。根据代码片段,代码中的一个明显缺陷是串行终端的初始化不正确且不完整。See和@Sawsdust感谢您的反馈和链接(比我最初使用的在线资源更清晰)。我检查了它们,我想我修复了初始化(见上文)。不幸的是,我的问题仍然存在,我仍然相信这里有干扰。我已经在上面添加了更多的细节来解释我为什么这么认为。非规范模式还需要定义VMIN和VTIME成员,以及清除一些其他属性。看见您的代码片段不构成一个。您还可以提供有关运行时环境和软件版本的详细信息。您的代码是否验证每个系统调用的返回值以检测错误/问题?