简体   繁体   English

无法通过串口接收字节但可以传输字节

[英]Can't receive bytes over serial port but can transfer bytes

I have a simple application that runs on an embedded device running Linux that sends and receives bytes over UART.我有一个简单的应用程序,它运行在运行 Linux 的嵌入式设备上,它通过 UART 发送和接收字节。 I have a minicom session open in my host machine to which the RS-232 USB cable is connected.我在连接 RS-232 USB 电缆的主机中打开了一个 minicom 会话。

So far, I am only able to send data from the app to the serial session but not the other way around.到目前为止,我只能将数据从应用程序发送到串行会话,但不能反过来。 This should indicate my UART configs including the baud rate are fine since I can send the data at least, and the serial session is also running at the same baud rate.这应该表明我的 UART 配置(包括波特率)很好,因为我至少可以发送数据,并且串行会话也以相同的波特率运行。

select() returns 0 which indicates the call timed out. select()返回 0 表示调用超时。 Is it implying the socket is busy at the moment and can't be used?是不是暗示socket现在很忙,不能使用?

Opening a socket打开一个套接字

#DEVICE_PORT      "/dev/ttyHSL0"

static int buildFlowControl(Enum_FlowCtrl fc, struct termios* term)
{
    if (NO_FLOW_CTRL == fc)
    {
        term->c_cflag |= CRTSCTS;           
        term->c_iflag &= ~(IXON | IXOFF);
    }
    else if (FC_RTSCTS == fc)
    {
        term->c_cflag &= ~CRTSCTS;
        term->c_iflag |= (IXON | IXOFF);
    }
    else if (FC_XONXOFF == fc)
    {
        term->c_cflag &= ~CRTSCTS;
        term->c_iflag &= ~(IXON | IXOFF);
    }else{
        return -1;
    }
    
    return 0;
}
int UART_Open(const char* port, unsigned int baudrate, Enum_FlowCtrl flowCtrl)
{
    int fd;
    struct termios term;
    
    fd = open(port, O_RDWR);
    
    bzero(&term, sizeof(term));
    cfmakeraw(&term);
    term.c_cflag |= CREAD;
    tcgetattr(fd, &term);
    
    buildBaudrate(baudrate, &term);
    buildDataBit(8, &term);
    buildStopBit(1, &term);
    buildParity(PB_NONE, &term);
    buildFlowControl(flowCtrl, &term);

    term.c_iflag &= ~ICRNL;
    term.c_iflag &= ~INLCR;
    term.c_iflag |= IGNBRK;

    term.c_oflag &= ~OCRNL;
    term.c_oflag &= ~ONLCR;
    term.c_oflag &= ~OPOST;

    term.c_lflag &= ~ICANON;
    term.c_lflag &= ~ISIG;
    term.c_lflag &= ~IEXTEN;
    term.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ECHOCTL|ECHOPRT|ECHOKE);

    term.c_cc[VMIN] = 5;    // minimum received bytes before unblocking
    term.c_cc[VTIME] = 100; // 10 SECONDS timeout

    tcsetattr(fd, TCSANOW, &term);
    tcflush(fd, TCIOFLUSH);

    return fd;
}

Main主要的

int socketFileDescriptor;

int main(void argc, char *argv[])
{
   int baudRate = atoi(argv[1]);
   socketFileDescriptor = UART_Open(DEVICE_PORT, baudRate, NO_FLOW_CTRL);   

   if (pthread_create(&threadUartRcv, NULL, UartRcv, NULL) != 0)
   { 
      // error handling
   }  ​
   while(true);  
}

UART receive function: UART接收功能:

static void* UartRcv(void* arg)
{
    int ret;
    fd_set fdset;
    struct timeval timeout = {5, 0};    
    char buffer[100] = {0};

    FD_ZERO(&fdset); 
    FD_SET(socketFileDescriptor, &fdset); 
    while(true)
    {
        ret = select(socketFileDescriptor + 1, &fdset, NULL, NULL, &timeout); // waits for 5 seconds for any activity on socket

        // reset the time value back to the original since it's reset by select()
        timeout.tv_sec = 5;
        
        if (ret == -1)
        {
            printf("< failed to select >\n");
            exit(-1);
        }
        else if (ret == 0)
        {
            printf("< no data >\n");
        }
        else
        {
            if (FD_ISSET(socketFileDescriptor, &fdset)) 
            {
                do {
                    memset(buffer, 0x0, sizeof(buffer));
                    ret = read(socketFileDescriptor, buffer, 100);
                    sleep(3);
                } while (true);
            }
        }
    }
}

I was able to send data from minicom by disabling the Hardware Flow Control.通过禁用硬件流控制,我能够从 minicom 发送数据。 I'm not quite certain as to why would that solve given RTS/CTS is enabled我不太确定为什么在启用 RTS/CTS 的情况下会解决这个问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM