🛠 Faire clignoter une LED avec libgpiod (numérotation GPIO du A64 : PB0 = 32)
Objectives
First steps with GPIO on the PINE A64 running a mainline kernel (Armbian). Two specificities to keep in mind right away: (1) Allwinner's GPIO numbering follows the formula offset = (bank − A) × 32 + pin, so PB0 = 1×32 + 0 = 32, PD16 = 112, PH2 = 226 — forget the Raspberry Pi BCM numbering; (2) the 40-pin "Pi-2" connector does not have the RPi pinout: its UART is on PB0/PB1 (offsets 32/33, commented as "On Pi-2 connector" in the device tree). You will wire an LED, make it blink in the shell using gpioset, and then in C using libgpiod.
Hardware
- 1 × PINE A64/A64+ running Armbian (mainline kernel
currentoredge) - 1 × LED + 330 Ω to 1 kΩ resistor
- Breadboard wires — 3.3 V logic on the Pi-2 connector (Allwinner I/O standard, not 5 V tolerant)
sudo apt install gpiod libgpiod-dev
Full code
# Repérer la puce GPIO (le pilote pinctrl-sun50i-a64 est gpiochip0) :
gpioinfo gpiochip0 | head
# Clignoter en shell — PB0 => offset 32 :
while true; do gpioset gpiochip0 32=1; sleep 0.5; gpioset gpiochip0 32=0; sleep 0.5; done
/* blink.c — gcc blink.c -o blink -lgpiod */
#include <gpiod.h>
#include <unistd.h>
int main(void) {
/* PB0 : (B-A)*32 + 0 = 32 (pilote pinctrl sun50i-a64 = gpiochip0) */
struct gpiod_chip *chip = gpiod_chip_open_by_name("gpiochip0");
if (!chip) { perror("gpiochip0"); return 1; }
struct gpiod_line *led = gpiod_chip_get_line(chip, 32); /* PB0 */
if (gpiod_line_request_output(led, "blink", 0)) { perror("request PB0"); return 1; }
for (int i = 0; i < 10; i++) {
gpiod_line_set_value(led, i & 1);
sleep(1);
}
return 0;
}
Expected verification
The LED blinks at 1 Hz (shell script: 0.5 s). gpioinfo gpiochip0 lists the A64 pins with their names (PB0 at offset 32): this is the tool that corrects your numbering before any wiring. Since PB0/PB1 were originally the UART2 pins of the Pi-2 connector, the device tree leaves them status = "disabled" by default — as long as you do not enable uart2, you can use them as GPIO outputs without conflict.
Common errors
- Using "Raspberry Pi" numbers (BCM): the A64 mainline numbering is bank×32+pin (PB0 = 32, PH2 = 226); the exposed banks are PB, PC, PD, PE, PF, PG, PH — there is no "GPIO 17" here.
- Believing an RPi shield/HAT is compatible: the Pi-2 connector is mechanically compatible only — UART is on PB0/PB1 (physical pins 11/12), I2C1 on PH2/PH3, SPI0 on PC0–PC3. >
- Injecting 5 V into a pin: all connector logic is 3.3 V (Allwinner I/O standard).
- Forgetting the current-limiting resistor: an LED connected directly to 3.3 V draws too much current from the pin.
- Looking for an ADC or hardware PWM on the Pi-2 connector: the A64 exposes a TPADC/LRADC (used by the Pinebook battery) but it is not routed to the 40-pin connector; no routed PWM is claimed here either — the datasheet PDF has not been machine-verified.
- In C, forgetting to check the chip name (
gpiochip0assumes a single controller): on a system with other GPIO drivers, rungpioinfofirst.
Other tutorials for this board
- Premier boot d'Armbian sur la PINE A64 (microSD, console série, rootfs)
- PINE A64 ou PINE A64+ ? Le pièg du réseau gigabit dès le premier regard
- Benchmark Ethernet iperf3 : mesurer le piège 10/100 vs gigabit
- Lire un capteur I²C (BME280) sur le bus i2c-1 du connecteur Pi-2
- Un serveur maison qui consomme 2,5 W : Docker léger sur la PINE A64
- Construire sa propre image Armbian pour la PINE A64 (armbian/build)
Code examples for this board
clignotante.pyPythonbouton-gpio.pyPythoncapteur-i2c.shBashsurveillance-temperature.shBashcapteur-dht11.pyPythonservo-pwm-sysfs.shBash