How to connect embedded gps device to gpsd

时间:2016-08-31 17:25:42

标签: tcp gps pty gpsd

My questions are about my problem interfacing to the 'device' side of gpsd.

I have a GPS device that produces NMEA 0183 output via an RS232 / UART connection, sitting on an embedded board. My problem is that I want to get the data from this device into 'gpsd' running in linux on an SoC on another 'System' board. The only connection I have to get the data from the embedded board with the device is an I2c connection, and I can create an app on the System board that will pull the NMEA message data from the embedded board, across the I2c interface.
My question is how best to get these NMEA messages from my app on the System board into gpsd running on my System board, so that I can use gpsd to 'consolidate' and 'distribute' the gps data to other client applications?

It looks like possibilities are using a tcp or udp device connection into gpsd, or to use a pseudo-terminal (pty) connection as is apparently used for regression testing.

I tried opening a 'raw' pseudo-terminal pair in my app, and adding the pty slave device to gpsd via gpsd's control socket connection. But although gpsd appears to recognize the device as a pseudo-terminal (with major node number 136) and add the pty slave device (/dev/pts/2 in this case), open the pty slave device, and 'activate' the device, it never appears to read any of the NMEA messages coming across the pty slave.

I see the following debug output from gpsd:

root@abcd-efgh:~# gpsd -n -N -D12 -F /var/run/gpsd.sock
gpsd:SPIN: control socket /var/run/gpsd.sock is fd 3
gpsd:PROG: control socket opened at /var/run/gpsd.sock
gpsd:INFO: launching (Version 3.11~dev)
gpsd:IO: opening IPv4 socket
gpsd:SPIN: passivesock_af() -> 4
gpsd:IO: opening IPv6 socket
gpsd:SPIN: passivesock_af() -> 5
gpsd:INFO: listening on port 2947
gpsd:PROG: shmat() succeeded, segment 0
gpsd:PROG: shared-segment creation succeeded,
gpsd:INFO: running with effective group ID 0
gpsd:INFO: running with effective user ID 0
gpsd:INFO: startup at 2016-08-31T16:48:39.000Z (1472662119)
gpsd:UNK: select waits
gpsd:SPIN: select() {3 4 5} -> { 3 } at 1472662124.273340 (errno 0)
gpsd:INFO: control socket connect on fd 6
gpsd:CLIENT: <= control(6): +/dev/pts/2\x0a
gpsd:INFO: <= control(6): adding /dev/pts/2
gpsd:INFO: stashing device /dev/pts/2 at slot 0
gpsd:INFO: opening GPS data source type 6 at '/dev/pts/2'
gpsd:INFO: speed 115200, 8N1
gpsd:SPIN: open(/dev/pts/2) -> 7 in gpsd_serial_open()
gpsd:INFO: gpsd_activate(2): activated GPS (fd 7)
gpsd:INFO: device /dev/pts/2 activated

At that point gpsd just appears to "hang" waiting on messages...

But although GPS messages are then being written from the pty master (by the app running on the System board that pulls the messages from the device), gpsd never appears to read them... If I connect with 'gpsmon' or 'gpspipe' to see what messages are coming across, I see no JSON or raw message output like I would if I had a serial device (ttySx) directly connected to gpsd. I'm not sure if gpsd has added my pty slave file descriptor to the list of descriptors it 'select()'s on.

I've also tried writing another 'dummy' app to open the pty slave device in place of gpsd and read what's coming across the pseduo-terminal connection from the 'main' app that is writing the NMEA messages, and the dummy app appears to get all of the messages correctly. So I'm not sure why gpsd isn't seeing them.

Is the pty connection a valid way to approach this?
Do I have to start up gpsd from my application, passing it the slave pty device path in gpsd's runstring options, instead of connecting the pty device via the control socket 'add device' message? Or would the 'tcp' device connection be a more standard way to interface the messages from the device, via my main application? Can I then open a local socket connection from my app, and feed the 'tcp://localhost:port' in an 'add device' message across the control socket connection? Or does the tcp socket connection have to already exist when gpsd is launched?

UPDATE: It does appear my pty interface works, as long as I run gpsd with the pts slave device in the runstring, instead of trying to add it with an "add device" message through the control socket. I'm now seeing the NMEA messages I'm sending through from my application being used by gpsd, and can run gpsmon and see location information updating.

0 个答案:

没有答案