Заставить Raspberry Pi GPIO работать из модуля Azure IoT Edge

У меня есть простой пример проекта Node-RED здесь, на GitHub, где я пытается взаимодействовать с несколькими GPIO на Raspberry Pi под управлением Buster. Если я запустил этот проект прямо на Pi, он будет работать нормально. Если я запустил его как модуль, развернув через Azure IoT Edge, я не смогу взаимодействовать с тем же GPIO, даже если я развернул его с помощью этих параметров создания контейнера ...

{
  "HostConfig": {
    "PortBindings": {
      "1880/tcp": [
        {
          "HostPort": "80"
        }
      ]
    },
    "Privileged": true
  }
}

... из /kpmartinhfi/gpio-poc:latest в Docker Hub, созданного с использованием docker buildx build --platform linux/arm/v7 -t kpmartinhfi/gpio-poc:latest . --push.

Пользовательский интерфейс редактора Node-RED доступен по адресу: 80 на устройстве, поэтому он в основном работает, но при попытке использовать GPIO возникают ошибки доступа / разрешений:

16 Sep 19:21:33 - [info] Starting flows
16 Sep 19:21:33 - [info] Started flows
16 Sep 19:21:33 - [info] [rpi-gpio out:Buzzer (GPIO20)] err: Traceback (most recent call last):
  File "/usr/src/node-red/node_modules/@node-red/nodes/core/hardware/nrgpio.py", line 84, in <module>
 :
16 Sep 19:21:33 - [info] [rpi-gpio out:Buzzer (GPIO20)] err:     GPIO.setup(pin,GPIO.OUT)
RuntimeError: No access to /dev/mem.  Try running as root!
 :
16 Sep 19:21:33 - [info] [rpi-gpio out:Relay (GPIO26)] err: Traceback (most recent call last):
  File "/usr/src/node-red/node_modules/@node-red/nodes/core/hardware/nrgpio.py", line 84, in <module>
    GPIO.setup(pin,GPIO.OUT)
RuntimeError: No access to /dev/mem.  Try running as root!
 :
16 Sep 19:21:33 - [info] [rpi-gpio out:Buzzer (GPIO20)] closed
16 Sep 19:21:33 - [info] [rpi-gpio out:Relay (GPIO26)] closed
16 Sep 19:21:33 - [info] [rpi-gpio out:Relay (GPIO16)] err: Traceback (most recent call last):
  File "/usr/src/node-red/node_modules/@node-red/nodes/core/hardware/nrgpio.py", line 84, in <module>
 :
16 Sep 19:21:33 - [info] [rpi-gpio out:Relay (GPIO16)] err:     GPIO.setup(pin,GPIO.OUT)
RuntimeError: No access to /dev/mem.  Try running as root!
 :
16 Sep 19:21:33 - [info] [rpi-gpio out:Relay (GPIO16)] closed
16 Sep 19:21:36 - [info] [rpi-gpio out:Relay (GPIO16)] out: 0
16 Sep 19:21:36 - [error] [rpi-gpio out:Relay (GPIO16)] nrpgio python command not running
16 Sep 19:21:37 - [info] [rpi-gpio out:Relay (GPIO16)] out: 1
16 Sep 19:21:37 - [error] [rpi-gpio out:Relay (GPIO16)] nrpgio python command not running

Как лучше всего решить эту проблему, чтобы система не оставалась в ужасно небезопасном состоянии?

Моя попытка использовать Privileged:true была задумана как «взлом», чтобы просто посмотреть, как все работает, но я подозреваю, что это не лучший способ перейти к «производству».

Интересно, нужно ли мне что-то делать в Dockerfile, например, добавить пользователя Node-RED по умолчанию в группу с доступом к GPIO, но, поскольку каждая попытка занимает довольно много времени, я подумал, что сначала спрошу. :)


person papakpmartin    schedule 16.09.2019    source источник


Ответы (1)


Я не уверен, что это решит вашу проблему точно, но одна из вещей, которые вам нужно сделать, чтобы получить доступ к контактам GPIO RPI из вашего модуля IoT Edge, - это привязать их к модулю. например, я написал модуль на Python, который интегрируется с аксессуаром SenseHat для IoT Edge. Как и многие библиотеки, он использует шину i2c для связи с выводами GPIO, поэтому я помещаю их в свой контейнер с помощью этих «опций создания».

{"HostConfig":{"Binds":["/dev/i2c-1:/dev/i2c-1"],"Privileged":true}}

Если это не сработает, в зависимости от того, как Node-Red получает доступ к контактам, вы также можете попробовать

{"HostConfig":{"Binds":["/dev/gpiomem:/dev/gpiomem"],"Privileged":true}}

или (и я думаю, что это подход "поделиться всем")

{"HostConfig":{"Binds":["/sys:/sys"],"Privileged":true}}
person Steve Busby - MSFT    schedule 16.09.2019
comment
Спасибо за ответ @ steve-busby-msft и @hardillb. Я пробовал и "Binds":["/dev/gpiomem:/dev/gpiomem"], и "Binds":["/sys:/sys"] в параметрах создания контейнера без каких-либо изменений в поведении. Мне интересно, может быть что-то другое в Buster, потому что я тоже не умею echo "out" > /sys/class/gpio/gpio16/direction (я получаю -bash: /sys/class/gpio/gpio16/direction: No such file or directory, если я это сделаю). - person papakpmartin; 23.09.2019
comment
По рекомендации @hardillb в другом месте я попытался настроить gpiod и использовать узлы gpiod, и если я жестко закодирую IP-адрес в узле, это действительно сработает. Я упоминаю об этом здесь только для того, чтобы продемонстрировать, что оборудование и установка Node-RED и код do, похоже, работают, и проблема, о которой я спрашиваю выше, кажется реальной проблемой при попытке прямого доступа к GPIO. . - person papakpmartin; 23.09.2019
comment
это вполне могло быть чем-то другим в Buster, поскольку я делал это только в raspbian stretch, и у меня никогда не было проблем с размещением контактов GPIO в контейнере. Не знаю, куда идти, извини. - person Steve Busby - MSFT; 24.09.2019