以非 root 身份访问 GPIO (/sys/class/gpio)

Access GPIO (/sys/class/gpio) as non-root

默认情况下/sys/class/gpio只能作为root访问。所以我喜欢新组gpio可以使用/sys/class/gpio下的文件和目录。为此,我将以下行添加到 /etc/rc.local(我在 Debian 上):

sudo chown root:gpio /sys/class/gpio/unexport /sys/class/gpio/export
sudo chmod 220 /sys/class/gpio/unexport /sys/class/gpio/export

因此,这为所有 gpio 组成员提供了写入权限。所以他们现在可以 exportunexport 别针了。

问题是他们无法 read/write export 之后的特定 pin 文件(e.x。/sys/class/gpio/gpio17),因为这些文件属于 root:root再次.

我怎样才能更改它们也默认创建为 root:gpio?我的意思是每次导出 pin 时我都可以手动执行此操作。但这有点不舒服。

更新

根据 larsks 的回答,我创建了丢失的规则文件。现在部分有效:

-rwxrwx---  1 root gpio 4096 Jun 19 16:48 export
lrwxrwxrwx  1 root gpio    0 Jun 19 16:51 gpio17 -> ../../devices/soc/3f200000.gpio/gpio/gpio17
lrwxrwxrwx  1 root gpio    0 Jun 19 16:45 gpiochip0 -> ../../devices/soc/3f200000.gpio/gpio/gpiochip0
-rwxrwx---  1 root gpio 4096 Jun 19 16:45 unexport

但是对于 ./gpio17/ 我仍然得到 root:root:

-rw-r--r-- 1 root root 4096 Jun 19 16:52 active_low
lrwxrwxrwx 1 root root    0 Jun 19 16:52 device -> ../../../3f200000.gpio
-rw-r--r-- 1 root root 4096 Jun 19 16:52 direction
-rw-r--r-- 1 root root 4096 Jun 19 16:52 edge
drwxr-xr-x 2 root root    0 Jun 19 16:52 power
lrwxrwxrwx 1 root root    0 Jun 19 16:52 subsystem -> ../../../../../class/gpio
-rw-r--r-- 1 root root 4096 Jun 19 16:52 uevent
-rw-r--r-- 1 root root 4096 Jun 19 16:52 value

更新 2

好的,我解决了这个问题。因为我在 RaspbianInstaller 上安装了 Raspbian,所以我从未使用过 raspi-config 工具。这似乎是一个问题。因为我还缺少 /sys/device/virtual/gpio/ 文件夹。

我在这里遵循了这个指南:https://community.element14.com/products/raspberry-pi/f/forum/26425/piface-digital-2---setup-and-use#139528

然后权限是正确的(即使是 pin 文件夹及其文件 valuedirection、...)。

您可以使用 udev 规则来执行此操作,这些规则可以定义内核实例化新设备时要执行的操作。 Raspberry Pi 设备的 Raspbian 发行版的当前版本在 /etc/udev/rules.d/99-com.rules 中包含以下内容:

SUBSYSTEM=="gpio*", PROGRAM="/bin/sh -c 'chown -R root:gpio /sys/class/gpio && chmod -R 770 /sys/class/gpio; chown -R root:gpio /sys/devices/virtual/gpio && chmod -R 770 /sys/devices/virtual/gpio'"

这确保 /sys/class/gpio 下的条目始终可供 gpio 组的成员使用:

# ls -lL /sys/class/gpio/
total 0
-rwxrwx--- 1 root gpio 4096 May  6 23:36 export
drwxrwx--- 2 root gpio    0 Jan  1  1970 gpiochip0
-rwxrwx--- 1 root gpio 4096 May  6 23:37 unexport
# echo 11 > /sys/class/gpio/export 
# ls -lL /sys/class/gpio/
total 0
-rwxrwx--- 1 root gpio 4096 May  6 23:37 export
drwxrwx--- 2 root gpio    0 May  6 23:37 gpio11
drwxrwx--- 2 root gpio    0 Jan  1  1970 gpiochip0
-rwxrwx--- 1 root gpio 4096 May  6 23:37 unexport

更新

各个图钉的权限也是正确的:

# ls -Ll /sys/class/gpio/gpio11/
total 0
-rwxrwx--- 1 root gpio 4096 May  6 23:37 active_low
drwxr-xr-x 3 root root    0 May  6 23:36 device
-rwxrwx--- 1 root gpio 4096 May  6 23:37 direction
-rwxrwx--- 1 root gpio 4096 May  6 23:37 edge
drwxrwx--- 2 root gpio    0 May  6 23:37 subsystem
-rwxrwx--- 1 root gpio 4096 May  6 23:37 uevent
-rwxrwx--- 1 root gpio 4096 May  6 23:37 value

4.x 内核的更常见规则如下

SUBSYSTEM=="gpio*", PROGRAM="/bin/sh -c 'find -L /sys/class/gpio/ -maxdepth 2 -exec chown root:gpio {} \; -exec chmod 770 {} \; || true'"

如果路径中有符号 link,初始答案中的规则将无法 chown 导出的 gpio

UPD 请记住,当您通过 sysfs 导出某些 GPIO 时,您应该等待 udev 规则触发并完成,然后才能获得所需的访问权限。对我有用的是在尝试访问 GPIO 文件之前睡大约 100 毫秒。

扩展@roman-savrulin 的回答,这里有一个更简单的版本。

不需要 运行 REMOVE 事件的规则,只需要 ADD 事件。也不需要 运行 'find' 因为 udev 环境将提供包含新 GPIO 引脚文件的 sysfs 目录的确切路径。您还可以使用 'chgrp' 仅更改所属组,并使用 'chmod' 中的符号模式仅添加组写入权限位。

在尝试打开 pin 的文件之前,您仍然需要等待规则处理完成,但是使用只涉及最少数量的必要文件的更简单的规则应该可以更快地完成该过程。

SUBSYSTEM=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chgrp -R gpio /sys/${DEVPATH} && chmod -R g+w /sys/${DEVPATH}'"

查看您所属的群组:

userk@dopamine $: groups
userk sudo dialout

如果你属于以下dialout,如果不属于,请评论。

userk@dopamine $: ls -l /dev/gpiomem 
crw------- root root /dev/gpiomem

此文件镜像与 GPIO 设备关联的内存。该命令的输出意味着文件的所有者是 root 用户,“拥有”它的组是 root 组。这 10 个字符代表文件类型和与之关联的权限。当前配置允许文件的所有者读取和写入文件。

如果您想控制 gpios,您希望能够读取和写入该文件。

一个选项是修改群组所有者并使其与您所属的群组相匹配(在我的例子中是拨出)并设置权限以允许该群组的所有用户读取和写入文件。

长话短说:

userk@dopamine $: sudo chown root:dialout /dev/gpiomem
userk@dopamine $: sudo chmod 660 /dev/gpiomem

等等!此设置不会持久存在,重启后会消失。

有关该主题的更多信息,请参阅此post

对于Ubuntu运行。

sudo apt install rpi.gpio-common