User:Brushdemon/Raspberry Pi GPIO

From Gentoo Wiki
Jump to:navigation Jump to:search


Raspberry Pi GPIO Pin Layout[1]
Copyright © 2012-2024 Raspberry Pi Ltd,
CC BY-SA 4.0

Raspberry Pi single board computers contain GPIO (General-Purpose Input-Output) header pins by default on most boards. These pins allow control of external electronic components ranging from a simple LED to more complex hardware commonly found on Raspberry Pi HATs (Hardware Attached on Top). Some GPIO pins can be configured to provide alternate functionality such as:

  • PWM
  • I2C
  • SPI
  • UART

Following steps the at Raspberry_Pi_Install_Guide#Installing_the_Raspberry_Pi_Foundation_files will provide a kernel which contains the /dev/gpiomem kernel character device by default. This character device it is used by programming libraries such as python's gpiozero to provide an easy way of programming GPIO control. The idea behind the /dev/gpiomem device is to allow user access to the GPIO memory bank without giving user access to the entire system memory through the /dev/mem file. The only issue is that by default on a Gentoo system, /dev/gpiomem only allows root read and write access. This page will demonstrate how to configure udev rules so that sudo/root isn't needed to execute programs written using a GPIO library or when using command line pin control tools. These rules will also be useful for configuring alternate pin functionality such as I2C and SPI. The Raspberry Pi 5 operates a little differently to the former versions of the hardware.

Raspberry Pi 5 Changes

All Raspberry Pi's prior to the Raspberry Pi 5 shared the same memory within the VC4 chip to control the GPIO pins, accessed through the /dev/gpiomem character device provided by the Linux Kernel. This required some library writers to manage the GPIO interface using the VC Mailbox API. The Raspberry Pi 5 brought a physically small but practically large change with it's hardware architecture; the RP1 micro-controller.

The RP1 micro-controller is responsible for managing the various south-bridge interfaces. For the purposes of GPIO access, this has meant that the VC4 graphics chip is no longer directly handling the memory for GPIO pins and subsequently, the /dev/gpiomem character device no longer exists on the Pi 5. Instead, you'll find /dev/gpiomem[0-4] as well as gpiochip[0-4]. This change has meant that some older GPIO libraries aren't compatible with the Raspberry Pi 5. As libraries adapt to the RP1, this is subject to change.

The above information can be verified by grepping through the /dev directory on a Raspberry Pi 5:

root #ls -lFa /dev | grep gpio
crw-rw----   1 root gpio    254,   0 Jul  1 20:39 gpiochip0
crw-rw----   1 root gpio    254,   1 Jul  1 20:39 gpiochip1
crw-rw----   1 root gpio    254,   2 Jul  1 20:39 gpiochip2
crw-rw----   1 root gpio    254,   3 Jul  1 20:39 gpiochip3
crw-rw----   1 root gpio    254,   4 Jul  1 20:39 gpiochip4
crw-rw----   1 root gpio    234,   0 Jul  1 20:39 gpiomem0
crw-rw----   1 root gpio    239,   0 Jul  1 20:39 gpiomem1
crw-rw----   1 root gpio    238,   0 Jul  1 20:39 gpiomem2
crw-rw----   1 root gpio    236,   0 Jul  1 20:39 gpiomem3
crw-rw----   1 root gpio    235,   0 Jul  1 20:39 gpiomem4

For comparison sake, the following is the output from a Raspberry Pi 1 B+:

root #ls -lFa /dev | grep gpio
crw-rw----   1 root gpio    254,   0 May 27 23:40 gpiochip0
crw-rw----   1 root gpio    242,   0 Jul  1 20:07 gpiomem

This change practically means that instead of addressing /dev/gpiomem, some libraries such as dev-libs/libgpiod will require you to address /dev/gpiochip4. Chip 4 is the `pinctrl` ABI which maps to the RP1's GPIO controller chip. It's always advised to read through your chosen library's documentation to understand if there are any extra requirements when writing software for a Raspberry Pi 5.

