blink_c.c
C version with libgpiod: the program requests GPIO17 as output on gpiochip0, toggles it 20 times at 1 Hz, then releases everything cleanly. Great for Python-free systemd services and for learning the kernel gpiochip model. Verify the pin on the J8 schematic (40 pins).
Hardware
A Raspberry Pi 5 (quad-core BCM2712 at 2.4 GHz, RP1 I/O chip, 40-pin GPIO, recommended 5 V/5 A USB-C power, two CSI camera ports). One LED, 330-ohm resistor, gcc and libgpiod-dev on the board.
Wiring
LED + resistor between GPIO17 (pin 11) and GND; never 5 V into a GPIO line.
How it works
gpiod_chip_open_by_name opens the controller, gpiohandle_request_lines claims the line as output, gpiohandle_set_values writes the level; release hands the pin back.
Running it
Copy the script to the board (scp), then run it with python3. On Bookworm, gpiozero 2.x drives the pins through the RP1 chip; keep gpiozero and python3-rpi.gpio updated (sudo apt full-upgrade). A 5 V/5 A supply is advised.
Variants
Compile with -O2 for a daemon; gpiod_line_event_wait for event-driven C. A 27 W (5 V/5 A) supply is recommended; without it USB output is capped at 600 mA total.
blink_c.c
/* blink_c.c — clignotement LED en C avec libgpiod (API v1 gpiohandle). */
/* Deps: sudo apt install libgpiod-dev ; gcc blink_c.c -lgpiod -o blink_c */
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
struct gpiod_chip *chip = gpiod_chip_open_by_name("gpiochip0");
if (!chip) { perror("gpiochip0"); return 1; }
struct gpiohandle_data data = { .values[0] = 0 };
struct gpiohandle_request req = {
.lineoffsets = { 17 }, /* GPIO17, broche 11 */
.flags = GPIOHANDLE_REQUEST_OUTPUT,
.lines = 1, .default_values = { 0 },
.consumer_label = "blink-c",
};
if (gpiohandle_request_lines(gpiod_chip_get_line(chip, 17), &req))
{ perror("request"); return 1; }
for (int i = 0; i < 20; i++) {
data.values[0] = !data.values[0];
gpiohandle_set_values(&req, &data);
usleep(500000);
}
gpiohandle_release(&req); gpiod_chip_close(chip);
return 0;
}