Application can't send through UART

I’m having trouble understanding why my application is unable to transmit a string through UART.

I am attempting to transmit a string via UART_B between two Colibri iMX8X devices. There are no issues when sending strings directly through the UART port. However, when utilizing the termios library, the message is sent but not received.

If I send a message through the program using termios, and then send another message (e.g., “echo test > /dev/colibri-uartb”), not only does the string “test” appear but also all the previously sent messages.

My initial guess was that boost library was overriding the function write, but after ensuring the right library, the problem remains.

code example:

    int enviaar(char *msg)
    {
        // char buf_rx[100];
        char buf_tx[100];
        const char *device = "/dev/colibri-uartb";
        struct termios tty;
        int fd;
        int flags = O_RDWR | O_NOCTTY | O_NDELAY; /* O_RDWR Read/write access to the serial port */
                                                  /* O_NOCTTY No terminal will control the process */
                                                  /* O_NDELAY Use non-blocking I/O */

        /*------------------------------- Opening the Serial Port -------------------------------*/
        fd = open(device, flags);

        if (fd == -1)
        {
            printf("\n Failed to open port! ");
            return -1;
        }

        tcgetattr(fd, &tty); /* Get the current attributes of the Serial port */

        cfsetispeed(&tty, B115200); 
        cfsetospeed(&tty, B115200); 

        tty.c_cflag &= ~PARENB;  /* Disables the Parity Enable bit(PARENB)  */
        tty.c_cflag &= ~CSTOPB;  /* Clear CSTOPB, configuring 1 stop bit    */
        tty.c_cflag &= ~CSIZE;   /* Using mask to clear data size setting   */
        tty.c_cflag |= CS8;      /* Set 8 data bits                         */
        tty.c_cflag &= ~CRTSCTS; /* Disable Hardware Flow Control           */
        tty.c_cflag |= CREAD;// | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
        tty.c_lflag &= ~ICANON;
        tty.c_lflag &= ~ECHO;                                                        // Disable echo
        tty.c_lflag &= ~ECHOE;                                                       // Disable erasure
        tty.c_lflag &= ~ECHONL;                                                      // Disable new-line echo
        tty.c_lflag &= ~ISIG;                                                        // Disable interpretation of INTR, QUIT and SUSP
        tty.c_iflag |= (IXON | IXOFF | IXANY);                                      // Turn off s/w flow ctrl
        tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); // Disable any special handling of received bytes

        if ((tcsetattr(fd, TCSANOW, &tty)) != 0)
        { /* Write the configuration to the termios structure*/
            printf("Error! Can't set attributes.\n");
            return -1;
        }
        else
        {
            printf("All set! \n");
        }

        tcflush(fd, TCIFLUSH);

        strncpy(buf_tx, msg, sizeof(buf_tx));

        int result = write(fd, &msg[0], sizeof(msg));
        if (result == -1)
        {
            printf("Error: %s\n", strerror(errno));
            return -1;
        }
        else
        {
            printf("%d bytes sent\n", result);
        }
        close(fd);
    }

Could you please specify how exactly you are “sending strings directly through the UART port”? Are you doing it from the Torizon core console or from the same container console where you are running your termios app?

1 Like

I’ve also found some issues with your code:

int result = write(fd, &msg[0], sizeof(msg));
The msg is pointeer and its size is 8 on ARM64 platforms. You should use strlen(msg) to get the correct length of the string.

You have enabled software flow control with (IXON | IXOFF | IXANY) . Make sure the receiving end also has software flow control enabled, or you might face issues with some characters.
If the flow control is not mandatory I’d disable it
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Disable software flow control

1 Like

Captain Obvious says to be certain you have a Null Modem cable between the two ports. Mini-testers are incredibly useful.

You can find them much cheaper than this place on-line.

The lights will flash so you can see transmission. For most of them, green is logic on one side and red is logic on both. Read the little card that comes with yours. The 25-pin versions work way better than the 9-pin.

1 Like

Hi Alex,
Turn’s out, the problem with the code was two bit masks (ICANON and ISIG). After disable it, it works just fine.
Thanks for the help.