управление gpio на Ubuntu 20.04 64 бита arm Raspberry Pi

Вопрос или проблема

Я написал программу на C, которая использует GPIO пины на Raspberry Pi. Когда я писал программу, она работала нормально на Ubuntu 18.04 armhf (32 бита). Теперь же, на моем Raspberry Pi 4 с Ubuntu 20.04 arm64 я получаю следующую ошибку при запуске с sudo:

    initPeripherals: mmap gpio failed (Операция не разрешена)

Насколько я понимаю, эта ошибка возникает из-за того, что ядро было скомпилировано с опцией

    CONFIG_STRICT_DEVMEM=y

Как я могу исправить эту проблему, не перекомпилируя ядро? Я попробовал установить iomem=relaxed и strict-devmem=0, но безрезультатно. Я также пробовал добавлять правила в /etc/udev/rules.d/, но это тоже не сработало. Кроме того, я пытался изменять членство групп, но опять же, я запускаю это от имени root с помощью sudo.

Правка: Ядро 18.04 arm64 работает без проблем. Думаю, я буду довольствоваться этим.

Похоже, это проблема с правами.

$ sudo apt install rpi.gpio-common

После этого вы должны быть в состоянии

$ echo "21" > /sys/class/gpio/export
$ echo "1" > /sys/class/gpio/gpio21
$ echo "21" > /sys/class/gpio/unexport

Если это так, не должно быть проблем с работой с GPIO из C кода.

Этот пакет просто устанавливает файл правил. Я видел в интернете решения, предоставляющие правила udev, но большинство из них не работают.

$ cat /lib/udev/rules.d/60-rpi.gpio-common.rules 
SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", GROUP="dialout", MODE="0660"
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value'"

Вы также можете вручную поместить файл в /etc/udev/rules.d/.

Ответ или решение

Управление GPIO на Ubuntu 20.04 64-битной ARM Raspberry Pi

Работа с GPIO на Raspberry Pi может вызвать некоторые трудности, особенно при переходе на более новые версии операционной системы, такие как Ubuntu 20.04. Проблема, с которой вы столкнулись, связана с ограничениями доступа к памяти устройств, установленными в ядре Linux, и будет рассмотрена ниже.

Проблема

При запуске вашей программы на C с использованием GPIO вы получили ошибку:

initPeripherals: mmap gpio failed (Operation not permitted)

Эта ошибка указывает на то, что ваше приложение пытается использовать mmap для доступа к адресам GPIO, однако система не позволяет это делать из-за настроек, связанных с безопасностью памяти устройств.

Причина

Как вы правильно отметили, наличие опции CONFIG_STRICT_DEVMEM=y в конфигурации ядра ограничивает доступ к определенным областям памяти, включая GPIO. Это было сделано для повышения безопасности системы, но может привести к проблемам при запуске приложений, нуждающихся в прямом доступе к железу.

Решение без перекомпиляции ядра

  1. Установка необходимых пакетов

    Первым шагом является установка пакета rpi.gpio-common, который содержит необходимые правила для работы с GPIO. Выполните следующую команду:

    sudo apt install rpi.gpio-common

    Это установит необходимые правила доступа к GPIO, что упростит управление ими.

  2. Проверка правил Udev

    Проверьте содержимое файла правил Udev, который был установлен. Это можно сделать командой:

    cat /lib/udev/rules.d/60-rpi.gpio-common.rules

    Убедитесь, что в этом файле присутствуют правила, касающиеся доступа к GPIO. Правила должны выглядеть следующим образом:

    SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", GROUP="dialout", MODE="0660"
    SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'"
    SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value'"

    Эти правила позволяют корректно работать с GPIO от программы, запущенной от имени пользователя, входящего в группу dialout.

  3. Использование GPIO

    После установки пакета и проверки правил Udev, попробуйте выполнить следующие команды для управления GPIO:

    echo "21" > /sys/class/gpio/export
    echo "1" > /sys/class/gpio/gpio21/value
    echo "21" > /sys/class/gpio/unexport

    Эти команды должны успешно выполняться без ошибок доступа.

  4. Обновление групповой принадлежности пользователя (опционально)

    Если вы предпочитаете запускать свою программу без sudo, убедитесь, что ваш пользователь включен в группу dialout. Для этого выполните:

    sudo usermod -aG dialout $USER

    После этого перезагрузите систему или выйдите и войдите обратно в сеанс.

Заключение

Правильная настройка доступа к GPIO на Raspberry Pi под управлением Ubuntu 20.04 требует установки необходимых пакетов и проверки правил Udev. Вышеобозначенные шаги должны помочь вам устранить проблему, связанную с ошибкой mmap при работе с GPIO. Надеюсь, это руководство окажется полезным и облегчит вам дальнейшую работу с GPIO на вашем Raspberry Pi.

Оцените материал
Добавить комментарий

Капча загружается...