Linux串口编程中的阻塞是指在进行串口通信时,程序会等待直到某个条件满足才会继续执行。阻塞操作通常用于同步I/O操作,即程序在执行I/O操作时会暂停,直到操作完成。
通过设置超时时间,可以在指定时间内没有数据到达时退出阻塞状态。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
int main() {
int fd;
struct termios options;
// 打开串口设备
fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
perror("open_port: Unable to open /dev/ttyS0");
return -1;
}
// 获取当前串口配置
tcgetattr(fd, &options);
// 设置波特率
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
// 设置数据位、停止位和校验位
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// 设置输入模式
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
// 设置输出模式
options.c_oflag &= ~OPOST;
// 应用配置
tcsetattr(fd, TCSANOW, &options);
// 设置读取超时
struct timeval timeout;
timeout.tv_sec = 5; // 5秒超时
timeout.tv_usec = 0;
tcsetattr(fd, TCSANOW, &timeout);
char buffer[256];
int n = read(fd, buffer, sizeof(buffer));
if (n > 0) {
buffer[n] = '\0';
printf("Received data: %s\n", buffer);
} else {
printf("Read timeout or error occurred.\n");
}
close(fd);
return 0;
}
通过设置串口为非阻塞模式,可以在没有数据到达时立即返回。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
int main() {
int fd;
struct termios options;
// 打开串口设备
fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
perror("open_port: Unable to open /dev/ttyS0");
return -1;
}
// 获取当前串口配置
tcgetattr(fd, &options);
// 设置波特率
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
// 设置数据位、停止位和校验位
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// 设置输入模式
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
// 设置输出模式
options.c_oflag &= ~OPOST;
// 设置非阻塞模式
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 0;
// 应用配置
tcsetattr(fd, TCSANOW, &options);
char buffer[256];
int n;
while (1) {
n = read(fd, buffer, sizeof(buffer));
if (n > 0) {
buffer[n] = '\0';
printf("Received data: %s\n", buffer);
} else if (n == -1 && errno == EAGAIN) {
// 没有数据到达,继续循环
usleep(100000); // 等待100毫秒
} else {
perror("read");
break;
}
}
close(fd);
return 0;
}
通过上述方法,可以有效解决Linux串口编程中的阻塞问题,提高程序的响应性和稳定性。
领取专属 10元无门槛券
手把手带您无忧上云