You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 04:24:55