1

I try sending to serial port someone string echo -ne '\x55\x90\x17\x01\x00' > /dev/ttyACM0, usb monitoring show me this data:

ffff8c957536f540 2932377867 S Bo:2:005:3 -115 5 = 55901701 00

this working properly, all data send it in one string, device accepted command. but if data include 0xA, its always split data into 2 lines. for example:

echo -ne '\x55\x90\xa\x01\xde' > /dev/ttyACM0

usb monitoring show me this:

ffff8c957536f540 3046024649 S Bo:2:005:3 -115 3 = 55900a
ffff8c957b719000 3046024661 S Bo:2:005:3 -115 2 = 01de

string split to 2 lines, of course, the device has ignored this command.

My question, how to send any data with included 0xA. This something wrong with stty, I spend a lot of time but still do not the success. or please confirm, this does not possible to send 0xA in mid of string from Linux console to a serial port.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232

3 Answers3

3

This looks a lot like an issue that was discussed on Bash's mailing list during the past couple of days. Bash uses line buffering for output, so a printf or echo that contains newlines in the middle calls the write() system call for each "line".

$ strace -ewrite bash -c 'echo -ne "foobar"' >/dev/null 
write(1, "foobar", 6)                   = 6
+++ exited with 0 +++

$ strace -ewrite bash -c 'echo -ne "foo\nbar\n"' >/dev/null 
write(1, "foo\n", 4)                    = 4
write(1, "bar\n", 4)                    = 4
+++ exited with 0 +++

If the device you're writing to is sensitive about that, it may result in more than one distinct packet further down the line. A serial connection or a TCP stream(*) shouldn't care, but something more like UDP packets would.

It appears you can't work around this in Bash, but you can use some other utility that doesn't split the output to lines in the middle of a single output command. All other shells I tested print the above in one write() call, and so does the external printf utility from GNU coreutils. It should be in /usr/bin/printf on Linuxes, so /usr/bin/printf '\x55\x90\xa\x01\xde' should work:

$ strace -f -ewrite /usr/bin/printf '\x55\x90\xa\x01\xde' >/dev/null 
write(1, "U\220\n\1\336", 5)            = 5
+++ exited with 0 +++

Alternatively, you could pipe the output through dd, which by default buffers the output to blocks of 512 (apart from the last), which should be enough in your case. (dd obs=512 to be explicit about it.)

