Write a simple LED driver with DeviceTree for Raspberry Pi 5
- What is a Device Tree?
- Method 1: How to use the existing generic LED driver to control a GPIO.
- Method 2: How to write a custom LED driver from scratch to control a GPIO.
1.What is Device Tree
The Device Tree (DT) is the industry-standard data structure used by the Linux kernel to describe hardware that cannot be automatically discovered by the CPU (such as GPIOs, I2C devices, and on-chip controllers).Think of the Device Tree as a hardware blueprint. It separates the hardware description from the kernel binary code.Think of the Device Tree as a hardware blueprint. It separates the hardware description from the kernel binary code.
- Old Way (Pre-DT): Every board had a hardcoded C file inside the kernel source. Changing a single GPIO pin required recompiling the entire kernel.
- Modern Way (With DT): The hardware layout is written in a text file (
.dts). This is compiled into a binary (.dtb) that the bootloader (like U-Boot) passes to the kernel at startup.
The Development Workflow
You rarely write a Device Tree from scratch. The typical process looks like this:
- Start with Vendor Source: You get a basic
.dtsfile from the chip maker (the SoC vendor) that describes the CPU core. - Customize for Your Board: You create a new
.dtsfile for your specific target board. Inside this file, you include the vendor's basic file (e.g.,#include "bcm2712.dtsi") and then add your specific hardware design (like your LEDs, sensors, or screen). - Compile: You use the Device Tree Compiler (DTC) to convert your human-readable
.dtsinto a machine-readable.dtb. - Boot: The bootloader loads this
.dtbinto memory and starts the kernel.
arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts. Because the device tree is modular, you will see it includes other files like #include "bcm2712-dtsi".How to get raspberry pi kerenl source code.
Key Terminology
DTS (Device Tree Source): The human-readable text file where developers describe the hardware.
DTB (Device Tree Blob): The binary version that the kernel actually reads.
DTC (Device Tree Compiler): The tool that converts
.dtsto.dtb.
2.The Easy Way (Using the Existing Driver)
gpio-leds driver.Step 1: Create the Overlay (Host Computer)
rpi_gpio27_led.dts. This overlay tells the kernel: "Hey, there is an LED connected to GPIO 27, please manage it using the standard driver."/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2712";
fragment@0 {
target-path = "/";
__overlay__ {
my_led_device {
compatible = "gpio-leds";
led27 {
label = "rpi5::gpio27";
gpios = <&rpi1_gpio 27 0>; /* 0 is active high */
default-state = "off";
};
};
};
};
};
Code Explanation:
/dts-v1/;Declares the file as Version 1 of the Device Tree syntax./plugin/;This is critical. It informs the compiler that this is an Overlay, designed to be "grafted" onto the existing live system device tree rather than replacing it entirely.compatible = "brcm,bcm2712";Specifies compatibility with the Raspberry Pi 5's SoC (BCM2712). This serves as a safety check to prevent loading the overlay onto incompatible hardware like a Pi 4.fragment@0Overlays consist of multiple fragments. This is the first logical block of changes.target-path = "/";Specifies that the new node should be inserted at the Root of the main device tree.__overlay__Everything defined inside this block will be "injected" into the target path once the overlay is loaded.compatible = "gpio-leds";The most important property. It instructs the kernel to load the standardleds-gpiodriver. This triggers thegpio_led_probefunction built into Linux.led27The child node name representing this specific LED in the device tree structure.label = "rpi5::gpio27";This is the name that will appear in userspace. After loading, you will find the directory at/sys/class/leds/rpi5::gpio27/.gpios = <&rp1_gpio 27 0>;&rp1_gpio: Points to the GPIO controller on the RP1 southbridge chip (for Pi 5).27: The GPIO pin number.0: The flag bit.0represents Active High.default-state = "off";Ensures the LED is initialized to an "off" state when the driver is first loaded.
Step 2: Transfer to Target
Copy the rpi_gpio27_led.dts file from your host PC to the Raspberry Pi 5.
$scp rpi_gpio27_led.dts linda@10.1.xx.xxx:/home/linda/
Step 3: Compile and Apply (Target Board)
Log into your Raspberry Pi 5 and compile the file:
Step 4: Verification and Test the LED
3.The Custom Way (Writing Your Own Driver)
Goal: Write a custom kernel module to control GPIO 17.
Prerequisites: You need a configured Linux kernel build environment. (Refer to "Write the Very first HelloWorld driver." for setup).
Step 1: Explain The Driver Code "led17_driver_sys.c" (Host Computer)
The demo source code is on my github, if need to download.
Step 2: The Device Tree Overlay "rpi_gpio17_led.dts"(Host Computer)
Step 3: Compile and Deploy (Host Computer)
Compile the Driver:
Transfer Files: Copy the .ko file and the .dts file to your Raspberry Pi 5.
Step 4:Compile, Apply and Insert Driver (Target Board)
Step 5: Verification and Test the LED
Reference
- LED handing under Linux https://docs.kernel.org/leds/leds-class.html
- ACTIVE LOW/ACTIVE HIGH LED https://www.youtube.com/watch?v=BQ974qIJsOM
- Raspberry Pi Kernel https://www.raspberrypi.com/documentation/computers/linux_kernel.html
Comments