在Linux主机上,有三种可能的方法可以在Docker容器中访问GPIO引脚。
像这样启动容器将使容器完全访问主机的设备,包括GPIO:
$ docker run --privileged -d whatever
请参考Docker文档中有关此选项的说明。根据您的安全要求程度,这可能不是最佳选择。
与其将主机的所有设备暴露给容器,您可以具体指定并在运行时仅将/dev/gpiomem设备暴露给容器。请注意,该设备需要主机Linux发行版内核驱动程序的支持。最近几个版本的Raspbian应该已经支持了。在其他发行版中可能会有所不同。
$ docker run --device /dev/gpiomem -d whatever
Raspberry Pi的GPIO在宿主机的文件系统下,位于/sys/class/gpio目录下。可以通过该文件系统中的虚拟文件以用户权限访问。使用Docker卷将其暴露给容器:
$ docker run -v /sys:/sys -d whatever
请注意,使用sysfs进行GPIO操作可能比设备操作更慢。
哪种方法适合您的需求也取决于您在访问GPIO时使用的库。并非所有库都支持这三个选项。
您可能会使用docker卷
来暴露sysfs
接口。例如,可以这样实现:
docker run -v /sys:/sys fedora bash
这将会把主机上的/sys
暴露给容器内的/sys
,并且您将可以访问/sys/class/gpio
层次结构。
如果您使用的代码没有使用sysfs
接口来访问GPIO引脚,那么您需要在容器内公开它正在使用的任何设备节点,可能需要使用--device
参数来执行docker run
等操作。
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
--device /dev/gpiomem:/dev/gpiomem
而不使用 --privileged
,成功在容器中运行了wiringpi。 - larsks/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 \
...
我还在寻找更好的解决方案。
将属性"Privileged": true添加到文件deployment.template.json中
"modules": {
"gpio": {
"version": "1.0",
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
"image": "${MODULES.gpio}",
"createOptions": {
"HostConfig": {
"Privileged": true
}
}
}
},
在文件Dockerfile.arm32v7中注释掉moduleuser的创建。Moduleuser没有足够的权限,因此它会忽略Privileged:true选项。没有它,Docker将以根权限运行。
# RUN useradd -ms /bin/bash moduleuser
# USER moduleuser
/dev/gpiochip0
(或者也可以使用特权模式)。 - Saxon Druce