The specifics regarding how the RP1 handles pin functionality are found within the RP1 Peripherals datasheet. As per the datasheet, the functional blocks and their locations on the GPIO pins have been chosen to match user-facing functions on the 40-pin header of a Raspberry Pi 4 Model B.

Pin Functions

Raspberry Pi GPIO pins provide and operate with 3.3v tolerant logic. Connecting peripherals which operate at a different logic level, such as 5V, will damage the Raspberry Pi. Ensure that a logic level shifter is used with these peripherals or find peripherals which operate at the recommended 3.3v logic level.

GPIO Pins have two different numbering schemes which they may be referred to:

  • Physical Pin Numbering
    • Begins from the top left with pin 1 through to the bottom right with pin 40
    • Example: Pin 2 which refers to the 5V pin
  • GPIO Pin Numbering (also referred to as BCM pin numbering)
    • Pins are connected to the Broadcom chip (RP1 on the Pi 5)
    • Example: GPIO 18 refers to physical pin 12

Different programming libraries may refer to either physical or GPIO pin numbering.

Power & Ground

Not all pins on the GPIO header operate as Input/Outputs. Some of them provide specialized functionality such as power output and ground pins. Other pins can operate as standard GPIO but can be configured to provide interfaces for different protocols.

Raspberry Pi's provide the following power and ground pins:

  • Two 5V power output pins
    • Pins 2 & 4
    • Will provide as much current as your power adapter allows
  • Two 3V3 power output pins
    • Pins 1 & 17
    • 500mA - Available since the Raspberry Pi 1 B+ and newer
  • Eight ground pins (all connected to the same rail)
    • Pins 6, 9, 14, 20, 25, 30, 34, and 39

The above power and ground pins can not be reconfigured for regular GPIO functionality. Devices that need higher current should be powered externally and the Pi itself should only be used to control those devices.


GPIO pins on Raspberry Pi's can be configured to either read input or provide output. Because the GPIO pins operate using 3.3v digital logic, the inputs and the outputs represent binary bits by setting the voltage between 0v or 3.3v. When a pin is 0v, it can be described as, "low" which represents a 0. The opposite also holds true where 3.3v is described as, "high" which represents a 1.

Setting a GPIO to either an input or output is library specific and the relevant documentation should be consulted.

The dev-embedded/raspberrypi-utils package provides the "pinctrl" program which allows for pull-up and pull-down reads/write of pins. This is useful for one-off tests where the user may wish to, for example, flash an LED on and off. Users may find more documentation in the Raspberry Pi Utils pinctrl page (not to be confused with the Linux kernel driver of the same name).

GPIO pins can provide a maximum current draw of 16mA.[2] High current demanding components such as motors should be powered externally while the GPIO pin should only be used to control the component. Motors in particular may benefit from more fine grained controlled through the use of PWM.

Less power-hungry components such LED's should use a resistor to limit the current and voltage pulled by the component. Failure to do so may damage the GPIO pin (and potentially the Raspberry Pi board itself).


All GPIO pins can be configured to provide software PWM (Pulse-width modulation). Hardware controlled PWM is available on GPIO12, GPIO13, GPIO18, and GPIO19. PWM is useful for controlling motors and similar hardware where variable speed is desired. The methods for configuring software PWM on a pin are dependent on the GPIO library being used.


I2C (inter-integrated circuit) is a two wire/signal serial communication protocol. The protocol is a relative of serial protocols in that it provides a master/slave relationship between devices/components. Unlike SPI, I2C allows for multiple devices or components to be configured as masters.[3] Raspberry Pi's can be configured as either a master or slave but operating as both simultaneously is not supported.[4]

The I2C protocol needs the following two signals to function:

  • SDA (Data Signal)
    • Sends/Receives data
  • SCL (Data Clock)
    • Keeps the devices/components in sync

On the Raspberry Pi, the following pin pairs can provide an I2C interface[5]:

I2C Function Physical Pin Broadcom/GPIO Pin Pin Function
Data Signal 27 GPIO0 SDA0/ID_SD
Data Clock 28 GPIO1 SCL0/ID_SC

