我的程序中存在一个错误,我通过使用 strace 缩小了范围,出现以下错误 -
open("/sys/class/gpio/gpio17/value", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 EACCES (Permission denied)
open("/sys/class/gpio/gpio17/direction", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 EACCES (Permission denied)
有关背景信息,您可以在此处阅读此主题 -https://stackoverflow.com/questions/39524234/bug-with-writing-to-file-in-linux-sys-class-gpio
我单独运行了 3 次测试,一次正常运行,一次指定了 sudo,另一次指定了故意延迟。以下是这些运行的相关 strace 结果 -
Normal
open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/value", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 EACCES (Permission denied)
open("/sys/class/gpio/gpio17/direction", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 EACCES (Permission denied)
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
sudo
open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/value", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/direction", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 4
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
Delayed
("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/value", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/direction", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 4
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
现在我尝试寻找这个错误,但我发现的只是 javascript、android 或 nodejs 错误,没有指向原始描述的链接。任何类型的信息都对我非常有益,所以感谢您的帮助:)
编辑- 如果相关,我将其作为 udev 规则/etc/udev/rules.d/99-com.rules
-
SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", GROUP="gpio", MODE="0660"
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /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:gpio /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'"
和 ls -l 输出 -
total 0
--w--w---- 1 root gpio 4096 Sep 16 07:13 export
lrwxrwxrwx 1 root root 0 Sep 16 07:13 gpio17 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio17
lrwxrwxrwx 1 root root 0 Jul 31 05:23 gpiochip0 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpiochip0
--w--w---- 1 root gpio 4096 Sep 16 06:50 unexport
当前用户也是 GPIO 组的一部分。
答案1
我愿意把钱花在你的程序和udev
.
显然,/sys/class/gpio/gpio17/value
和/sys/class/gpio/gpio17/direction
节点是在 后的某个时刻创建的open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
,最初它们可能由 拥有root:root
,普通用户没有写访问权限。
然后 udev 规则生效,udev 调用 sh 来设置权限,但这需要一段时间;如果您open()
之前尝试下一个,则会失败。
不知道有没有办法让你等待udev完成而不进行轮询。