gpio-utils
gpio-utils copied to clipboard
Error No such file or directory
On a raspberry PI 3/debian,
$ gpio --config ./raspberrypi.toml status GPIO07 | Number | Exported | Direction | Active Low | Names | Value | +------------+------------+------------+------------+------------+------------+ ERROR: Io(Error { repr: Os { code: 2, message: "No such file or directory" } })
raspberrypi.toml
is in current directory.
What does this error mean?
It's possible that the Debian Raspberry Pi image doesn't have sysfs GPIO enabled by default. What do you get if you ls /sys/class/gpio
?
I wonder if this is the timing issue on export that has been noted elsewhere related to udev: https://github.com/rust-embedded/rust-sysfs-gpio/issues/5. Can you run the command again with strace
so we can see what file or directory was not found?
strace gpio --config ./raspberrypi.toml status GPIO07 > strace.log 2>&1
It seem that is /sys/class/gpio/gpio7/value
was not found.
execve("/home/pi/.cargo/bin/gpio", ["gpio", "--config", "./raspberrypi.toml", "status", "GPIO07"], [/* 40 vars */]) = 0
brk(0) = 0x55960000
uname({sys="Linux", node="raspberrypi", ...}) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f9a000
access("/etc/ld.so.preload", R_OK) = 0
open("/etc/ld.so.preload", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=42, ...}) = 0
mmap2(NULL, 42, PROT_READ|PROT_WRITE, MAP_PRIVATE, 3, 0) = 0x76f99000
close(3) = 0
open("/usr/lib/arm-linux-gnueabihf/libarmmem.so", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0h\5\0\0004\0\0\0"..., 512) = 512
lseek(3, 17960, SEEK_SET) = 17960
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 960) = 960
lseek(3, 17696, SEEK_SET) = 17696
read(3, "A.\0\0\0aeabi\0\1$\0\0\0\0056\0\6\6\10\1\t\1\n\3\f\1\22\4\24"..., 47) = 47
fstat64(3, {st_mode=S_IFREG|0644, st_size=18920, ...}) = 0
mmap2(NULL, 83236, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76f58000
mprotect(0x76f5d000, 61440, PROT_NONE) = 0
mmap2(0x76f6c000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x4000) = 0x76f6c000
mprotect(0x7ed5c000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC|PROT_GROWSDOWN) = 0
close(3) = 0
munmap(0x76f99000, 42) = 0
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=77353, ...}) = 0
mmap2(NULL, 77353, PROT_READ, MAP_PRIVATE, 3, 0) = 0x76f45000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/arm-linux-gnueabihf/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0P\t\0\0004\0\0\0"..., 512) = 512
lseek(3, 8680, SEEK_SET) = 8680
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1120) = 1120
lseek(3, 8328, SEEK_SET) = 8328
read(3, "A.\0\0\0aeabi\0\1$\0\0\0\0056\0\6\6\10\1\t\1\n\2\22\4\23\1\24"..., 47) = 47
fstat64(3, {st_mode=S_IFREG|0644, st_size=9800, ...}) = 0
mmap2(NULL, 73912, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76f32000
mprotect(0x76f34000, 61440, PROT_NONE) = 0
mmap2(0x76f43000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0x76f43000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/arm-linux-gnueabihf/librt.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0 \27\0\0004\0\0\0"..., 512) = 512
lseek(3, 25352, SEEK_SET) = 25352
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1280) = 1280
lseek(3, 24940, SEEK_SET) = 24940
read(3, "A.\0\0\0aeabi\0\1$\0\0\0\0056\0\6\6\10\1\t\1\n\2\22\4\23\1\24"..., 47) = 47
fstat64(3, {st_mode=S_IFREG|0644, st_size=26632, ...}) = 0
mmap2(NULL, 90640, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76f1b000
mprotect(0x76f21000, 61440, PROT_NONE) = 0
mmap2(0x76f30000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x5000) = 0x76f30000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/arm-linux-gnueabihf/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0008I\0\0004\0\0\0"..., 512) = 512
lseek(3, 125760, SEEK_SET) = 125760
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1560) = 1560
lseek(3, 90528, SEEK_SET) = 90528
read(3, "A.\0\0\0aeabi\0\1$\0\0\0\0056\0\6\6\10\1\t\1\n\2\22\4\23\1\24"..., 47) = 47
fstat64(3, {st_mode=S_IFREG|0755, st_size=127320, ...}) = 0
mmap2(NULL, 164424, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76ef2000
mprotect(0x76f08000, 61440, PROT_NONE) = 0
mmap2(0x76f17000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x76f17000
mmap2(0x76f19000, 4680, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x76f19000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/arm-linux-gnueabihf/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0`\321\0\0004\0\0\0"..., 512) = 512
lseek(3, 116400, SEEK_SET) = 116400
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1120) = 1120
lseek(3, 116072, SEEK_SET) = 116072
read(3, "A.\0\0\0aeabi\0\1$\0\0\0\0056\0\6\6\10\1\t\1\n\2\22\4\24\1\25"..., 47) = 47
fstat64(3, {st_mode=S_IFREG|0644, st_size=117520, ...}) = 0
mmap2(NULL, 181664, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76ec5000
mprotect(0x76ee2000, 61440, PROT_NONE) = 0
mmap2(0x76ef1000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c000) = 0x76ef1000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/arm-linux-gnueabihf/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0@h\1\0004\0\0\0"..., 512) = 512
lseek(3, 1231820, SEEK_SET) = 1231820
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 2880) = 2880
lseek(3, 1228284, SEEK_SET) = 1228284
read(3, "A.\0\0\0aeabi\0\1$\0\0\0\0056\0\6\6\10\1\t\1\n\2\22\4\23\1\24"..., 47) = 47
fstat64(3, {st_mode=S_IFREG|0755, st_size=1234700, ...}) = 0
mmap2(NULL, 1303888, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76d86000
mprotect(0x76eaf000, 65536, PROT_NONE) = 0
mmap2(0x76ebf000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x129000) = 0x76ebf000
mmap2(0x76ec2000, 9552, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x76ec2000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/arm-linux-gnueabihf/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0`=\0\0004\0\0\0"..., 512) = 512
lseek(3, 451032, SEEK_SET) = 451032
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1120) = 1120
lseek(3, 450676, SEEK_SET) = 450676
read(3, "A0\0\0\0aeabi\0\1&\0\0\0\0056\0\6\6\10\1\t\1\n\2\22\4\23\1\24"..., 49) = 49
fstat64(3, {st_mode=S_IFREG|0644, st_size=452152, ...}) = 0
mmap2(NULL, 516220, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76d07000
mprotect(0x76d74000, 65536, PROT_NONE) = 0
mmap2(0x76d84000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6d000) = 0x76d84000
close(3) = 0
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f98000
set_tls(0x76f98db0, 0x76f99538, 0x76f9e050, 0x76f98db0, 0x76f9e050) = 0
mprotect(0x76ebf000, 8192, PROT_READ) = 0
mprotect(0x76d84000, 4096, PROT_READ) = 0
mprotect(0x76f17000, 4096, PROT_READ) = 0
mprotect(0x76f30000, 4096, PROT_READ) = 0
mprotect(0x76f43000, 4096, PROT_READ) = 0
mprotect(0x76f58000, 20480, PROT_READ|PROT_WRITE) = 0
mprotect(0x76f58000, 20480, PROT_READ|PROT_EXEC) = 0
cacheflush(0x76f58000, 0x76f5d000, 0, 0x15, 0) = 0
mprotect(0x54c82000, 20480, PROT_READ) = 0
mprotect(0x76f9d000, 4096, PROT_READ) = 0
munmap(0x76f45000, 77353) = 0
set_tid_address(0x76f98958) = 1366
set_robust_list(0x76f98960, 12) = 0
rt_sigaction(SIGRTMIN, {0x76ef6260, [], SA_RESTORER|SA_SIGINFO, 0x76db26c0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0x76ef6348, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x76db26c0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0
readlink("/etc/malloc.conf", 0x7ed5b15c, 4096) = -1 ENOENT (No such file or directory)
brk(0) = 0x55960000
mmap2(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76b07000
munmap(0x76b07000, 2097152) = 0
mmap2(NULL, 4190208, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76908000
munmap(0x76908000, 1015808) = 0
munmap(0x76c00000, 1077248) = 0
open("/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 3
read(3, "0-3\n", 8192) = 4
close(3) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x76db26b0}, {SIG_DFL, [], 0}, 8) = 0
mmap2(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76800000
open("/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0
fstat64(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(3, "54b48000-54c72000 r-xp 00000000 "..., 1024) = 1024
read(3, "0000000 00:00 0 \n76ec5000-76ee20"..., 1024) = 1024
read(3, "ueabihf/librt-2.24.so\n76f32000-7"..., 1024) = 1024
close(3) = 0
sched_getaffinity(1366, 32, {f}) = 4
mmap2(0x7e55d000, 4096, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7e55d000
rt_sigaction(SIGSEGV, {0x54c11db4, [], SA_RESTORER|SA_STACK|SA_SIGINFO, 0x76db26c0}, NULL, 8) = 0
rt_sigaction(SIGBUS, {0x54c11db4, [], SA_RESTORER|SA_STACK|SA_SIGINFO, 0x76db26c0}, NULL, 8) = 0
sigaltstack(NULL, {ss_sp=0, ss_flags=SS_DISABLE, ss_size=0}) = 0
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f96000
sigaltstack({ss_sp=0x76f96000, ss_flags=0, ss_size=8192}, NULL) = 0
syscall_384(0x7ed5b5c7, 0, 0x1, 0x4, 0x1, 0x54c87190) = 0
syscall_384(0x7ed5b668, 0x8, 0x1, 0x54c5d3f2, 0x54c87190, 0x54c87440) = 0x8
syscall_384(0x7ed5b640, 0x8, 0x1, 0x54c5d3f2, 0x54c87190, 0x54c87440) = 0x8
stat64("/etc/gpio.toml", 0x7ed5b4c0) = -1 ENOENT (No such file or directory)
stat64("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/etc", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/etc", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/etc/gpio.d", 0x7ed5ae30) = -1 ENOENT (No such file or directory)
open("./raspberrypi.toml", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
ioctl(3, FIOCLEX) = 0
read(3, "#\r\n# Pin Map for Raspberry Pi 2/", 32) = 32
read(3, "3\r\n#\r\n# This file exports all pi"..., 64) = 64
read(3, "\n# do not want this, you will ne"..., 128) = 128
read(3, " not know how you will be using "..., 256) = 256
read(3, " \"PIN05\", \"SCL1\"]\r\n\r\n[[pins]]\r\nn"..., 512) = 512
read(3, "GEN4\"]\r\n\r\n[[pins]]\r\nnum = 24\r\nna"..., 1024) = 908
read(3, "", 116) = 0
write(1, "| Number | Exported | Dire"..., 80| Number | Exported | Direction | Active Low | Names | Value |
) = 80
write(1, "+------------+------------+-----"..., 80+------------+------------+------------+------------+------------+------------+
) = 80
open("/sys/class/gpio/gpio7/value", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
write(1, "ERROR: Io(Error { repr: Os { cod"..., 80ERROR: Io(Error { repr: Os { code: 2, message: "No such file or directory" } })
) = 80
sigaltstack({ss_sp=0, ss_flags=SS_DISABLE, ss_size=8192}, NULL) = 0
munmap(0x76f96000, 8192) = 0
exit_group(1) = ?
+++ exited with 1 +++
If I do gpio --config ./raspberrypi.toml write GPIO07 1
, /sys/class/gpio/gpio7/
doesn't exist.
It's Ok if I do echo 7 > /sys/class/gpio/export
ls /sys/class/gpio/gpio7/
active_low device direction edge power subsystem uevent value
gpio --config ./raspberrypi.toml status GPIO07
| Number | Exported | Direction | Active Low | Names | Value |
+------------+------------+------------+------------+------------+------------+
| 7 | true | In | false | GPIO07 | 1 |
| | | | | PIN26 | |
| | | | | SPI_CE1_N | |
Ah, I see. I think you need to execute the gpio export
command with your config first. I'm so used to using this on systems where we have this integrated as an init script (custom embedded linux).
If I do
gpio --config ./raspberrypi.toml export GPIO07 gpio --config ./raspberrypi.toml status GPIO07
I got information
| Number | Exported | Direction | Active Low | Names | Value |
+------------+------------+------------+------------+------------+------------+
| 7 | true | In | false | GPIO07 | 1 |
| | | | | PIN26 | |
| | | | | SPI_CE1_N | |
-------------------------------------------------------------------------------
but I have this error with gpio export
gpio --config ./raspberrypi.toml export GPIO07 Error occurred while exporting pin: PinConfig { num: 7, direction: In, names: {"GPIO07", "PIN26", "SPI_CE1_N"}, export: true, active_low: false } Permission denied (os error 13) ls /sys/class/gpio export gpio7 gpiochip0 gpiochip100 gpiochip128 unexport
No error when I do
gpio --config ./raspberrypi.toml unexport GPIO07 ls /sys/class/gpio export gpiochip0 gpiochip100 gpiochip128 unexport
That second error does sound more similar to the aforementioned RPi issues and might be something we could put a workaround in for (in gpio-utils, not the library).
Like @nastevens say in rust-sysfs-gpio Added warning about Raspberry Pi PR, do you think that is possible to use the retry crate to try a few times with a delay between each attempt?
Yes, that sounds reasonable. Can you open a PR with this @LeMoussel?
I'm newbie with Rust :)
However I will try to do a PR in order to use the retry
crate in export
function.
Permission denied error is due to the creation of symlink for each GPIO name/alias : /var/run/gpio/<name>
-> /sys/class/gpio<num>
.
For Raspberry PI, I don't see why these symlink are created.
In gpio_export.rs, Line 28, If I replace
if let Err(e) = export::export(pin, Some(symlink_root)) {
by
if let Err(e) = export::export(pin, None) {
There is no more error.
Should be make PR for that?
The symlink feature does have real value in many configurations. We could consider changing the deafult to not have a symlink root (see config.rs).
Ok.
In raspberrypi.toml
, I add
[config] symlink_root = "/sys/class/gpio"
But there is always error. This is due to the fact that is not possible to create new symbolic link (like /sys/class/gpio/GPIO07
) on the filesystem /sys/class/gpio/gpio7
. See export.rs Line 82.
I get the same error if I do ln -s /sys/class/gpio/gpio7 /sys/class/gpio/GPIO07
One solution would be to put no name in the configuration file raspberrypi.toml
for pins?
Yeah, making the symlink root be in sysfs will not work and doesn't make sense. Using some other directory (e.g. /tmp) may work.
Yep ! It's much better with
[config] symlink_root = "/tmp/gpio"
With this configuration
[config] symlink_root = "/tmp/gpio"
[[pins]] num = 7 names = ["GPIO07", "PIN26", "SPI_CE1_N"] direction = "out"
I got this result
./target/debug/gpio --config ./raspberrypi.toml export GPIO07
./target/debug/gpio --config ./raspberrypi.toml status GPIO07
| Number | Exported | Direction | Active Low | Names | Value |
+------------+------------+------------+------------+------------+------------+
| 7 | true | Out | false | GPIO07 | 0 |
| | | | | PIN26 | |
| | | | | SPI_CE1_N | |
-------------------------------------------------------------------------------
./target/debug/gpio --config ./raspberrypi.toml unexport GPIO07
I update export.rs
to use the retry
crate. I do PR with this.