The EEPROM0 I2C interface is primarily used by HATs (Hardware Attached on Top) to communicate it's identification, capabilities and firmware (device tree overlay) necessary for the HAT to function. More information about the HAT standard can be found in HAT+ specification datasheet.

I2C Function Physical Pin Broadcom/GPIO Pin Pin Function
Data Signal 3 GPIO2 SDA1
Data Clock 5 GPIO3 SCL1

I2C1 provides the interface for user projects.

Since the Raspberry Pi 4, more GPIO pins can be configured to provide I2C pins. More information can be found regarding the specifics within each Raspberry Pi's CPU (RP1 for Pi 5) peripherals datasheets. For example, for the Pi 4 this can be found in the BCM2711 Peripherals data sheet; chapter 3: BSC. For the Pi 5, this can be found in the RP1 Peripherals data sheet; chapter 3.5: I2C.


SPI (serial peripheral interface) is a short-distance protocol used primarily by embedded devices to communicate with components. Because SPI is a serial protocol, it operates using a master/slave communication design. On a Raspberry Pi, the SPI interface is used by a number of peripherals which can include: displays, network controllers (Ethernet, CAN bus), UARTs, etc.[6]

The SPI protocol requires 3 serial wires and one chip enable to operate in Standard Mode:

  • CE (Chip Enable; also referred to as Chip Select)
    • The CE line is pulled low to tell the SPI peripheral that communication is ready
  • SCLK (Serial Clock)
    • The master device sends a clock cycle which keeps the main device and peripheral in sync
  • MOSI (Master Out, Slave In)
    • Data line from main device -> peripheral device
  • MISO (Master In, Slave Out)
    • Data line from peripheral device -> main device

The Raspberry Pi Zero, 1, 2, and 3 have two/three SPI hardware controllers.[7] The specifics of how SPI operates on these versions of the Raspberry Pi may be found within BCM2835 Peripherals Datasheet. Specifically Chapter 2.3 - Universal SPI Master (2x) explains how SPI operates and functions, Chapter 10 - SPI explains the specific implementations of the protocol.

Similar to I2C, each SPI interface is named as SPI0, SPI1, etc. The following tables show the pins used for each SPI interface. These tables are very slightly adapted from Raspberry Pi Hardware documentation: Serial Peripheral Interface (SPI), which you should read.

SPI0 - Two hardware chip enables
SPI function Physical Pin Broadcom/GPIO Pin Pin Function
SPI1 - Three hardware chip enables. Not available on 26 GPIO models.
SPI function Physical Pin Broadcom/GPIO Pin Pin Function
CE0 12 GPIO18 SPI1_CE0_N
CE1 11 GPIO17 SPI1_CE1_N
CE2 36 GPIO16 SPI1_CE2_N
SPI2 - Only available on Compute Modules only, except CM4.
SPI function Broadcom/GPIO Pin Pin Function

The Raspberry Pi 4, 400, Compute Module 4, and 5 contain six usable SPI buses. SPI0 and SPI1 are still available on these newer Pi models as well as the following:

SPI function Physical Pin Broadcom/GPIO Pin Pin Function
CE1 18 GPIO24 SPI3_CE1_N
SPI function Physical Pin Broadcom/GPIO Pin Pin Function
CE1 22 GPIO25 SPI4_CE1_N
SPI function Physical Pin Broadcom/GPIO Pin Pin Function
CE0 32 GPIO12 SPI5_CE0_N
CE1 37 GPIO26 SPI5_CE1_N
SPI function Physical Pin Broadcom/GPIO Pin Pin Function
CE0 12 GPIO18 SPI6_CE0_N
CE1 13 GPIO27 SPI6_CE1_N


UART (Universal Asynchronous Receiver / Transmitter), or more commonly just called, "Serial," is a serial protocol which doesn't rely upon a shared clock. Synchronization between devices is achieved by setting the same baud/bit rate on both ends of the connection.

More information regarding this protocol as well as set up on a Gentoo system running on a Raspberry Pi can be found on the Raspberry_Pi_Serial_Ports page.


