我在我的电脑上使用串口通过串行通信与另一个设备通信。当我将我的 Ubuntu 18.04 更新到 Ubuntu 22.04 时,我遇到了串行端口通信问题。只传输了 16 个字节,其余消息丢失,无法传输到主机。
我认为这个问题的原因可能是以下任何一个或其他原因:
FIFO 缓冲区:如果 FIFO 缓冲区已启用且其大小适合您的用例。
中断处理:串口中断处理是否正常。
串口驱动程序:如果您使用适合您的硬件的串口驱动程序。
内核版本:如果您使用的内核版本已知存在串行端口通信问题。
硬件问题:如果您的串行端口或您正在与之通信的设备有任何硬件问题。
我认为问题的原因是在新版本的 Ubuntu 中,必须更改一些设置。我正在尝试增加 FIFO 缓冲区并增加中断的优先级,但没有成功。
关于如何处理这个问题有什么建议吗?
这是我打开串口的方式:
int32_t fd;
uint32_t flags = O_RDWR;
fd = open("/dev/ttyS2", flags);
if (fd < 0)
printf("open() failed for device: %s. Reason: %s", strerror(errno));
// Create new termios struct, we call it 'tty' for convention
struct termios tty;
memset(&tty, 0, sizeof(tty));
// Read in existing settings, and handle any error
if (tcgetattr(fd, &tty) != 0)
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
//!---Control Modes---
/// diff parity settings start
// add new flag for mark parity to be zero every time a.k.a. SPACE
tty.c_cflag |= PARENB | CMSPAR;
tty.c_cflag &= ~PARODD;
/// diff parity settings end
// Clear stop field, only one stop bit used in communication (most common)
tty.c_cflag &= ~CSTOPB;
// 8 bits per byte
tty.c_cflag |= CS8;
// Disable RTS/CTS hardware flow control
tty.c_cflag &= ~CRTSCTS;
// Turn on READ & ignore ctrl lines (CLOCAL = 1)
tty.c_cflag |= CREAD | CLOCAL;
//!---Local Modes---
// disable canonical mode
tty.c_lflag &= ~ICANON;
// disable all kind of echo
// Disable echo
tty.c_lflag &= ~ECHO;
// Disable erasure
tty.c_lflag &= ~ECHOE;
// Disable new-line echo
tty.c_lflag &= ~ECHONL;
// Disable interpretation of INTR, QUIT and SUSP
tty.c_lflag &= ~ISIG;
//!---Input Modes---
// Turn off software flow ctrl
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
// Disable any special handling of received bytes
tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL);
//!---Output Modes---
// Prevent special interpretation of output bytes (e.g. newline chars)
tty.c_oflag &= ~OPOST;
// Prevent conversion of newline to carriage return/line feed
tty.c_oflag &= ~ONLCR;
// Mark parity errors in received messages
tty.c_iflag |= INPCK; // Enable parity checking
tty.c_iflag |= PARMRK; // Enable in-band marking
// Make sure input parity errors are not ignored
tty.c_iflag &= ~IGNPAR;
//!---VMIN and VTIME---
/**
VMIN = 0, VTIME = 0:
No blocking, return immediately with what is available.
VMIN > 0, VTIME = 0:
This will make read() always wait for bytes (exactly
how many is determined by VMIN), so read() could block
indefinitely.
VMIN = 0, VTIME > 0:
This is a blocking read of any number chars with a maximum
timeout (given by VTIME). read() will block until either
any amount of data is available, or the timeout occurs.
VMIN > 0, VTIME > 0:
Block until either VMIN characters have been received,
or VTIME after first character has elapsed. Note that
the timeout for VTIME does not begin until the first
character is received.
**/
// Wait for up to 1 deciseconds, returning as soon as any data is received.
// 10 deciseconds = 1 sec
tty.c_cc[VTIME] = 0;
tty.c_cc[VMIN] = 0;
//!---Baud Rate---
// Set in/out baud rate to be 19200
cfsetispeed(&tty, B19200);
cfsetospeed(&tty, B19200);
//!---Saving termios---
// Save tty settings, also checking for error
if (tcsetattr(_fd, TCSANOW, &tty) != 0)
printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));