Unexpected results testing serial loopback using echo and cat

27,466

Solution 1

Thanks to the second comment by Bruce, I was able to figure out the problem on my own.

After running stty -a -F /dev/ttyS1, there were 3 options I found to contribute to the problem: "echo", "onlcr", and "icrnl".

Since this serial port is looped back to itself, here is what happened after running echo "hi" > /dev/ttyS1:

  1. The echo command appends a newline to the end of the message by default, so "hi" + LF is sent out to /dev/ttyS1
  2. Because "onlcr" was set, the serial device converted the LF to CRLF so the physical message sent out the Tx line was "hi" + CRLF
  3. Because "icrnl" was set, the physical messaged received on the Rx line converted the CR to LF. So the message outputted by 'cat' was "hi" + LFLF.
  4. Because "echo" was set, the message received on the Rx ("hi" + LFLF), was then sent back out on the Tx line.
  5. Because of onlcr, "hi" + LFLF became "hi" + CRLFCRLF.
  6. Because of icrnl, "hi" + CRLFCRLF became "hi" + LFLFLFLF
  7. Because of echo, "hi" + LFLFLFLF was then sent out the Tx

And so on...

In order to fix this problem, I ran the following command:

stty -F /dev/ttyS1 -echo -onlcr

Disabling "echo" prevents an infinite loop of messages and disabling "onlcr" prevents the serial device from converting LF to CRLF on output. Now cat receives one "hi" (with a single newline!) for each time I run echo.

CR = carriage return (ASCII 0x0D); LF = line feed or newline (ASCII 0x0A)

Solution 2

I had a similar issue as well with concatenating files into a serial tty for testing. In addition to the accepted answer:

If you're testing serial output by doing something like: cat somefile.txt > /dev/ttyS0, it will have a good amount of unexpected byte data if you're testing for exact byte values.

With stty doing a simple stty raw -F /dev/ttyS0 will stop the terminal from inserting/replacing characters (e.g. [...] 0x0A [...] -> [...] 0x0D 0x0A [...]). The raw flag changes the modes of the terminal so no input and output processing is performed.

Share:
27,466

Related videos on Youtube

Kristina
Author by

Kristina

Updated on September 18, 2022

Comments

  • Kristina
    Kristina almost 2 years

    So I have a standard RS232 serial port that is looped back to itself by simply running a wire from Tx to Rx. I'm testing loopback by running echo and cat in two separate terminals:

    cat /dev/ttyS1
    echo "hi" > /dev/ttyS1
    

    My issue is with the output. I would expect to see one "hi" come back on the terminal running cat but instead I get this:

    hi
    [2 newlines]
    hi
    [4 newlines]
    hi
    [8 newlines]
    hi
    [16 newlines]
    hi
    [32 newlines]
    hi
    

    ...and so on until I ctrl+c cat.

    After interrupting cat, if I run it again it will not output "hi"s until I run echo a second time.

    Is this normal? Any idea why I'm seeing this behavior?

    Edit: By newline, I mean ASCII 0x0A. There are no carriage returns in this output.

    • mrb
      mrb almost 12 years
      Could it be caused by having two processes opening the same device? What if you run tip /dev/ttyS1 (~. to exit) and tried typing data there? It should be displayed in your terminal when the wire is connected, as it receives what it has transmitted.
    • Admin
      Admin almost 12 years
      Are you really getting newlines, or a carriage-return/newline pair? The distinction is important at the level you're working. Try "cat /dev/ttyS1 > somefile" then do "od -x somefile" to see exactly what bytes are coming out of the TTY device file. Also, do an "stty -F /dev/ttyS1 -a". Read the man page for "stty" and look at what the output of stty tells you, for every little setting. RS232 serial comms are tricky.
  • BMiner
    BMiner over 10 years
    Hmm... doesn't look like stty raw will disable echoing by default. You may need to do stty raw -echo.
  • Skattered
    Skattered over 4 years
    -icrnl did the trick for me.
  • fadedbee
    fadedbee over 4 years
    sudo stty raw -F /dev/ttyUSB0 -echo fixed it for me.