pi_lw_gpio.c provides a lightweight General Purpose Input Output (GPIO) interface library for the Raspberry Pi via virtual memory mapping of the GPIO peripheral. This software requires no dependencies other than Raspbian running on any version of the Raspberry Pi. Note, not all possible GPIO functions are included in this library at the present.
This project is not meant to replace the many, and much better, existing PI GPIO libraries such as pigpio and Wiring Pi. The purpose is to publish the tools I created to learn more about the Pi as well as share the learning process to others. As such, this emphasizes documenting how GPIO interface via virtual memory mapping is achieved to allow anyone a better understanding of the Raspberry PI and low-level programming in general.
pi_lw_gpio.c is provided two ways for flexibility:
- C source and header files that can be compiled along with your program
- C shared library
To learn and understand the source code, see raspberry_pi_gpio_programming.pdf for a complete breakdown on how this GPIO interface library works.
These instructions will get you a copy of the project up and running on your local machine for development and testing purposes.
First, clone this repository.
$ git clone https://github.com/besp9510/pi_lw_gpio.git
Alternatively, download the repository from Git.
Once obtaining a copy on your local machine, navigate to the top directory and run the configure script to generate a Makefile.
$ ./configure
By default, files will be installed under /usr/local/
. Note that passing the option --help
will display available configuration options such as installation directory prefix and debug symbols.
Compile pi_lw_gpio.c into a shared library.
$ make
Then install files to the installation directory. You must run the following either as root or with root privileges.
$ sudo make install
To use pi_lw_gpio.c in your project, simply include the header file pi_lw_gpio.h
and link to the shared library -lpilwgpio
.
At anytime, to uninstall pi_lw_gpio.c, use the same Makefile used for compiling or a Makefile generated using the configuration script with the same options as root or with root privileges.
$ sudo make uninstall
pi_lw_gpio_test.c is a test script to check and see the GPIO interface library working on your PI. The outline of this test script:
- Read all pin's mode and level
- All pins to output
- Set all pins
- Clear all pins
- All pins to input
- Revet all pin's mode and level
To compile the test script, first navigate to the test directory test/
. Next, run the configure script to generate the Makefile:
$ ./configure
By default, the pi_lw_gpio.c shared library will be looked for under the standard directories (e.g. /usr/local/
). If this is not the case, pass the option --help
to learn how to specify a directory to be searched. Additionally, --help
will also display available configuration options such as debug symbols and debug logs.
Next, compile the test script:
$ make
This will create an executable called pi_gpio_test
under bin/
.
To learn and understand the source code, see raspberry_pi_gpio_programming.pdf for a complete breakdown on how this GPIO interface library works.This reference documents
- What GPIOs are
- BCM2837 ARM & Working with Peripherals
- Memory Mapping
- GPIO Function Macros
Note that this reference has register addresses specific to the BCM2836/BCM2837 (Raspberry PI 2 & 3) processor. The peripheral base physical address for the other PI versions are:
- Raspberry PI 1 & Zero (BCM2835) : 0x20000000
- Raspberry PI 4 (BCM2711) : 0xFE000000
Set and clear a GPIO pin. Setting a pin causes it to go high while clearing causes it to go low.
int gpio_set(int p);
int gpio_clear(int p);
gpio_set()
and gpio_clear()
returns 0 upon success. On error, an error number is returned.
Error numbers:
ENOPIVER
: Could not get Pi board revision.MAP_FAILED
: Memory map failed (most likely due to permissions)EINVAL
: Invalid GPIO pin (must be in range 0 to 30)
Read the level of a GPIO pin.
int gpio_read_level(int p);
gpio_read_level()
returns 0
if pin is low or 1
if pin is high. On error, an error number is returned.
Error numbers:
ENOPIVER
: Could not get Pi board revision.MAP_FAILED
: Memory map failed (most likely due to permissions)EINVAL
: Invalid GPIO pin (must be in range 0 to 30)
Set the mode a GPIO pin. Supported modes are:
GPIO_INPUT
GPIO_OUTPUT
int gpio_set_mode(int mode, int p);
gpio_set_mode()
returns 0 upon success. On error, an error number is returned.
Error numbers:
ENOPIVER
: Could not get Pi board revision.MAP_FAILED
: Memory map failed (most likely due to permissions)EINVAL
: Invalid GPIO pin (must be in range 0 to 30)
Read the current mode of a GPIO pin. Supported modes are:
GPIO_INPUT
GPIO_OUTPUT
int gpio_read_mode(int p);
gpio_read_mode()
returns the following upon success.
GPIO_INPUT
GPIO_OUTPUT
On error, an error number is returned.
Error numbers:
ENOPIVER
: Could not get Pi board revision.MAP_FAILED
: Memory map failed (most likely due to permissions)EINVAL
: Invalid GPIO pin (must be in range 0 to 30)
Follow the "fork-and-pull" Git workflow.
- Fork the repo on GitHub
- Clone the project to your own machine
- Commit changes to your own branch
- Push your work back up to your fork
- Submit a Pull request so that your changes can be reviewed
Be sure to merge the latest from "upstream" before making a pull request!
Feel free to email at the email address under my account name if you have any questions.
Benjamin Spencer
This project is licensed under the MIT License - see the LICENSE.md file for details