Linux Ubuntu开机首次启动时UART接收数据异常问题求助
UART收发Mavlink消息开机首次启动停滞问题
我开发的控制台应用通过UART收发Mavlink消息,但每次开机后首次启动程序会出现停滞现象。经上千次测试,每次开机都需要先使用VSCode的Serial Monitor或Hterm抓取数据包并关闭,程序才能正常运行,后续启动均无问题。
应用主要基于C语言开发,采用termios配置UART,同时使用C++标准库的线程与队列功能。怀疑问题出在Linux内核缓冲区,但不确定是否正确。以下是我编写的UART库相关函数代码:
#include "uart.h" int UART0_Open(int fd, char *port) { fd = open(port, O_RDWR|O_NOCTTY|O_NDELAY); if (fd == FAIL) { perror("Can't open serial port!\n"); return FAIL; } if (fcntl(fd, F_SETFL, 0) < 0) { printf("Fcntl fail!\n"); return FAIL; } else { printf("Fcntl = %d\n", fcntl(fd, F_SETFL,0)); } if (isatty(STDIN_FILENO) == 0) { printf("Standard input is not a terminal device\n"); return FAIL; } else { printf("Isatty success\n"); } printf("fd->open=%d\n", fd); return fd; } uart_status_t UART0_Set(int fd, uart_baudrate_t baudrate, uart_flow_control_t flow_ctrl, uart_databits_t databits, uart_stopbits_t stopbits, uart_parity_t parity) { int i; int status; struct termios options; if(tcgetattr(fd, &options)!=0) { perror("Setup UART\n"); return FAIL; } /* Baudrate settings */ switch(baudrate) { case BAUD_9600: { cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); break; } case BAUD_19200: { cfsetispeed(&options, B19200); cfsetospeed(&options, B19200); break; } case BAUD_38400: { cfsetispeed(&options, B38400); cfsetospeed(&options, B38400); break; } case BAUD_115200: { cfsetispeed(&options, B115200); cfsetospeed(&options, B115200); break; } case BAUD_230400: { cfsetispeed(&options, B230400); cfsetospeed(&options, B230400); break; } default: { perror("Unsupported UART baudrate!\n"); return FAIL; break; } } options.c_cflag |= CLOCAL; options.c_cflag |= CREAD; /* Flow Control settings */ switch(flow_ctrl) { case NO_FLOW_CTRL: // No flow control is used { options.c_cflag &= ~CRTSCTS; break; } case HW_FLOW_CTRL: // Hardware flow control { options.c_cflag |= CRTSCTS; break; } case SW_FLOW_CTRL: // Software flow control { options.c_cflag |= IXON | IXOFF | IXANY; break; } } options.c_cflag &= ~CSIZE; // Mask other flag bits /* Databits settings */ switch (databits) { case DATABIT_5: { options.c_cflag |= CS5; break; } case DATABIT_6: { options.c_cflag |= CS6; break; } case DATABIT_7: { options.c_cflag |= CS7; break; } case DATABIT_8: { options.c_cflag |= CS8; break; } default: fprintf(stderr, "Unsupported data size\n"); return FAIL; } /* Parity settings */ switch(parity) { case PARITY_NO: //No Parity bit { options.c_cflag &= ~PARENB; options.c_iflag &= ~INPCK; break; } case PARITY_ODD: //Odd parity check { options.c_cflag |= (PARODD | PARENB); options.c_iflag |= INPCK; break; } case PARITY_EVEN: //Even parity check { options.c_cflag |= PARENB; options.c_cflag &= ~PARODD; options.c_iflag |= INPCK; break; } case PARITY_SPACE: //Space { options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; break; } default: { fprintf(stderr, "Unsupported parity\n"); return FAIL; } } //Set stop bit switch (stopbits) { case STOPBIT_1: { options.c_cflag &= ~CSTOPB; break; } case STOPBIT_2: { options.c_cflag |= CSTOPB; break; } default: fprintf(stderr,"Unsupported stop bits\n"); return FAIL; } //Modify output mode, RAW data mode options.c_oflag &= ~OPOST; //set the minimum waiting time and minimum receiving bytes before unblocking options.c_cc[VTIME] = 1; options.c_cc[VMIN] = 1; tcflush(fd,TCIFLUSH); //active the configuration if(tcsetattr(fd, TCSANOW, &options) != 0) { perror("com set error!\n"); return FAIL; } /* Delete this later */ int bd = cfgetospeed(&options); if(tcgetattr(fd, &options) != 0) { perror("UART config not valid!\n"); return FAIL; } printf("Configured baudrate: %d\n", UART0_GetOutputBaudrate(&options)); return SUCCESS; } int UART0_Recv(int fd, char *rcv_buf, int data_len) { int len,fs_sel; fd_set fs_read; struct timeval time; FD_ZERO(&fs_read); FD_SET(fd, &fs_read); time.tv_sec = 10; time.tv_usec = 0; // Using Select() function to realize the multiply channels' communication // fs_sel = select(fd+1, &fs_read, NULL, NULL, &time); // if(fs_sel) // { // len = read(fd, rcv_buf, data_len); // return(len); // } // else // { // return FAIL; // } return read(fd, rcv_buf, data_len); } int UART0_Send(int fd, char *send_buf, int data_len) { int len = 0; len = write(fd, send_buf, data_len); if(len == data_len) { return(len); } else { tcflush(fd,TCOFLUSH); return FAIL; } } void UART0_Close(int fd) { close(fd); } uart_baudrate_t UART0_GetInputBaudrate(struct termios *t) { int bd = cfgetispeed(t); switch(bd) { case B9600: { return BAUD_9600; } case B19200: { return BAUD_19200; } case B38400: { return BAUD_38400; } case B115200: { return BAUD_115200; } case B230400: { return BAUD_230400; } default: { return FAIL; } } } uart_baudrate_t UART0_GetOutputBaudrate(struct termios *t) { int bd = cfgetospeed(t); switch(bd) { case B9600: { return BAUD_9600; } case B19200: { return BAUD_19200; } case B38400: { return BAUD_38400; } case B115200: { return BAUD_115200; } case B230400: { return BAUD_230400; } default: { return FAIL; } } }
请问是否有人遇到过类似问题?
内容的提问来源于stack exchange,提问作者filipembedded
相关产品推荐
相关产品推荐