Configuration of GPIO pins and their alternate functions rely upon two things. The first is the ability to access the memory bank for the GPIO pins which consists of adding udev rules as well as creating groups then adding users to groups. The second is adding the appropriate lines to the /boot/config.txt or /boot/firmware/config.txt. Configuring udev rules and fixing permission issues is a good place to begin.

User GPIO Access

When using using a programming library, such as gpiozero for python or rust_gpiozero for rust, the user running the program won't have the necessary permissions to access the /dev/gpiomem or /dev/gpiochip4 character device. Simply changing the permissions on /dev/gpiomem and similar won't persist between boots. Udev rules provide a way for persistently changing the file ownership and access management of kernel devices.

The Raspberry Pi OS developers have conveniently already written udev rules, which can be found on their RPi-OS github page. Copy the contents of those rules to /etc/udev/rules.d/99-com.rules. You may use your favorite text editor, nano is being used in this demonstration.

root #nano /etc/udev/rules.d/99-com.rules
FILE /etc/udev/rules.d/99-com.rulesRaspberry Pi GPIO Udev Rules Example
SUBSYSTEM=="input", GROUP="input", MODE="0660"
SUBSYSTEM=="i2c-dev", GROUP="i2c", MODE="0660"
SUBSYSTEM=="spidev", GROUP="spi", MODE="0660"
SUBSYSTEM=="*gpiomem*", GROUP="gpio", MODE="0660"
SUBSYSTEM=="rpivid-*", GROUP="video", MODE="0660"

SUBSYSTEM=="gpio", GROUP="gpio", MODE="0660"
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chgrp -R gpio /sys/class/gpio && chmod -R g=u /sys/class/gpio'"
SUBSYSTEM=="gpio", ACTION=="add", PROGRAM="/bin/sh -c 'chgrp -R gpio /sys%p && chmod -R g=u /sys%p'"

# PWM export results in a "change" action on the pwmchip device (not "add" of a new device), so match actions other than "remove".
SUBSYSTEM=="pwm", ACTION!="remove", PROGRAM="/bin/sh -c 'chgrp -R gpio /sys%p && chmod -R g=u /sys%p'"

KERNEL=="ttyAMA[0-9]*|ttyS[0-9]*", PROGRAM="/bin/sh -c '\
        ALIASES=/proc/device-tree/aliases; \
        TTYNODE=$$\(readlink /sys/class/tty/%k/device/of_node | sed 's/base/:/' | cut -d: -f2); \
        if [ -e $$ALIASES/console ]; then \
            if [ $$TTYNODE = $$(strings $$ALIASES/console) ]; then \
                echo 0; \
            elif [ -e $$ALIASES/bluetooth ] && [ $$TTYNODE/bluetooth = $$(strings $$ALIASES/bluetooth) ]; then \
                echo 1; \
            else \
                exit 1; \
            fi \
        elif [ $$TTYNODE = $$(strings $$ALIASES/serial0) ]; then \
            echo 0; \
        elif [ $$TTYNODE = $$(strings $$ALIASES/serial1) ]; then \
            echo 1; \
        else \
            exit 1; \
        fi \
'", SYMLINK+="serial%c"

ACTION=="add", SUBSYSTEM=="vtconsole", KERNEL=="vtcon1", RUN+="/bin/sh -c '\
	if echo RPi-Sense FB | cmp -s /sys/class/graphics/fb0/name; then \
		echo 0 > /sys$devpath/bind; \
	fi; \

The rules above add more than just GPIO access; it also handles what are called, "Peripherals," or more accurately, "Pads" (semiconductor design term meaning, "chip connection to the outside world") within the Broadcom chip. For broad GPIO access, the rules above allow users in the, "gpio" group to access gpio-related kernel devices such as /dev/gpiomem, /dev/gpiochip0, etc.

Next create the "gpio" group.

root #groupadd gpio

Now add the user to the "gpio" group.

root #gpasswd -a youruser gpio

Finally, reboot the Raspberry Pi to ensure that /dev/gpiomem has group permissions set to "gpio".

root #ls -l /dev/gpiomem
crw-rw---- 1 root gpio 241, 0 Jun 16 15:12 /dev/gpiomem


