作为非root用户,如何访问GPIO (/sys/class/gpio)?

22

默认情况下,只有root用户才能访问/sys/class/gpio。所以我希望一个名为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组成员授予写权限。因此,他们现在可以很好地导出取消导出引脚。

问题是,在导出(例如/sys/class/gpio/gpio17)之后,他们无法读取/写入特定的引脚文件,因为那些文件再次由root:root拥有。

我如何更改它们默认创建为root:gpio?我的意思是每次导出引脚时,我可以手动执行此操作。但是这有点不方便。

更新

根据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

然后权限就正确了(甚至对于引脚文件夹及其文件valuedirection等也是如此)。

5个回答

18

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

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

如果路径中存在符号链接,则初始答案中的规则将无法更改导出的gpio的所有者。

更新 请记住,当您通过sysfs导出某些GPIO时,您应该等待udev规则触发并完成,然后再获取所需的访问权限。对我有用的方法是在尝试访问GPIO文件之前等待约100ms。


1
对于较新的内核,应优先选择此选项,而不是上面的答案。 - Pascal
这个可行!在Ubuntu 18.04发行版上的4.15内核上工作(不是Raspbian),其中没有raspi-config或此udev规则。对于这个发行版,需要创建gpio组并将用户添加到其中。 https://www.finnie.org/software/raspberrypi/ubuntu-rpi3/ - DKebler
你知道如何在5.x内核中完成这个吗?貌似在更新的内核上无法像这样工作。 - Richy1989

11

您可以使用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

是的,我已经尝试过了。对于您更新的 ls -Ll,我看到的是 root:root 而不是您所说的 root:gpio。但是它适用于 /sys/class/gpio/*。因此,现在可以导出引脚,但之后无法使用它们。 - TiMESPLiNTER
我不确定你看的是什么。value文件明显可以被gpio组写入。这完全可行,我经常使用它来作为非root用户访问GPIO引脚。 - larsks
3
不是为我。对于我的情况是“root:root”。我一周前安装了Raspbian,没有遇到你提到的规则文件,所以我自己创建了一个。这可能是问题所在吗? - TiMESPLiNTER
3
我正在使用树莓派2,并按照element14上Raymond编写的说明进行操作,但与原帖不同的是,导出的GPIO引脚权限(即/sys/class/gpio/gpioXY/*)仍然属于root:root而非root:gpio。我不知道下一步该怎么做。 - user4113344
1
@Nasha 可能有点晚了,但我遇到了完全相同的问题。我错过了从cli运行raspi-config,它设置了文件的正确用户和组。 - TiMESPLiNTER
显示剩余7条评论

2

在@roman-savrulin的回答基础上,这里提供一个更简单的版本。

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

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

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

0

适用于Ubuntu的运行。

sudo apt install rpi.gpio-common

0
检查您所属的群组:
userk@dopamine $: groups
userk sudo dialout

如果你属于dialout,请执行以下操作,否则请注释掉。

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

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

enter image description here

如果您想要控制GPIO,就需要能够读写该文件。

一种选择是修改组所有者,使其与您所属的组匹配(在我的情况下为dialout),并设置权限,以允许该组的所有用户读写该文件。

长话短说:

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

等一下!这个设置不会持久化,并且在重启后会消失。

有关该主题的更多信息,请参阅文章


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