Skip to content
tweej edited this page Jan 9, 2016 · 9 revisions

Welcome to the HighLatencyGPIO wiki!

This (userspace) C++11 class implements an interface to the linux sysfs GPIO subsystem via a RAII style C++ class. There are currently two constructors for the class. The first takes ownership of a GPIO, configures it as either an input or output, and allows a user to call setValue() and getValue() to set/obtain the logical value of the GPIO. The second takes ownership of a GPIO, configures it as an input, and will call a user-provided function upon all logical value transitions (which can be rising edge, falling edge, or both). This frees a user of this class from implementing their own callback/interrupt/polling functionality.

Included is a example program (main.cc) which shows how to use the class. It implements a latency test using two GPIO objects. It is assumed that whatever hardware on which the test is run, GPIO 15 is shorted to GPIO 60. On my BeagleBone Black (Debian Wheezy, linux 3.8.13), latencies of ~700 us reported via this test program are typical. (Slower with linux 4.1.12.) On my Raspberry Pi 2 Model B (Ubuntu MATE 15.10, linux 4.1.10), latencies of ~300 us reported via this test program are typical. Note that these latencies include overhead involved in GPIO::setValue() which will likely not be the case in a real use of the class.

A "lockfree" implementation is also provided, and can be enabled with the define "LOCKFREE" during compiliation. (A lockfree target is included in the makefile.) This implementation provides latencies of ~300 us on my BBB and ~160 us on my RPi2, but it is highly recommended that you DO NOT USE THIS IMPLEMENTATION unless you very clearly understand and accept the cost (massive waste of CPU cycles and power). If you require this sort of latency, a better solution would be to implement the required functionality in a kernel module, or one of the BBB PRUs.

Dependencies:

  • linux >= 3.8
  • C++11 (use -std=c++0x or -std=c++11 for your compiler)
  • boost ( >= 1.30, >= 1.53 for lockfree)

Potential User Pitfalls:

  • The RAII style is enforced by the exported or unexported state of the GPIO. If a program is abnormally terminated (such that the destructor of each GPIO is not called), then subsequent attempts to use the same GPIO will fail, because the GPIO is already exported in the sysfs which is assumed to signify that another GPIO object already owns the sysfs GPIO. Care should be taken to terminate your program appropriately, and ensure the unexported state of any GPIOs you plan to use in a program via a run script.

Additional features being considered:

  • PWM support
  • Debouncing feature for mechanical switches
  • Maximum switching frequency enforcement (to prevent wearing out mechanical relays or other components due to bugs during development)
  • Thread priority adjustment via native_handle()
  • Polling all file descriptors at once in a higher level object/class instead of in each GPIO object (think boost::asio::io_service)

I compared the performance of this library to Pi4J by creating an identical test driver in Java. Latencies of ~2000 microseconds result from the use of that library with a Raspberry Pi 2 Model B, which is a factor of 6.6 greater latency.

Environment:

  • Ubuntu MATE 15.10.1, linux 4.1.15
  • OpenJDK 8 (Pi4J)
  • GCC 5.2.1 (HighLatencyGPIO)

Special thanks go out to Derek Molloy for his incredibly helpful tutorial videos on the BBB.

https://www.youtube.com/user/DerekMolloyDCU

Clone this wiki locally