User:Brushdemon/Raspberry Pi GPIO

From Gentoo Wiki
Jump to:navigation Jump to:search

TODO

This page is currently a work in progress.

The following are some C&C and things still missing from this page.

  • Reference using the firmware section of the installation page instead of sys-boot/raspberrypi-firmware.
  • Add a safety/warning section talking about the physical limitations of the GPIO pins as mentioned in the discussions page.
  • Add sections talking about enabling and using SPI and I2C.
    • Mention config.txt and creating then adding the groups needed for the udev rules to work correctly.
    • If config.txt options are talked about, may as well talk about the options to swap around the numbering of pins.
    • Talk about Hardware PWM pins and the ability to generate SW duty cycles on regular GPIO pins.
  • Link to Raspberry_Pi_Serial_Ports. D.R.Y. (even if you didn't write it).
  • Potentially move this page to a dedicated subpage of the install guide.

Overview

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

Raspberry Pi boards 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. Some GPIO pins can be configured to provide alternate functionality such as:

  • PWM
  • SPI
  • I2C
  • UART/Serial (GPIO 14 & 15)


Following steps 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 only issue with the /dev/gpiomem character device is that by default on a Gentoo system, it 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. 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 handling the interface for GPIO pins and subsequently, the /dev/gpiomem character device no longer exists on the Pi 5. Instead, you'll find /dev/gpiomem0-4 as well as gpiochip0-4. This change has meant that some older GPIO libraries aren't compatible with the Raspberry Pi 5. This may be 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` interface provided by the RP1. It's always advised to read through the specific library's documentation to understand if there are any extra requirements when writing software for a Raspberry Pi 5.

Physical Properties

Warning
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 can 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 directly to the Broadcom chip (RP1 on the Pi 5)
    • Example: GPIO 18 which 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

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. More

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

The dev-embedded/raspberrypi-utils package provides the "pinctrl" program which allows for pull-up and pull-down readings on pins. This is useful for one-off testing of pins. Users may find more documentation in the Raspberry Pi Utils pinctrl page.

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.


PWM

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.

The Raspberry Pi also allows for alternate functions which allow for connected components to communicate to the Pi using different protocols.


I2C

I2C (inter-integrated circuit) is a two wire/signal serial communication protocol. The protocol is similar to the serial protocol in that it provides a master/slave relationship between devices/components. Raspberry Pi's can be configured as either a master or slave but operating as both simultaneously is not supported.[3]

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[4]:

  • I2C0
    • Pin 3/GPIO 2: SDA 1
    • Pin 5/GPIO 3: SCL 1
  • EEPROM0
    • Pin 27/GPIO 0: SDA 0
    • Pin 28/GPIO 1: SCL 0


The EEPROM0 I2C interface is primarily used by HATs (Hardware Attached on Top) to communicate the capabilities and firmware necessary for the HAT to function.

Since the Raspberry Pi 4, more GPIO pins can be configured to provide I2C interfaces. 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.

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

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
Python
dev-libs/pigpio The pigpio library
  • Likely wont be compatible with Pi 5 and newer boards[5][6]
libgpiod C
Python
Rust
dev-libs/libgpiod kernel.org 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[7]
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[8][9]
  • Pi 5 missing PWM features [10]
gpiozero Python Github readthedocs.io
  • Raspberry Pi Org. recommended and pre-installed on Raspberry Pi OS[11]
  • Requires the python packages: spidev, RPi.GPIO,[12] and colorzero[13] to function correctly
RPi.GPIO Python pypi
sourceforge
sourceforge
  • Popular choice prior to gpiozero
  • More commonly used as a pin factory for gpiozero
  • Doesn't work with Pi 5[14]
rust_gpiozero Rust Github docs.rs
Github README provides beginner examples
  • Add to projects cargo.toml
rppal Rust Github docs.rs
Github README provides important information
  • Add to projects cargo.toml

External Resources

References

  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. Raspberry Pi Ltd, RP1 Peripherals: 3.5. I2C, Raspberry Pi Website, 2023. Retrieved July 6th, 2024
  4. Raspberry Pi Ltd, GPIO and the 40-pin header: Alternative Functions, Raspberry Pi Website, Retrieved July 6th, 2024
  5. joan2937, pigpio Issue 586, pigpio Github repository, September 28th, 2023. Retrieved on July 2nd, 2024
  6. JinShil, pigpio Issue 589, pigpio Github repository, November 7th, 2023. Retrieved on July 2nd, 2024
  7. hhk7734, python3-gpiod README, python3-gpiod Github repository, May 20th, 2024. Retrieved on July 2nd, 2024
  8. Gordon Henderson, wiringPi - deprecated (web archive), wiringpi.com (web archive), August 6th, 2019. Retrieved July 2nd 2024
  9. GrazerComputerClub, wiringPi README, GrazerComputerClub Github Page, March 13th, 2024. Retrieved on July 2nd, 2024
  10. mstroh76, Wiring Pi Issue 21, GrazerComputerClub Github Page, February 27th, 2024. Retrieved July 2nd, 2024
  11. Raspberry Pi Ltd, Use Python on a Raspberry Pi, Raspberry Pi, Retrieved July 2 2024
  12. Ben Nuttall, gpiozero Documentation - Development, gpiozero readthedocs, Retrieved July 2, 2024
  13. Ben Nuttall & Dave Jones, gpiozero setup.cfg, gpiozero Github, Retrieved July 2nd, 2024
  14. Melissa LeBlanc-Williams, Plans to support Raspberry Pi 5, RPi.GPIO sourceforge, October 19th, 2023. Retrieved July 2nd, 2024