简体   繁体   中英

Linux: Read data from serial port with one process and write to it with another

I've ecountered a problem using a serial GPS/GNSS device on a Raspberry Pi. The device in question is a u-blox GNSS receiver symlinked to /dev/gps .

I try to achieve logging the output data from this device and simultaneously sending correction data to it.

To be more specific, I use RTKLIBs ( http://www.rtklib.com/ ) str2str tool for sending NTRIP/RTCM correction data to the GNSS receiver in order to get better position estimations using DGNSS/RTK. The receiver's output data will be logged by a python script which is based on the GPS deamon (gpsd).

However, I guess the main issue is related to the serial port control. When I run the writing process (str2str) first and afterwards any reading process (my python script/gpsd frontends (eg cgps) /cat) at the same time, the reading process will output data for a few seconds and freeze then. It doesn't matter which tool I use for reading the data.

I found this question: https://superuser.com/questions/488908/sharing-a-serial-port-between-two-processes . Therefore I made sure that the processes got rw access to the device and even tried running them as superuser. Furthermore I stumbled upon socat and virtual serial ports, but didn't find any use for it. ( Virtual Serial Port for Linux )

Is there any way to read data from a serial port with one process and write to it with another? The only solution I know of right now might be to rewrite the read and write process in python using pySerial. This would allow to only have one process accessing the serial device, but would mean plenty of work.

Finally I found a soultion using a construction somehow similar to this: https://serverfault.com/questions/453032/socat-to-share-a-serial-link-between-multiple-processes

A first socat instance (A) gets GNSS correction data from a TCP connection, which is piped to socat B. Socat B manages the connection to the serial device and pipes output data to another socat instance C, which allows other processes such as gpsd to connect and get the receiver's output from TCP port.

In total, this looks like:

socat -d -d -d -u -lpA   TCP4:127.0.0.1:10030 - 2>>log.txt | 
socat -d -d -d -t3 -lpB  - /dev/gps,raw  2>>log.txt|
socat -d -d -d -u -lpC   - TCP4-LISTEN:10031,forever,reuseaddr,fork 2>>log.txt

With only one process managing the serial connection, it doesn't block anymore.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM