2

im sending some binary data over serial between two computers. I do it like this :

Receive

cat < /dev/ttyO5 >> $file

Send

cat < $file > /dev/ttyO5

When i check the files, sometimes the receiver machine copies some bytes of the beggining of file at the end. Something like this:

ce16 8fa7 bf54 dc6b 238a #Original file
ce16 8fa7 bf54 dc6b 238a ce16 8fa7 #Generated file on receive machine

The number of bytes added at the end is not fixed, sometimes is 3 bytes, sometimes 4....And i dont know why, I flush the memories before sending and receiving ....

Any clue?

EDIT: SOLVED; the option -echo needs to be disabled on the port confirguration.

Lomezno
  • 90
  • 11
  • Bug in the UART driver for this platform? Besides that it might be latency, DMA, and other problems. – 0andriy Jun 08 '17 at 20:48
  • I dont think so. It only happens when i test the communication. I mean, if i transfer one file, there´s no problem. When i try to send 100 files of 1000bytes each, that´s when the problem comes. – Lomezno Jun 08 '17 at 20:51
  • Exactly looks like a driver bug or anything from the above list. – 0andriy Jun 08 '17 at 20:52
  • Just a bit of clarification you may need. The above example clearly shows that your `read()` in user space gets extra bytes from UART kernel buffer (position is reset to 0 by some reason, perhaps DMA is involved and bug n driver implementation). – 0andriy Jun 09 '17 at 22:20
  • ok, let's assume its one of the problems you suggest....THen explain me, why if I do the same test I mentioned before but on C/C++, the problem disappears? Why the problem is only when doing this on bash? – Lomezno Jun 12 '17 at 06:45
  • It might be race, it might be wrong termios configuration. There are possibilities, and you are clearly not doing your homework. Go through the list of possible issues and ensure that they are not the case, update your post accordingly. – 0andriy Jun 12 '17 at 07:09

3 Answers3

3

As a rule of thumb, you shall not copy binary data over serial port with unknown configuration. Either encode the data to the text file (uuencode, base64, quoted printable, implement your own) or make sure the serial port is configured to transfer 8bit raw data. Look for this example to see how it is achieved in C code. To manipulate the serial port configuration from shell script or CLI you can use stty command. What is important: set 8 data bits, disable software control flow and select raw data to be transmitted. Make sure you set the same configuration on both side.

ArturFH
  • 1,697
  • 15
  • 28
  • I use bash, i cant use C.. I forgot to mention, both machines are set to raw mode. The options of stty I didnt check them. But the problem is that some files are ok, some are bytes added.... – Lomezno Jun 07 '17 at 10:13
  • @Lomezno: Refer this cross-site duplicate, https://unix.stackexchange.com/a/117064/112235 which provides some real insight into the requirement – Inian Jun 07 '17 at 10:33
1

Turning Lomezno's solution into an answer:

stty -F <DEVICE> -echo

(where <DEVICE> is the serial device)

personal_cloud
  • 3,943
  • 3
  • 28
  • 38
0

Lomezno mentioned not wanting to use C. To reset all the port settings, I use the following Python script:

#!/usr/bin/python2.7

import os, time, termios, sys

PORT = sys.argv[1]

# reset the serial port configuration
fd     = os.open(PORT, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK)
iflag  = termios.IGNBRK
oflag  = 0
cflag  = termios.CS8 | termios.CREAD | termios.CLOCAL
lflag  = 0
speed  = termios.B115200
cc     = termios.tcgetattr(fd)[-1]
attr   = [iflag, oflag, cflag, lflag, speed, speed, cc]
termios.tcsetattr(fd, termios.TCSANOW, attr)
os.close(fd)
personal_cloud
  • 3,943
  • 3
  • 28
  • 38