linuxserial-portembedded-linuxuarttermios

writting 0D 0A insted of 0A when I tried to write into uart


The following code configures UART port.

const char *UART2_path="/dev/ttymxc2";
int UART2;


void UART2_open(const char *UART2_path)
{
    int flags = O_RDWR | O_NOCTTY ;
                                                                            
    UART2 = open(UART2_path,flags);

    tcgetattr(UART2, &ttyurt); //Get the current attributes of the serial port //
    //Setting baud rate (input and output)
    cfsetispeed(&ttyurt, B115200);
    cfsetospeed(&ttyurt, B115200);
    ttyurt.c_cflag &= ~PARENB;   // Disables the Parity Enable bit(PARENB)  //
    ttyurt.c_cflag &= ~CSTOPB;   // Clear CSTOPB, configuring 1 stop bit    //
    ttyurt.c_cflag &= ~CSIZE;    // Using mask to clear data size setting   //
    ttyurt.c_cflag |=  CS8;      // Set 8 data bits                         //
    ttyurt.c_cflag &= ~CRTSCTS;  // Disable Hardware Flow Control           //
    
    tcsetattr(UART2, TCSANOW, &ttyurt); // Write the configuration to the termios structure//

    tcflush(UART2, TCIFLUSH);
}

//---------
buffer[8]={0x1f,0x0a,0x1a,0x89,0x85,0xbf,0x36,0x40};

write(UART2,&buffer,strlen(buffer));//sending on uart

expected output==>1f0a8985bf3640
actual output  ==>1f0d0a8985bf3640  

I'm able to send data, but for some reason 0x0A sent characters are received as 0x0D 0x0A. I'm fairly sure something in this port configuration is doing this.

extra byte 0d before 0a?


Solution

  • writting 0D 0A insted of 0A when I tried to write into uart

    That appears to caused by a termios (mis)configuration that is inappropriate for your situation. The termios layer is capable of translating/expanding each occurrence of \n to \r\n for output (i.e. the ONLCR attribute, which is typically enabled by default).

    The following code configures UART port.

    Your program accesses a serial terminal (i.e. /dev/tty...) rather than a "UART port". There are several layers of processing in between your program and the UART hardware. See Linux serial drivers

    Your initialization code is properly implemented (i.e. per Setting Terminal Modes Properly), but it is just the bare minimum that sets only the serial line parameters to 115200 8N1 and no HW flow control. Absolutely no other termios attributes are specified, which means that your program will use whatever previous (random?) settings (such as the ONLCR attribute), and may occasionally misbehave.

    The most important consideration when using a serial terminal and termios configuration is determining whether the data should be handled in canonical (as lines of text) or non-canonical (aka raw or binary) mode. Canonical mode provides additional processing to facilitate the reading/writing of text as lines, delimited by End-of-Line characters. Otherwise syscalls are performed for an arbitrary number of bytes. See this answer for more details.

    Your output data appears to be not (ASCII) text, so presumably you want to use non-canonical (aka raw) mode. For raw output, your program should specify:

    ttyurt.c_oflag &= ~OPOST;
    

    This will inhibit any data conversion on output by termios.

    But your termios initialization is also incomplete for reading.
    For a proper and concise termios initialization for non-canonical mode, see this answer.
    If instead you need canonical mode, then refer to this answer.