3

I've used the answer to this question to enable control of my Raspberry Pi GPIO pins from within a Docker container, which runs Alpine.

$ docker run --device /dev/gpiomem whatever

This works with the Python RPi.GPIO module, but not with wiringPi.

Python and its dependencies takes up about the same space as Alpine itself, so I'd like to use wiringPi to save on install time and SD card space, and to keep things simple.

Running wiringPi v2.46 in Raspbian directly (installed using apt-get install wiringpi) works fine, and I can successfully configure and trigger digital output pins.

Running wiringPi v2.26 in the Alpine container (installed using apk add wiringpi) fails when trying to configure a pin:

$ gpio -g mode 26 out
Unable to determine hardware version. I see: Hardware   : BCM2835,
 - expecting BCM2708 or BCM2709. Please report this to projects@drogon.net

Is there anything I can do to expose the SOC to the container, so that wiringPi recognises it correctly? What else might be required to get this working?

Jonathan Holvey
  • 697
  • 9
  • 27
  • Can you include the version of wiringpi you're using (specifically, the output of `gpio -v`)? Just looking at it briefly it looks like `gpio` requires `/dev/mem`. – larsks Nov 01 '18 at 03:59
  • I've added the versions to my question – Jonathan Holvey Nov 01 '18 at 07:04
  • I think it's because the version of `wiringPi` in the arch image is too old and doesn't know about more recent hardware. You may need to convince the Arch folks to update their package, or just build your own package. – larsks Nov 01 '18 at 11:02

2 Answers2

3

Warning: Thar be hacks ahead.

The fundamental problem, as I noted in my comment, is that your containerized wiringPi is simply too old. Older Pi harwdare (like the Pi 2) used the BCM2708/BCM2709 processors, but newer hardware uses the BCM2835. WiringPi needs to know what processor is in use in order to correctly locate the GPIO control registers.

It's possible that there isn't a substantial difference between the older and newer processors as far as GPIO goes. If -- and only if -- this is the case, you can "trick" your containerized wiringPi into working.

  1. Create a version a /proc/cpuinfo with the desired processor name:

    sed s/BCM2835/BCM2709/ < /proc/cpuinfo > /proc/cpuinfo
    
  2. Bind mount that onto /proc/cpuinfo inside the container. You'll also need to provide /dev/mem, and you'll need to run with --privileged:

    docker run -it --rm --privileged --device /dev/mem -v /tmp/cpuinfo:/proc/cpuinfo alpine sh
    

This gives us:

/ # gpio -v
gpio version: 2.26
Copyright (c) 2012-2015 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Raspberry Pi Details:
  Type: Model 2, Revision: 1.1, Memory: 1024MB, Maker: Sony [OV]
/ # gpio readall
 +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 |   IN | 0 |  3 || 4  |   |      | 5V      |     |     |
 |   3 |   9 |   SCL.1 |   IN | 0 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 0 |  7 || 8  | 0 | IN   | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 0 | IN   | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 0 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI |   IN | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO |   IN | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK |   IN | 0 | 23 || 24 | 0 | IN   | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 0 | IN   | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 0 | 27 || 28 | 0 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 0 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 0 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+

You would want to experiment to see if this actually works as intended.

Or just run a Raspbian image instead of an Arch image.

larsks
  • 277,717
  • 41
  • 399
  • 399
2

Thanks to larsks for pointing out the difference in version numbers.

Version 2.46 of wiringPi is available for Alpine, but I'd failed to notice it's only in the edge branch of the community repository

To use this version I had to modify the file /etc/apk/repositories, replacing the existing community entry with the edge version.

Since I'm using Docker, I had to do this as part of the image build process, so I added the following to my Dockerfile:

RUN sed -i "s/v[0-9.]*\/community/edge\/community/" /etc/apk/repositories \
    && apk update && apk add wiringpi
Jonathan Holvey
  • 697
  • 9
  • 27