[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: gpsd autobaud and cpu usage

From: sean d'epagnier
Subject: Re: gpsd autobaud and cpu usage
Date: Mon, 21 Sep 2020 19:29:10 -0400

Hi Gary,

On 9/21/20, Gary E. Miller <> wrote:
>> gpsd uses 5% of the cpu just reading from a single gps.
> I run on Raspberry Pi 3, and average 3% usage.  So something odd with
> your setup.

This is about the same since the pizero is an arm6.   In either case
this cpu usage is way too high for what gpsd is doing.   I need all my
cpu and more cpu uses more power and everything is usually solar

>> The
>> "pselect" call that gpsd uses never blocks and always returns 1 even
>> if there is no data.
> That would be a bug in your C library.  pselect() s supposed to block.
>> I realize this is due to bugs in the usb
>> drivers,

I have managed to get kernel panics in the usb serial module from
plugging in a gps twice after hundreds of plug/unplug cycles.   I also
managed to hard lock gpsd a few times if I try to open the same port
gpsd is using despite the exclusive lock.   This also unbelievably
seems to block data from being read from other serial ports not
involved.   It's really difficult to reproduce any of these, and I'm
trying to work around the issues.  I only get these cases after
plugging and unplugging multiple usb serial devices at least a few
dozen times each ( didn't count but at least 30 or more times)  and
I'm able to avoid accessing (probing for other sensors) the devices
gpsd uses which seems promising.

> News to me.
>> but in other applications which use poll, this doesn't seem
>> to be an issue.   If I insert nanosleep of 100ms after the call, the
>> cpu usage goes down to 0.3% and does not seem to affect gpsd in other
>> ways but I am not sure possible implications especially with higher
>> rate gps (mine is 1hz)
> That would break other things.  100 ms is way too long to sleep.

I made it sleep on only 0 byte reads and the cpu usage drops from 5%
down to 3%.  I sleep on 1 and 0 byte reads and the cpu usage drops to
0.4% (which is probably where it should be)   Most of the reads are 1
byte and there is a lot of overhead in using select as it has to
iterate over all the theoretical fds in multiple cases (sockets,
devices, control sockets)

Shouldn't gpsd be using poll instead and avoid all of this?   I think
it would improve efficiency considerably.

>> My other issue is with autobauding.   It was claimed the baud could be
>> detected in 1 second, but this does not seem to be the case.
> It never was.  Now that some GNSS receivers output 4K long messages at
> 4,800 gpsd has to wait a long time on each speed.  Maybe gpsd could check
> speedds quickly, then slower on a 2nd pass.

I think 2 passes would be great if this is true.  I care mostly about
sirf and nmea which can be detected quickly.   It should detect the
baud rates in a specific order to speed detection and also on what
baud is most likely:  38400, 4800, 9600, 19200, 57600 etc   I don't
think it does this.

It seems on a pi anyway, it should be possible to detect multiple baud
rate simultaneously using software serial ports though this may use a
lot of cpu.

I think once the baud and driver are detected they should be stored
somewhere on a disk as a hint for future detections but I can script
this externally to gpsd.

>> gpsctl
>> -f takes 3-4 seconds even if the baud is set correctly, and if not, it
>> takes 15, 28, or maybe it just hangs for 5 minutes until I kill it and
>> it never finds the baud rate.
> It can take longer than 5 minutes on pathological cases.

I don't think it ever finds the baud in some cases.  I can wait a lot
longer than 5 minutes.  I'll play with this some more.

>> The same behavior occurs with gpsd or
>> gpsctl -f.   In the code it does not seem to have a timeout to detect
>> the baud rate.   Maybe this worked better in older versions of gpsd?
> It worked different on older versions.  It failed quickly on older
> versions,
> now it detects more receivers.
> Why do you not just set the speed correctly and be done with it?

I develop pypilot a free software sailboat autopilot and specifically
using tinypilot which is an operating system based on tinycore linux
on the pi zero.   I have no idea what kind of gps the user might try
to plug in, but I want it to work if possible and faster auto
detection is better.  If gpsd detects nothing I want to know sooner as
I have to detect if it might be a different type of sensor like wind
direction or water speed etc.   Currently it's possible to write udev
rules to assign devices to gpsd but less user configuration is
desirable and a lot of these sailors have never used a pi or ssh

I also noticed gpsd doesn't quote the timestamp specifically in the
json message when a devices is activated from a control socket
resulting in invalid json messages I worked around with:

def gps_json_loads(line):
        return pyjson.loads(line)
    act = '"activated"'
    i = line.index(act)
    j = line.index('Z', i)
    line = line[:i]+act+':"'+line[i+12:j+1]+'"'+line[j+1:]
    return pyjson.loads(line)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]