Linux: gpio 导出时间问题

创建于 2014-03-27  ·  9评论  ·  资料来源: raspberrypi/linux

如果使用 Raspbian (2014-01-07-wheezy-raspbian.zip) 从 Raspberry Pi 上的命令行单独执行以下三个命令,则它们执行成功:

pi<strong i="6">@raspberrypi</strong> ~ $ echo 23 > /sys/class/gpio/unexport
pi<strong i="7">@raspberrypi</strong> ~ $ echo 23 > /sys/class/gpio/export
pi<strong i="8">@raspberrypi</strong> ~ $ echo out > /sys/class/gpio/gpio23/direction 
pi<strong i="9">@raspberrypi</strong> ~ $ 

但是,如果它们在同一行上一起执行,则会出现权限被拒绝的错误:

pi<strong i="13">@raspberrypi</strong> ~ $ echo 23 > /sys/class/gpio/unexport; echo 23 > /sys/class/gpio/export; echo out > /sys/class/gpio/gpio23/direction
-bash: /sys/class/gpio/gpio23/direction: Permission denied
pi<strong i="14">@raspberrypi</strong> ~ $ 

权限被拒绝错误的发生是因为“echo out > /sys/class/gpio/gpio23/direction”在组和“/sys/class/gpio/gpio23/direction”的权限位已设置为适当的值之前执行. 组和权限位是“root”和“-rw-r--r--”,但它们应该是“gpio”和“-rwxrwx---”。

这个时间问题可以在下面的命令序列中看到,它导出 gpio 23 并列出“/sys/class/gpio/gpio23/”的内容两次。 第一个 ls 命令的输出与第二个 ls 命令的输出完全不同。 所有文件的组和权限都已更改。

pi<strong i="19">@raspberrypi</strong> ~ $ echo 23 > /sys/class/gpio/unexport; echo 23 > /sys/class/gpio/export; ls -l /sys/class/gpio/gpio23/; ls -l /sys/class/gpio/gpio23/
total 0
-rw-r--r-- 1 root root 4096 Mar 27 21:51 active_low
-rw-r--r-- 1 root root 4096 Mar 27 21:51 direction
-rw-r--r-- 1 root root 4096 Mar 27 21:51 edge
drwxr-xr-x 2 root root    0 Mar 27 21:51 power
lrwxrwxrwx 1 root root    0 Mar 27 21:51 subsystem -> ../../../../class/gpio
-rw-r--r-- 1 root root 4096 Mar 27 21:51 uevent
-rw-r--r-- 1 root root 4096 Mar 27 21:51 value
total 0
-rwxrwx--- 1 root gpio 4096 Mar 27 21:51 active_low
-rwxrwx--- 1 root gpio 4096 Mar 27 21:51 direction
-rwxrwx--- 1 root gpio 4096 Mar 27 21:51 edge
drwxrwx--- 2 root gpio    0 Mar 27 21:51 power
lrwxrwxrwx 1 root gpio    0 Mar 27 21:51 subsystem -> ../../../../class/gpio
-rwxrwx--- 1 root gpio 4096 Mar 27 21:51 uevent
-rwxrwx--- 1 root gpio 4096 Mar 27 21:51 value

这是一个需要解决的问题吗?

最有用的评论

这是一个非常烦人的问题,需要丑陋的解决方法。 它不应该被关闭。

所有9条评论

我刚刚编辑了上面的帖子。 最初没有出现“echo 23 > /sys/class/gpio/unexport”。 unexport 只是让 gpio 恢复到其初始未导出状态所必需的。

我得到:

pi<strong i="6">@raspberrypi</strong>:~ $ ls -l /sys/class/gpio/
total 0
--w------- 1 root root 4096 Mar 27 17:41 export
lrwxrwxrwx 1 root root    0 Mar 27 17:41 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0
--w------- 1 root root 4096 Mar 27 17:41 unexport
pi<strong i="7">@raspberrypi</strong>:~ $ echo 23 > /sys/class/gpio/unexport
-bash: /sys/class/gpio/unexport: Permission denied

这是我所期望的。 只有 root 有权访问 /sys/class/gpio/unexport 所以当 pi 尝试这样做时,它正确地获得了权限被拒绝。

如果我先运行“sudo su”,那么命令会按预期工作。

这是我以前在旧版本或 Raspbian 上得到的,但在2014-01-07-wheezy-raspbian 上我得到:

pi<strong i="7">@raspberrypi</strong> ~ $ ls -l /sys/class/gpio/
total 0
-rwxrwx--- 1 root gpio 4096 Mar 28 16:58 export
lrwxrwxrwx 1 root gpio    0 Jan  1  1970 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0
-rwxrwx--- 1 root gpio 4096 Mar 28 17:01 unexport
pi<strong i="8">@raspberrypi</strong> ~ $ echo 23 > /sys/class/gpio/export 
pi<strong i="9">@raspberrypi</strong> ~ $ 

一切正常,没有错误。 gpio 组中的每个人都有权访问 /sys/class/gpio/export,而 pi 是 gpio 组的成员。

pi<strong i="13">@raspberrypi</strong> ~ $ groups pi
pi : pi adm dialout cdrom sudo audio video plugdev games users netdev input spi gpio

uname 输出以下内容:

pi<strong i="17">@raspberrypi</strong> ~ $ uname -a
Linux raspberrypi 3.10.34+ #661 PREEMPT Thu Mar 27 00:36:02 GMT 2014 armv6l GNU/Linux

当我们使用来自 piface 人员的一些 udev 东西时,行为发生了变化。 没错,您必须等待 udev 更改已创建设备的权限。 这是一个用户空间的东西,所以不是这个 repo,但我不确定有没有办法改进它。

这行得通吗?

echo 23 > /sys/class/gpio/unexport; echo 23 > /sys/class/gpio/export; sleep 1; echo out > /sys/class/gpio/gpio23/direction

@asb好的,感谢您的信息。 我想我会更改onoff 中的代码,以便它等待权限更改。 优点是使用 onoff 的应用程序可以避免超级用户问题。

@popcornmix是的,有效,谢谢。

我可以看到将 GPIO 权限过程扩展到用户空间的价值,但是这个实现
破坏了内核 GPIO 导出操作的语义。 写入 /sys/class/gpio/export
应该等待用户空间进程在写入返回之前报告它已完成其工作。

变通解决方案表明,用户必须等待一段时间,以便 sysfs 元数据在
导出操作非常难看,因为没有正确的等待时间。 变通策略
寻找元数据的变化(例如组设置为 gpio)是不够的,因为
用户空间权限过程是灵活的 - 它可能决定 root 是正确的组并且没有变化
发生。

内核 GPIO 导出操作的语义变化是可移植代码的障碍,不仅
Raspberry Pi 与其他硬件平台之间,以及不同 Linux 之间
树莓派上的发行版。

同意。 内核有责任提供一个有效的 sysfs 实现,而 Raspbian 的实现显然以一种丑陋的方式被破坏了。 我不明白这个问题如何被标记为关闭。

这是一个非常烦人的问题,需要丑陋的解决方法。 它不应该被关闭。

此页面是否有帮助?
0 / 5 - 0 等级