Having followed the above udev steps, enabling I2C simply requires creating the i2c group, adding the user to that group then enabling i2c within /boot/config.txt as well as loading the kernel module.

First, create the "i2c" group.

root #groupadd i2c

Now add the user to the "i2c" group.

root #gpasswd -a youruser i2c

Now append the following to /boot/config.txt.

FILE /boot/config.txtEnable I2C

Finally ensure that the "i2c-dev" module loads at boot.

FILE /lib/modprobe.d/i2c.confLoad I2C Module

Now reboot the Raspberry Pi.

When working with I2C, it may be helpful to install sys-apps/i2c-tools. This package is useful in detecting the I2C bus and the connected components.

root #emerge --ask sys-apps/i2c-tools

sys-apps/i2c-tools installs a command line program "i2cdetect". Running that command with the "-l" option will show available i2c buses. The following is example output on a Raspberry Pi 5.

user $i2cdetect -l
i2c-1	i2c       	Synopsys DesignWare I2C adapter 	I2C adapter
i2c-11	i2c       	107d508200.i2c                  	I2C adapter
i2c-12	i2c       	107d508280.i2c                  	I2C adapter

"i2c-1" maps directly to I2C1 as outlined in the Pin Functionality section of this page.


Similar to I2C, configuring GPIO pins for SPI requires creating the "spi" group, adding a user to it and then appending a line to /boot/config.txt. Enabling an overlay or using dtparam in /boot/config.txt should load the relevant kernel module so there should be no need for creating a new file in the /lib/modprobe.d.

First create the "spi" group.

root #groupadd spi

Now add the user to the "spi" group.

root #gpasswd -a youruser spi

Now append the following to /boot/config.txt.

FILE /boot/config.txtEnable SPI

Now reboot the Raspberry Pi.

Upon reboot, the following kernel character devices should be present.

user $ls -l /dev | grep spi
crw-rw----  1 root spi     153,   1 Jul 13 16:18 spidev0.0
crw-rw----  1 root spi     153,   2 Jul 13 16:18 spidev0.1
crw-rw----  1 root spi     153,   0 Jul 13 16:18 spidev10.0

"spidev" is the kernel driver in use. "spidev0" translates to SPI0 as outlined in the Pin Functionality section of this page. "spidev0.0" and "spidev0.1" represent CE0 and CE1.

Alternate Busses

To enable different SPI busses (provided that the model of Raspberry Pi being used supports it) can be enabled by using the relevant dtoverlay.

Finding what overlays are available should be present within the /boot/overlays directory.

user $ls /boot/overlays | grep spi[0-9]-

Take for instance the dtoverlay, "spi1-2cs," will enable SPI1 with only two chip selects CE0 and CE1.

To use this overlay, append the following to /boot/config.txt.

FILE /boot/config.txtEnable alternate SPI

Reboot the Raspberry Pi and then confirm that the correct spidev character devices exist.

user $ls -l /dev | grep spi
crw-rw----  1 root spi     153,   2 Jul 13 16:50 spidev1.0
crw-rw----  1 root spi     153,   0 Jul 13 16:50 spidev10.0
crw-rw----  1 root spi     153,   1 Jul 13 16:50 spidev1.1


Configuring UART can be found on the Raspberry_Pi_Serial_Ports page.

Common GPIO Libraries

There are many Raspberry Pi GPIO libraries available. The table below includes the names of some libraries and links to the relevant locations for documentation.

Many of these libraries have working ebuilds found within the Home Assistant Repository.

Raspberry Pi GPIO Libraries
Library Language(s) Download Documentation Notes
pigpio C
dev-libs/pigpio The pigpio library
  • Likely wont be compatible with Pi 5 and newer boards[8][9]
libgpiod C
dev-libs/libgpiod git README's; the documentation is the code
  • Does work with the Raspberry Pi 5.
  • Python version was formerly known as "gpiod" before merging with libgpiod[10]
bcm2835 C airspayce website airspayce website
  • An older library; potentially won't work with Pi 5 due to RP1 changes
wiringpi C
Bindings for other languages exist - Severely out of date
Github None currently - Web Archive version only
  • In a state of transition as new developers have taken over the project[11][12]
  • Pi 5 missing PWM features [13]
