epoll 读串口例子
时间: 2023-07-23 18:10:09 浏览: 250
以下是一个使用 epoll 读取串口数据的示例代码,供您参考:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/epoll.h>
#define MAX_EVENTS 10
#define BUF_SIZE 256
int set_interface_attribs(int fd, int speed) {
struct termios tty;
memset(&tty, 0, sizeof(tty));
if (tcgetattr(fd, &tty) != 0) {
printf("Error %d from tcgetattr\n", errno);
return -1;
}
cfsetospeed(&tty, (speed_t)speed);
cfsetispeed(&tty, (speed_t)speed);
tty.c_cflag |= (CLOCAL | CREAD); // ignore modem controls
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; // 8-bit characters
tty.c_cflag &= ~PARENB; // no parity bit
tty.c_cflag &= ~CSTOPB; // only need 1 stop bit
tty.c_cflag &= ~CRTSCTS; // no hardware flowcontrol
// setup for non-canonical mode
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tty.c_oflag &= ~OPOST;
// fetch bytes as they become available
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 1;
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
printf("Error %d from tcsetattr\n", errno);
return -1;
}
return 0;
}
int set_blocking(int fd, int should_block) {
struct termios tty;
memset(&tty, 0, sizeof(tty));
if (tcgetattr(fd, &tty) != 0) {
printf("Error %d from tggetattr\n", errno);
return -1;
}
tty.c_cc[VMIN] = should_block ? 1 : 0;
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
printf("Error %d setting term attributes\n", errno);
return -1;
}
return 0;
}
int main() {
int fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0) {
printf("Error %d opening serial port\n", errno);
return -1;
}
if (set_interface_attribs(fd, B9600) < 0) {
printf("Error setting serial port attributes\n");
return -1;
}
if (set_blocking(fd, 0) < 0) {
printf("Error setting serial port blocking mode\n");
return -1;
}
int efd = epoll_create1(0);
if (efd == -1) {
printf("Error %d creating epoll instance\n", errno);
return -1;
}
struct epoll_event ev, events[MAX_EVENTS];
ev.events = EPOLLIN;
ev.data.fd = fd;
if (epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev) == -1) {
printf("Error %d adding file descriptor to epoll instance\n", errno);
return -1;
}
char buf[BUF_SIZE];
while (1) {
int n = epoll_wait(efd, events, MAX_EVENTS, -1);
if (n == -1) {
printf("Error %d from epoll_wait\n", errno);
break;
}
for (int i = 0; i < n; i++) {
if (events[i].events & EPOLLIN) {
int len = read(fd, buf, BUF_SIZE);
if (len > 0) {
buf[len] = 0;
printf("Received %d bytes: %s\n", len, buf);
}
}
}
}
close(fd);
close(efd);
return 0;
}
```
此示例代码使用 epoll 监听串口的 EPOLLIN 事件,当有数据可读时,使用非阻塞读取方式从串口读取数据。在读取到数据后,将其打印到控制台上。同时,该示例代码也设置了串口的基本参数,以确保能够正确地读取串口数据。
阅读全文