With the new Raspberry Pi 5 coming out, it is time to add support to Blinka, our CircuitPython library compatibility layer. One of the biggest changes to the Raspberry Pi 5 is the addition of a new southbridge chip, called the RP1, which now handles the GPIOs. Like many other projects, we have been the RPi.GPIO library to handle the General Purpose Input/Outputs. The only issue is that RPi.GPIO does not work on the Raspberry Pi 5 due to a changed memory mapping. Whereas everything was handled by the /dev/gpiomem
device before, now everything is dynamically split into multiple gpiomem devices. The 40-pin GPIO header happens to fall into /dev/gpiomem4
.
So this means it's time to look at a couple of new options that do work on the Raspberry Pi 5. The two biggest contenders are libgpiod and gpiozero, though there does appear to be a pure python version of libgpiod called gpiod. RPi.GPIO was written in c, so it should run faster than a pure python implementation, however as mentioned before, that no longer appears to be an option. So the replacement should be able to run as fast as possible.
On the surface, libgpiod appears to be the better option because of several different factors:
- The python bindings use the libgpiod library underneath, which itself is written in c
- We already have multiple other libraries using libgpiod, so adding it is much simpler
- Looking at the source, gpiozero appears to be a pure python implementation
On the other hand, Raspberry Pi is recommending gpiozero as the replacement to use on the the Raspberry Pi 5. So it's time to compare them head to head on speed alone. In order to test the speed, each library will turn a GPIO on and off as rapidly as possible and the results will be measured with a logic analyzer. The environment will be a fresh install of the 64-bit lite version or Raspberry Pi OS Bookworm since that is the minimum that the Raspberry Pi 5 requires. The scripts will be running inside of a virtual environment as is recommended now.
First up will be libgpiod. The script that will be used is:
import gpiod chip = gpiod.Chip('gpiochip4', gpiod.Chip.OPEN_BY_NAME) line = chip.get_line(18) line.request(consumer="blinktest", type=gpiod.LINE_REQ_DIR_OUT) while True: line.set_value(1) line.set_value(0)
After running the script and measuring, it looks like the mean frequency is 281.57 kHz, which means it can turn the GPIO on or off at an astounding 281,570 times per second on average. Since this measures a full cycle of turning a GPIO both on and off, that means the speed just to flip it in one direction averages about 563.14 kHz,
Next up is gpiozero. The script that will be used is:
from gpiozero import LED led = LED(18) while True: led.on() led.off()
After running the script and measuring, it looks like the mean frequency is 93.659 kHz, which means it can turn the GPIO on and off 93,659 times per second on average. The speed to flip it in a single direction would then average 187.318 kHz.
So clearly libgpiod is the winner at just over 3 times the speed of gpiozero!