gpiozero Python Github
  • Raspberry Pi Org. recommended and pre-installed on Raspberry Pi OS[14]
  • Requires the python packages: spidev, RPi.GPIO,[15] and colorzero[16] to function correctly
RPi.GPIO Python pypi
  • Popular choice prior to gpiozero
  • More commonly used as a pin factory for gpiozero
  • Doesn't work with Pi 5[17]
rust_gpiozero Rust Github
Github README provides beginner examples
  • Add to projects cargo.toml
rppal Rust Github
Github README provides important information
  • Add to projects cargo.toml

External Resources


  • BCM2835 Peripherals - CPU package used on the Pi 1 and Zero. May prove useful for Pi's up to the 3b+.
  • BCM2836 Peripherals - CPU package used on the Pi 2. The following use use the same peripherals data sheet:
    • BCM2837 - CPU package of the Pi 2 version 1.2 and 3B. The package is the same as the BCM2836 except the Cortex-A7 cluster was switched out for a quad core Cortex-A52 cluster.
    • BCM2837B0 - CPU package of the Pi 3A+ and 3B+. The package is the same as the BCM2837 except the Cortex-A52 cluser was switched out for a quad core Cortex-A53 MPCore cluster.
    • RP3A0 - CPU package used in the Pi Zero 2 W. The package is similar to the BCM2837.
  • BCM2711 Peripherals - CPU package used in the Pi 4.
  • RP1 Peripherals - The Raspberry Pi 5 southbridge microcontroller. This chip controls most of the IO hardware on the Pi 5.


  1. Raspberry Pi Ltd, GPIO-Pinout-Diagram, GPIO and the 40-pin header, Retrieved on June 25th, 2024
  2. Les Pounder, Raspberry Pi GPIO Pinout: What Each Pin Does on Pi 4, Earlier Models, Tom's Hardware, Marth 28th, 2023. Retrieved July 6th, 2024
  3. Sam, I2C with Raspberry Pi, Core Electronics, October 28th, 2022. Retrieved July 12th, 2024
  4. Raspberry Pi Ltd, RP1 Peripherals: 3.5. I2C, Raspberry Pi Website, 2023. Retrieved July 6th, 2024
  5. Raspberry Pi Ltd, GPIO and the 40-pin header: Alternative Functions, Raspberry Pi Website, Retrieved July 6th, 2024
  6. Raspberry Pi Ltd, Serial Peripheral Interface (SPI), Raspberry Pi Website, Retrieved July 10th, 2024
  7. Raspberry Pi Ltd, Serial Peripheral Interface (SPI), Raspberry Pi Website, Retrieved July 10th, 2024
  8. joan2937, pigpio Issue 586, pigpio Github repository, September 28th, 2023. Retrieved on July 2nd, 2024
  9. JinShil, pigpio Issue 589, pigpio Github repository, November 7th, 2023. Retrieved on July 2nd, 2024
  10. hhk7734, python3-gpiod README, python3-gpiod Github repository, May 20th, 2024. Retrieved on July 2nd, 2024
  11. Gordon Henderson, wiringPi - deprecated (web archive), (web archive), August 6th, 2019. Retrieved July 2nd 2024
  12. GrazerComputerClub, wiringPi README, GrazerComputerClub Github Page, March 13th, 2024. Retrieved on July 2nd, 2024
  13. mstroh76, Wiring Pi Issue 21, GrazerComputerClub Github Page, February 27th, 2024. Retrieved July 2nd, 2024
  14. Raspberry Pi Ltd, Use Python on a Raspberry Pi, Raspberry Pi, Retrieved July 2 2024
  15. Ben Nuttall, gpiozero Documentation - Development, gpiozero readthedocs, Retrieved July 2, 2024
  16. Ben Nuttall & Dave Jones, gpiozero setup.cfg, gpiozero Github, Retrieved July 2nd, 2024
  17. Melissa LeBlanc-Williams, Plans to support Raspberry Pi 5, RPi.GPIO sourceforge, October 19th, 2023. Retrieved July 2nd, 2024