Docker访问树莓派GPIO引脚

67
在树莓派2上运行Docker时,我们如何将GPIO引脚暴露给Docker容器?
5个回答

131

在Linux主机上,有三种可能的方法可以在Docker容器中访问GPIO引脚。

1. 使用“--privileged”选项运行Docker

像这样启动容器将使容器完全访问主机的设备,包括GPIO:

$ docker run --privileged -d whatever

请参考Docker文档中有关此选项的说明。根据您的安全要求程度,这可能不是最佳选择。

2. 添加/dev/gpiomem设备

与其将主机的所有设备暴露给容器,您可以具体指定并在运行时仅将/dev/gpiomem设备暴露给容器。请注意,该设备需要主机Linux发行版内核驱动程序的支持。最近几个版本的Raspbian应该已经支持了。在其他发行版中可能会有所不同。

$ docker run --device /dev/gpiomem -d whatever

3. 在宿主机上使用sysfs文件系统

Raspberry Pi的GPIO在宿主机的文件系统下,位于/sys/class/gpio目录下。可以通过该文件系统中的虚拟文件以用户权限访问。使用Docker卷将其暴露给容器:

$ docker run -v /sys:/sys -d whatever

请注意,使用sysfs进行GPIO操作可能比设备操作更慢。

GPIO库

哪种方法适合您的需求也取决于您在访问GPIO时使用的库。并非所有库都支持这三个选项。


6
显然,您知道如何给出良好的回答。保持那种精神 :-) - GhostCat
很棒的答案! :) - Dat
新的Docker Swarm模式使用docker-compose.yml的第3版,不允许使用特权选项或设备选项。我在我的Docker容器中使用RPi.GPIO Python库。sysfs方法似乎无法与该库一起使用。有人知道其他选项吗? - Bob Swain
2
我正在使用libgpiod - 为此,我必须映射/dev/gpiochip0(或者也可以使用特权模式)。 - Saxon Druce

7

您可能会使用docker卷来暴露sysfs接口。例如,可以这样实现:

docker run -v /sys:/sys fedora bash

这将会把主机上的/sys暴露给容器内的/sys,并且您将可以访问/sys/class/gpio层次结构。

如果您使用的代码没有使用sysfs接口来访问GPIO引脚,那么您需要在容器内公开它正在使用的任何设备节点,可能需要使用--device参数来执行docker run等操作。


6
我会使用这个图片:https://github.com/acencini/rpi-python-serial-wiringpi 作为基础图像。您可以轻松地使用Python访问此处。或者,您可以决定将Node下载到镜像上,并使用这两个npm库通过JavaScript访问:

https://github.com/bryan-m-hughes/raspi -- https://github.com/bryan-m-hughes/raspi-gpio

整个项目的基础是wiringPi,正如您在Dockerfile中所看到的,您必须在第一次运行镜像时运行此命令:

docker run --device /dev/ttyAMA0:/dev/ttyAMA0 --device /dev/mem:/dev/mem --privileged -ti acencini/rpi-python-serial-wiringpi /bin/bash

重要的是要打开dev端口和内存,以便wiringPi可以访问它。wiringPi需要对/dev/mem进行特权访问。

我通过使用 --device /dev/gpiomem:/dev/gpiomem不使用 --privileged,成功在容器中运行了wiringpi。 - larsks

1
在树莓派3B+上使用onoff应用程序,挂载/sys/devices/platform/soc/3f200000.gpio/sys/class/gpio就足够了。
docker run \
  -v /sys/devices/platform/soc/3f200000.gpio:/sys/devices/platform/soc/3f200000.gpio \
  -v /sys/class/gpio:/sys/class/gpio \
  ...

我还在寻找更好的解决方案。


0
如果您正在运行Azure IoT Edge和其中的Docker,则以下步骤将有所帮助。
  1. 将属性"Privileged": true添加到文件deployment.template.json

        "modules": {
         "gpio": {
          "version": "1.0",
          "type": "docker",
          "status": "running",
          "restartPolicy": "always",
          "settings": {
            "image": "${MODULES.gpio}",
            "createOptions": {
             "HostConfig": {
               "Privileged": true
            }
          }
        }
      },
    
  2. 在文件Dockerfile.arm32v7中注释掉moduleuser的创建。Moduleuser没有足够的权限,因此它会忽略Privileged:true选项。没有它,Docker将以根权限运行。

    # RUN useradd -ms /bin/bash moduleuser
    # USER moduleuser
  1. 添加引用到 System.Device.Gpio。 它目前处于预发布状态,但是它可以使用。https://github.com/dotnet/iot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接