There's no problem with the GPIO system. The problem is that inotify, to which incron
is an interface, won't necessarily work on all sysfs files, and it seems that this includes these.
If you skim down the inotify FAQ, you'll find this perhaps overly optimistic note:
Q: Can I watch sysfs (procfs, nfs...)?
Simply spoken: yes, but with some limitations. These limitations vary between kernel versions and tend to get smaller. Please read information about particular filesystems.
See also a similar sentiment here. If you search online for "inotify sysfs", you'll find lots of actual reports of this.
Inotify is a userspace entity; it monitors filesystem inodes.
Sysfs, a kernelspace subsystem and the basis of the entire /sys
directory, is not a normal filesystem. It exists in memory, and functions as an interface to the kernel. The way the individual files work is this: when opened and read, the kernel provides whatever information they represent. For example, when you read /sys/class/gpio/gpio25/value
, this is asking the kernel, "What is the current state of GPIO pin 25?". It will then tell you.
However, that information is not actually stored there. It's a fake file. Inotify was not really intended for this purpose; in one of the discussions from that internet search you'll find a remark from someone who is presumably one of the inotify devs:
With sysfs, it does not work as expected for some reason.
Well, I'm rather surprised inotify works with sysfs at all ;)
[...] Anyway, if you'd like to add fsnotify()
support into sysfs, sysfs maintainer (Greg - added to CC) is the one
to ask.
Here the point is made that there's nothing inotify can do about this -- to make this kind of monitoring work, something needs to be implemented in sysfs which is a kernel subsystem. Presumably this has been done to some extent, which is why the FAQ is optimistic.
The reason it probably hasn't been done with the GPIOs is because those files already have a specialized API to do exactly what you are trying to do. While it is no help to inotify, it is more flexible, at least from a programming perspective.
"value" ... reads as either 0 (low) or 1 (high). If the GPIO
is configured as an output, this value may be written;
any nonzero value is treated as high.
If the pin can be configured as interrupt-generating interrupt
and if it has been configured to generate interrupts (see the
description of "edge"), you can poll(2) on that file and
poll(2) will return whenever the interrupt was triggered. If
you use poll(2), set the events POLLPRI and POLLERR. If you
use select(2), set the file descriptor in exceptfds. After
poll(2) returns, either lseek(2) to the beginning of the sysfs
file and read the new value or close the file and re-open it
to read the value.
Note "you can poll(2) on that file and poll(2) will return whenever the interrupt was triggered". That's the normative technique and it does work. If you aren't familiar with poll()
see man 2 poll
. These are all native C library system calls (i.e., they go through the kernel) and should have equivalents in higher level languages such as python.
I would have hoped there was established software to provide for those who don't program at all (note that if you can, this is very very simple), but sadly, searching around I could not find anything general purpose.1 Don't let that stop you from searching yourself, however.
1. I'm happy to write a daemon for this, since it should exist, but I will not have time for a month or so.
poll()
as per the sysfs gpio docs.