0

Having problems reading data from Serial port using the following method which consists of two threads which access the same serial port.

While tx thread works reliable due, there is always data to be sent, the rx does not work if data is not present (RX/received) soon after application starts

Both Threads have similar structure to use the "select" for transmitting or receiving data. Any suggestion to debug further why the select does not work over time for receiving data.

void SerialEngine:: thread_rx()
{

    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    int count_tmp=0;
    uint8_t read_serial_byte[1];
    uint8_t data;
    int serial_index = 0, rx_state = 0, gps_index = 0, hmi_index = 0 , GPS_HMI = 0;
    uint8_t read_serial[2500]={0};

    rfd = open(portname, O_RDWR | O_NOCTTY | O_SYNC | O_NDELAY | O_NONBLOCK);
    if (rfd < 0) {
        printf("Error opening  read %s: %s\n", portname, strerror(errno));}

    

    while(!signaled)
    {
        //printf("Recval1 is %d \n", recval1);
        FD_ZERO(&readfds);
        FD_SET(rfd, &readfds);
        //printf("Xbee Rx trying again \n");
        recval1 = select(rfd + 1, &readfds, NULL, NULL, &tv); //Reading Data from Xbee

        if ((recval1 != -1) && (recval1 != 0))
        {
            if (FD_ISSET(rfd, &readfds))
            {
                        int read_index = read(rfd, read_serial_byte,1);

                        //printf("Read Index is %d \n", read_index);

            }
        }
        else if (recval1== -1)
        {
        
        }
        else if (recval1 == 0)
        {
        
        }
        
    }
}

void SerialEngine:: thread_serial_tx()
{

    struct timeval tv;
    tv.tv_sec = 5;
    tv.tv_usec = 0;

    wfd = open(portname, O_RDWR | O_NOCTTY | O_SYNC | O_NDELAY | O_NONBLOCK);
    if (wfd < 0) {
        printf("Error opening write %s: %s\n", portname, strerror(errno));}
    Set_Serial_Atributes.set_interface_attribs(wfd, B115200);

    FD_ZERO(&writefds);
    FD_SET(wfd, &writefds);
    recval2 = select(wfd + 1, NULL, &writefds, NULL, &tv); //Writing Data to Xbee


    while(!signaled)
    {


        if ((recval2 != -1) && (recval2 != 0))
        {
            if((!tx_queue.empty()))
            {
                tx_string_check = tx_queue.front();
                int tx_str_len = tx_string_check.size();
                int bytes_written = write(wfd,hmi_serial_check, tx_str_len);
                tx_queue.pop();                                                                                                                                                               486,2         57%
            }
        }
        else if (recval1== -1)
        {
        
        }
        else if (recval1 == 0)
        {
        
        }
        
    }
}
jpvans
  • 59
  • 6
  • 1
    *"rx does not work"* -- That is not an adequate description of symptoms. FYI your program is *several* layers (and buffers) removed from the hardware. "Nonblocking I/O" in this case means that your program is polling the system buffers (and not the UART). A **read()** syscall to fetch just one byte at a time is slow & expensive. Overall your code is computationally intensive. You could get the same (or better) results with less processing cost using blocking I/O and a proper *termios* configuration. IOW nonblocking I/O does not enable your program to get the data any faster/sooner. – sawdust Jun 28 '20 at 20:32
  • @sawdust Thanks for the feedback. Can you advise/provide a better configuration for the blocking way to read data? the packets are not big but I have multiple clients sending data to this serial link (XBEE). I do read 1 byte at a time for header/checksum validation. When there is an active client sending data, the thread for RX works fine, but if there is no active client, the "recval1" value is 0 and does not change when a client starts sending data. I am wondering if it is because to: - Hardware Control? - issue with the "rfd" - sleep/too fast FD_ZERO/FD_SET commands? – jpvans Jun 29 '20 at 01:03
  • *"Can you advise/provide a better configuration for the blocking way to read data?"* -- Take a look at [this code](https://stackoverflow.com/questions/54392470/how-to-handle-buffering-serial-data/54394770#54394770). A VTIME of 1 and VMIN set to the largest expected message would be appropriate settings. – sawdust Jun 29 '20 at 19:40

0 Answers0