So you want to use legacy Linux GPIO?

Starting kernel 4.8, a new GPIO interface, GPIO character device, replaced the legacy GPIO interface. The cons of the legacy interface are:

  • State not tied to process
  • Concurrent access to sysfs attributes
  • If process crashes, the GPIOs remain exported
  • Cumbersome API
  • Single sequence of GPIO numbers representing a two-level hierarchy - necessary to calculate the number of the GPIO, numbers not stable

For details, see the maintainer’s slides.

However, there is still plenty of old kernel users relying on the legacy GPIO.

The GPIO event consuming, however, typically requires 2 syscalls to do the trick, which are read(2) and lseek(2). Alternatively, one can also close-and-open after the read, which requires 3 syscalls.

Actually, it can be done with a single syscall, which is pread(2).

pread(2) has the following signature:

ssize_t pread(int fd, void buf[.count], size_t count, off_t offset);

As the last parameter (i.e. offset) suggests, using pread(2) would not update the file offset after the read. Meaning one would not need to reset the file offset manually.

So, it is recommended to use pread(2) for consuming the event.

You would not like additional syscalls to harm your CPU cache and the like. Besides, issuing non-vdso syscalls is never a cheap act.


This post is here because there would probably no one interested in checking the kernel document, which I recently added the above recommendadtion.