USB Garmin on GNU/Linux

From OpenStreetMap Wiki
Jump to navigation Jump to search

Garmin GPS devices with USB support are generally well‐supported on GNU/Linux systems. However, there are some niggles to get around. This page should describe how to get your Garmin devices working under various GNU/Linux systems.

There are two common causes of problems with USB Garmins on GNU/Linux: Device permissions, and the presence or lack of the garmin_gps kernel module. Both are discussed on the GPSBabel website in Hotplug vs. Garmin USB on Linux.

Check that your device is recognised

Connect your device to a USB port, then run dmesg.[1][2] You should see something like the following near the end:

[87294.953486] usb 5-6.4: new full speed USB device using ehci_hcd and address 10
[87295.141611] usb 5-6.4: configuration #1 chosen from 1 choice
[87295.141611] usb 5-6.4: New USB device found, idVendor=091e, idProduct=0003
[87295.141611] usb 5-6.4: New USB device strings: Mfr=0, Product=0, SerialNumber=0

If not, switch your device on! Some Garmin devices do not need to be powered on to transfer tracks and waypoints (such as Edge series models), while others do (the eTrex Legend for example).

Your GPS should also show up in lsusb output:[3]

Bus 005 Device 010: ID 091e:0003 Garmin International GPSmap (various models)

Device Permissions

Modern GNU/Linux distributions use udev to dynamically create device files in /dev/. By default, these are only accessible by the super‐user, and unless your distribution already sets device permissions appropriately a normal user will not be able to access the device.

Checking Device Permissions

Note the bus and device number from lsusb or dmesg output. In the example below, the bus number is 5, and the device number is 10 (highlighted):

Bus 005 Device 010: ID 091e:0003 Garmin International GPSmap (various models)

Check the permissions of device files of the format /dev/usbdevBUS_NUMBER.DEVICE_NUMBER* (no leading zeroes), and /dev/bus/usb/BUS_NUMBER/DEVICE_NUMBER (with leading zeroes):

$ ls -l /dev/usbdev5.10*
crw-rw---- 1 root root 252, 17 2008-12-28 20:43 /dev/usbdev5.10_ep00
crw-rw---- 1 root root 252, 15 2008-12-28 20:43 /dev/usbdev5.10_ep02
crw-rw---- 1 root root 252, 14 2008-12-28 20:43 /dev/usbdev5.10_ep81
crw-rw---- 1 root root 252, 16 2008-12-28 20:43 /dev/usbdev5.10_ep83
$ ls -l /dev/bus/usb/005/010
crw-rw-r-- 1 root root 189, 523 2008-12-28 20:43 /dev/bus/usb/005/010

In this case a normal user does not have full access to the USB device.

Fixing Device Permissions

To fix device permissions, you need to tell the system to create the device files with the required permissions. While device files are usually owned by root, they are group-owned by some group. Users who wish to use this device should be in this group.

On Debian 6.0 and later, udev is configured correctly. The device file will be in the lp group. To add yourself to the lp group execute this command as root:

adduser <user> lp

Then logout and login. Type

groups

to confirm that you are in the lp group.

On other distributions you may need to create udev a rule file.

On Fedora 5 and OpenSUSE 10.1 and later, create /etc/udev/rules.d/51-garmin.rules containing:

SYSFS{idVendor}=="091e", SYSFS{idProduct}=="0003", MODE="0666"

On Ubuntu 12.04 create /etc/udev/rules.d/51-garmin.rules as above, but SYSFS is no longer used:

 ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE="666"

Note: This tells udev to make the device files world readable

FIXME: Needs confirming. The mode seems awfully permissive.

One could change the permissions to add a group- remember to put users in the group though. For example, change MODE above to:

 ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE="664", GROUP="plugdev" 

Fedora 18 users can use the following line (note the colon after MODE!):

ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE:="0666"

Load the new rule by executing:

sudo udevadm control --reload-rules

Disconnect and re‐connect your GPS device, and check the permissions of the device files (the bus and device numbers may have changed).

