使用poll处理多个串口数据
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/time.h>
#include <unistd.h>
#include <poll.h>
#include <sys/ioctl.h>
#define IMU_SERIAL "/dev/ttyCH9344USB0"
#define ENCODE_SERIAL "/dev/ttyTHS2"
#define IMU_DATA_FILE "/tmp/imu.bin"
#define ENCODE_DATA_FILE "/tmp/encode.bin"
#define POLL_FD_NUM_MAX 2
#define RECVBUF_LEN_MAX 1024*1024
void close_serial(int *fd) {
close(*fd);
*fd = -1;
return;
}
void close_file(FILE **fd) {
fclose(*fd);
*fd = NULL;
return;
}
void free_buf(void **buf) {
free(*buf);
*buf = NULL;
return;
}
int ParseBaudRate(int baud)
{
int value = -1;
if (baud == B50 || baud == 50)
{
value = B50;
}
else if (baud == B75 || baud == 75)
{
value = B75;
}
else if (baud == B110 || baud == 110)
{
value = B110;
}
else if (baud == B134 || baud == 134)
{
value = B134;
}
else if (baud == B150 || baud == 150)
{
value = B150;
}
else if (baud == B200 || baud == 200)
{
value = B200;
}
else if (baud == B300 || baud == 300)
{
value = B300;
}
else if (baud == B600 || baud == 600)
{
value = B600;
}
else if (baud == B1200 || baud == 1200)
{
value = B1200;
}
else if (baud == B1800 || baud == 1800)
{
value = B1800;
}
else if (baud == B2400 || baud == 2400)
{
value = B2400;
}
else if (baud == B4800 || baud == 4800)
{
value = B4800;
}
else if (baud == B9600 || baud == 9600)
{
value = B9600;
}
else if (baud == B19200 || baud == 19200)
{
value = B19200;
}
else if (baud == B38400 || baud == 38400)
{
value = B38400;
}
else if (baud == B57600 || baud == 57600)
{
value = B57600;
}
else if (baud == B115200 || baud == 115200)
{
value = B115200;
}
else if (baud == B230400 || baud == 230400)
{
value = B230400;
}
else if (baud == B460800 || baud == 460800)
{
value = B460800;
}
else if (baud == B500000 || baud == 500000)
{
value = B500000;
}
else if (baud == B576000 || baud == 576000)
{
value = B576000;
}
else if (baud == B921600 || baud == 921600)
{
value = B921600;
}
else if (baud == B1000000 || baud == 1000000)
{
value = B1000000;
}
else if (baud == B1152000 || baud == 1152000)
{
value = B1152000;
}
else if (baud == B1500000 || baud == 1500000)
{
value = B1500000;
}
else if (baud == B2000000 || baud == 2000000)
{
value = B2000000;
}
else if (baud == B2500000 || baud == 2500000)
{
value = B2500000;
}
else if (baud == B3000000 || baud == 3000000)
{
value = B3000000;
}
else if (baud == B3500000 || baud == 3500000)
{
value = B3500000;
}
else if (baud == B4000000 || baud == 4000000)
{
value = B4000000;
}
return value;
}
int open_serial(char *tty_name, int baud) {
int ret = -1;
int fd = -1;
struct termios options;
memset(&options, 0, sizeof(options));
fd = open(tty_name, O_RDWR | O_NOCTTY);
if (fd < 0)
{
printf("open tty failed:%s\n", strerror(errno));
return fd;
}
ret = tcgetattr(fd, &options);
if (ret != 0)
{
printf("tcgetattr() failed:%s\n", strerror(errno));
close_serial(&fd);
return fd;
}
options.c_cflag |= CLOCAL | CREAD;
cfsetspeed(&options, ParseBaudRate(baud));
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~PARENB;
options.c_cflag &= ~PARODD;
options.c_cflag &= ~CSTOPB;
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 0;
tcflush(fd, TCIOFLUSH);
if ((tcsetattr(fd, TCSAFLUSH, &options)) != 0)
{
printf("tcsetattr failed:%s\n", strerror(errno));
close_serial(&fd);
return fd;
}
printf("open tty[%s] success, buad[%d]\n", tty_name, baud);
return fd;
}
int main()
{
int i = 0;
int ret = -1;
int recvlen = -1;
int writelen = -1;
int tty_imufd = -1;
int tty_encodefd = -1;
int fionread_byte = -1;
FILE *imu_fd = NULL;
FILE *encode_fd = NULL;
struct pollfd poll_fd[POLL_FD_NUM_MAX];
imu_fd = fopen(IMU_DATA_FILE, "ab");
if (NULL == imu_fd)
{
printf("open file[%s] failed\n", IMU_DATA_FILE);
return 1;
}
encode_fd = fopen(ENCODE_DATA_FILE, "ab");
if (NULL == encode_fd)
{
printf("open file[%s] failed\n", ENCODE_DATA_FILE);
close_file(&imu_fd);
return 1;
}
char *recv_buf = malloc(RECVBUF_LEN_MAX);
if (recv_buf == NULL)
{
printf("malloc %d failed\n", RECVBUF_LEN_MAX);
close_file(&imu_fd);
close_file(&encode_fd);
return 1;
}
tty_imufd = open_serial(IMU_SERIAL, 460800);
if (tty_imufd < 0)
{
printf("open [%s] failed\n", IMU_SERIAL);
free_buf((void **)&recv_buf);
close_file(&imu_fd);
close_file(&encode_fd);
return 1;
}
tty_encodefd = open_serial(ENCODE_SERIAL, 460800);
if (tty_encodefd < 0)
{
printf("open [%s] failed\n", ENCODE_SERIAL);
free_buf((void **)&recv_buf);
close_file(&imu_fd);
close_file(&encode_fd);
close_serial(&tty_imufd);
return 1;
}
poll_fd[0].fd = tty_imufd;
poll_fd[0].events = POLLIN;
poll_fd[1].fd = tty_encodefd;
poll_fd[1].events = POLLIN;
while(1)
{
ret = poll(poll_fd, POLL_FD_NUM_MAX, 500);
if (ret < 0)
{
printf("poll error[%s]\n", strerror(errno));
continue;
}
for (i = 0; i < POLL_FD_NUM_MAX; i++)
{
if (!(poll_fd[i].events & POLLIN))
{
continue;
}
ioctl(poll_fd[i].fd, FIONREAD, &fionread_byte);
if (fionread_byte <= 0)
{
continue;
}
recvlen = read(poll_fd[i].fd, recv_buf, RECVBUF_LEN_MAX);
if (recvlen < 0)
{
printf("read() error:%s\n", strerror(errno));
memset(recv_buf, 0, RECVBUF_LEN_MAX);
continue;
}
if (poll_fd[i].fd == tty_imufd)
{
writelen = fwrite(recv_buf, sizeof(char), recvlen, imu_fd);
if (writelen != recvlen)
{
printf("writing file falied, writelen_expect: %d, writelen_real: %d\n", recvlen, writelen);
}
}
else if (poll_fd[i].fd == tty_encodefd)
{
writelen = fwrite(recv_buf, sizeof(char), recvlen, encode_fd);
if (writelen != recvlen)
{
printf("writing file falied, writelen_expect: %d, writelen_real: %d\n", recvlen, writelen);
}
}
}
usleep(1000);
}
}