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成员,以及清除一些其他属性。看见您的代码片段不构成一个。您还可以提供有关运行时环境和软件版本的详细信息。您的代码是否验证每个系统调用的返回值以检测错误/问题?