(* TCP connections shouldn't care, but the question on the mailing list was exactly about printf ... > /dev/tcp/.... The distinct writes can affect the segmentation of the TCP stream, and apparently some buggy hosts care about that.)

ilkkachu
  • 138,973
  • first thanks for try to help me. I use printf before, of course, had a similar result to echo command, not work with 0xa in the middle. what I try to say, the problem not in echo or printf or another utility, the problem in STTY, from this point I have a question, how to "fix" stty, it's possible to use something another and does not involve stty when sending to the serial port? or, change 0xa in STTY to another byte, for example to 0XFF, I do not send 0xff in my data.in short story, the problem in STTY, how to fix? – Victor L Sep 25 '18 at 04:32
  • @VictorL, what happens if you run (printf '\x55\x90\x17'; printf '\x01\x00') > /dev/ttyACM0 ? Does it work in the same way as the same in just one printf, or does it also get split into two the way you didn't want it to? – ilkkachu Sep 25 '18 at 07:47
  • not working, the problem in stty – Victor L Sep 25 '18 at 07:54
  • @VictorL, how do you know the problem is in stty? – ilkkachu Sep 25 '18 at 08:17
  • It’s simple, when I forward data to the file from echo or printf, I have correct data in file. But when I forward data to the file from USBmon, this data after stty has been involved, and checking data in the file, string with data not correct. – Victor L Sep 25 '18 at 09:00
  • @VictorL, well, I have no experience in USB debugging, but if the bytes on the right hand side of your usb monitor output are the actual data bytes sent to the device, then you're getting the correct data (the five bytes 55 90 0a 01 de) there, too, even in the case of the newline. Just like the case of writing to a file. It's not like the terminal settings are changing anything there, like changing the LF to a CRLF. – ilkkachu Sep 25 '18 at 12:08
  • @VictorL, but I'm not sure if you tried that version with the two printfs, five comments above. Can you test that and post what the usb monitor shows for that? – ilkkachu Sep 25 '18 at 12:09
  • please read my previous comment more carefully, I making him again, probably you miss...... first when I send this string \x55\x90\x0b\x01\x85, this converted to 35 35 39 30 30 62 30 31 20 38 35, but, when I send this string \x55\x90\x0a\x01\x85, this converted to 35 35 39 │ 30 30 61 0A │ 66 66 66 66. in first variant b has been converted to 62, this is correct, in second variant A has been converted to 61 this is as well correct, but after this has been added real code 0A, and of course after this 66 66 66 66. stty, Linux, driver?, I do not know who is added this 0xa, but how to remove this? – Victor L Sep 25 '18 at 12:15
  • respond to this command (printf '\x55\x90\x17'; printf '\x01\x00') > /dev/ttyACM0 usbmon show this 35 35 39 30 31 37 0A 66 66 66 66 – Victor L Sep 25 '18 at 12:20
  • @VictorL, None of those seem to look anything like the output you present in your question (ffff8c957536f540 3046024649 S Bo:2:005:3 -115 3 = 55900a etc.) Instead, that looks more like the byte values of a hex dump. You're going to have to edit your question to show the actual details in some way that can be compared and tell us the meaning of the output. Right now, you haven't even shown what commands you run to get that output, so it's very hard to find out what the interpretation should be. – ilkkachu Sep 25 '18 at 12:24
  • @VictorL 35 35 39 30 31 37 0A 66 66 66 66 taken as a sequence of bytes represented in hex, is the string "559017\nffff", where\n` marks a newline, as usual. If the appearance of the newline in the output is a problem, then it seems to me you have that problem regardless of if you have a newline in the input. – ilkkachu Sep 25 '18 at 12:29
  • @VictorL, but frankly, you don't seem very cooperative, which is surprising given that the premise of posting a question on SE, is that you have a problem which you want to solve and are asking for assistance on it. – ilkkachu Sep 25 '18 at 12:30
  • xA it's similar to \n I know that, and of course, I have this in my data \x55\x90\xa\x01\xde, of course stty must to response to this code and create new line, but my question is very simple, how to send xA like a DATA, this was the original question, and I still do not have answer – Victor L Sep 25 '18 at 12:36
  • I not any problem to send my device any combination of data,except when the data include xA – Victor L Sep 25 '18 at 12:43
0

That doesn't mean that the data is "split" into 2 lines.

In short, you're writing the data correctly, it's the way you display the data that appears you have "two lines."

0xA is the ascii "linefeed"character, which is is the Unix/Linux "newline" character ('\n').

When you look at the data from USB monitor, the terminal (or almost all other text display software in Unix/Linux), will move the display to the next "line". On most terminals, this means that the display driver will insert a carriage return with the linefeed.

A better way to verify your data is to capture the data from USB monitor and pipe it to the od command, with the option to view hex characters (od -t x1). Then you should see the actual data that you've written.

RobertL
  • 6,780
  • ok, maybe the report is wrong, but the question still in, how to send raw string data to a device, when data include 0xa in the middle of the string. – Victor L Sep 24 '18 at 06:13
  • Ok, I have enough information, and I believe someone really smart help me. first when I send this string \x55\x90\x0b\x01\x85, this converted to 35 35 39 30 30 62 30 31 20 38 35, but, when I send this string \x55\x90\x0a\x01\x85, this converted to 35 35 39 │ 30 30 61 0A │ 66 66 66 66. in first variant b has been converted to 62, this is correct, in second variant A has been converted to 61 this is as well correct, but after this has been added real code 0A, and of course after this 66 66 66 66. stty, Linux, driver?, I do not know who is added this 0xa, but how to remove this??????????? – Victor L Sep 24 '18 at 07:03
  • 1
    This answer does not match the output given in the question, where clearly the USB monitoring program is not printing a Line Feed, but is already dumping the character data in hexadecimal in two groups of 6 and 4 hex digits instead of one 1 group of 10 hex digits. ikkachu's unanswered request for clarification is actually very pertinent. – JdeBP Sep 24 '18 at 07:46
  • where did you see answer mate? only flood with smart face it's my second thread on this forum and probably last, first was here https://stackoverflow.com/questions/52438785/send-to-serial-x0a – Victor L Sep 24 '18 at 08:01
0

Some tty devices keep LF to CRLF conversion output on. You can disable it using:

stty -onlcr -F /dev/ttyACM0

or, for strict POSIX stay

stty -onlcr < -F /dev/ttyACM0

or pure RAW mode try:

stty raw -echo -F /dev/ttyACM0

and then try

echo -ne '\x55\x90\xa\x01\xde' > /dev/ttyACM0