See also: Fixing USB permissions for Garmins in GPSBabel: Hotplug vs. Garmin USB on Linux

Using GPSBabel

See also: Fixing USB permissions for Garmins in GPSBabel: Hotplug vs. Garmin USB on Linux

GPSBabel has support for Garmin devices (serial or USB) using the garmin format and can use its internal USB support or the USB‐serial device provided by the garmin_gps kernel module. Your mileage may vary with the garmin_gps module, so the GPSBabel documentation suggests removing and blacklisting the module and using the internal USB suppport.

Removing and Blacklisting garmin_gps

To remove the module, just run the following as root:

modprobe -r garmin_gps

To prevent the module from being automatically loaded (you can still load it manually), edit /etc/modprobe.d/blacklist:

# prevent garmin_gps from being loaded so generic USB can be used instead
blacklist garmin_gps

Note: The blacklist may already exist on Ubuntu and Debian systems. On Fedora, the file to edit is /etc/modprobe.conf.

FIXME: Again, I haven’t verified the Fedora method.—Sward 22:51, 28 December 2008 (UTC)

On Debian follow instructions on the KernelModuleBlacklisting page.

Problems with usb-storage kernel driver

If gpsbabel gives you the following error message

usb_set_configuration failed, probably because kernel driver 'usb-storage' is blocking our access to the USB device. For more information see http://www.gpsbabel.org/os/Linux_Hotplug.html

then reconnect your gps-device, but this time without putting it into usb-mass-storage mode.

Problems with power-saving daemons

Some power-saving solutions (such as TLP) will place a Garmin USB device into power-saving mode, causing any transfers to fail with Could not start session in a reasonable number of tries. This is solved by blacklisting the Garmin device from power-saving. For example, TLP should have the following set in the configuration:

USB_BLACKLIST="091e:0003"

Replacing the hardware device with your own as found via lsusb.

Using gpsd

Much of the software that reads the current position from GPS devices does so via gpsd. gpsd is a daemon that understands various protocols used by GPS devices and presents a consistent interface that other applications such as Gpsdrive and TangoGPS can use. To use a Garmin USB device with gpsd, you will need to use the garmin_gps kernel module, or trick gpsd into reading NMEA data from gpsbabel.

Loading the garmin_gps Module

To check whether the module is loaded, run:

lsmod | grep garmin_gps

If there is no output, load the module with modprobe:

modprobe garmin_gps

You should see something like the following in the output of dmesg:

[96273.677562] usbserial: USB Serial support registered for Garmin GPS usb/tty
[96273.677605] garmin_gps 5-6.4:1.0: Garmin GPS usb/tty converter detected
[96273.678093] usb 5-6.4: Garmin GPS usb/tty converter now attached to ttyUSB0
[96273.678118] usbcore: registered new interface driver garmin_gps
[96273.678123] garmin_gps: garmin gps driver v0.31

ttyUSB0 (highlighted) is the USB‐serial device that you need to use with gpsd.

If you use gpsd a lot (and rarely use GPSBabel), you might want the module to load automatically when you connect your GPS device. To do this, remove it from the blacklist by commenting out the relevent line. Edit /etc/modprobe.d/blacklist and change:

blacklist garmin_gps

to:

#blacklist garmin_gps

Feeding gpsd NMEA from gpsbabel

First, make sure your device permissions are set up correct. If not, you will have to run gpsbabel as root or with sudo.

gpsbabel -T -i garmin -f usb: -o nmea -F - | gpsd -N /dev/stdin

As this is a pipe (|) from gpsbabels stdout to gpsd's stdin you must run gpsd in non-daemon mode (-N)

If you are using the garmin_gps module, you can use the following command :

gpsbabel -T -i garmin -f /dev/ttyUSB0 -o nmea -F - | gpsd -N /dev/stdin

Notes

  1. For information on dmesg, one recommended article is: Nazario, José and Krishnaswami, Natarajan. "dmesg explained". Linux Gazette, (2000).
  2. Ubuntu man page for command dmesg
  3. Ubuntu man page for command lsusb