4. 使用设备树配置硬件
任务目标
在Zephyr项目中,通过设备树(Device Tree)描述硬件资源(如LED、UART、GPIO按键),并验证设备树配置能够正确生成对应的设备宏与访问接口。本案例以nRF52840 DK开发板为硬件目标,完成一个最小可复现的设备树配置与验证闭环。
环境与依赖
- Zephyr RTOS 3.4+,已安装west工具链
- 硬件:nRF52840 DK(或使用QEMU模拟同一SoC)
- 项目基础:已通过
west init与west update完成Zephyr源码同步
实现步骤
在应用目录下创建boards/目录,为nRF52840 DK添加板级设备树覆盖文件。该文件在原始SoC设备树基础上,为GPIO0的引脚20(对应DK板载LED1)添加led标签,并声明一个gpio-keys节点用于按键输入。
关键完整代码
// 文件:boards/nrf52840dk_nrf52840.overlay
/ {
leds {
compatible = "gpio-leds";
led0: led_0 {
gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
label = "Green LED";
};
};
keys {
compatible = "gpio-keys";
button0: button_0 {
gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
label = "Button 1";
};
};
};
&gpio0 {
status = "okay";
};
// 文件:src/main.c
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/devicetree.h>
// 从设备树获取节点标识
#define LED0_NODE DT_ALIAS(led0)
#define BUTTON0_NODE DT_ALIAS(button0)
#if DT_NODE_HAS_STATUS(LED0_NODE, okay)
#define LED0_GPIO_LABEL DT_GPIO_LABEL(LED0_NODE, gpios)
#define LED0_GPIO_PIN DT_GPIO_PIN(LED0_NODE, gpios)
#define LED0_GPIO_FLAGS DT_GPIO_FLAGS(LED0_NODE, gpios)
#else
#error "LED0 node not found in device tree"
#endif
void main(void)
{
const struct device *led_dev;
const struct device *btn_dev;
int ret;
// 验证设备树节点已生成设备实例
led_dev = device_get_binding(LED0_GPIO_LABEL);
if (!led_dev) {
printk("LED device not found\n");
return;
}
btn_dev = device_get_binding(DT_GPIO_LABEL(BUTTON0_NODE, gpios));
if (!btn_dev) {
printk("Button device not found\n");
return;
}
// 配置LED引脚为输出
ret = gpio_pin_configure(led_dev, LED0_GPIO_PIN,
GPIO_OUTPUT_ACTIVE | LED0_GPIO_FLAGS);
if (ret < 0) {
printk("LED config failed: %d\n", ret);
return;
}
// 配置按键引脚为输入
ret = gpio_pin_configure(btn_dev,
DT_GPIO_PIN(BUTTON0_NODE, gpios),
GPIO_INPUT | DT_GPIO_FLAGS(BUTTON0_NODE, gpios));
if (ret < 0) {
printk("Button config failed: %d\n", ret);
return;
}
// 验证:读取按键状态并控制LED
while (1) {
int val = gpio_pin_get(btn_dev, DT_GPIO_PIN(BUTTON0_NODE, gpios));
gpio_pin_set(led_dev, LED0_GPIO_PIN, val ? 0 : 1);
k_msleep(100);
}
}
构建与运行
# 在应用目录下执行
west build -b nrf52840dk_nrf52840 .
west flash
验证方法与判定标准
构建成功且无#error触发,说明设备树节点被正确解析。烧录后观察:
- 按下DK板上的Button 1(P0.11),LED1(P0.20)点亮;松开后熄灭。
- 若使用QEMU,可通过
west build -t run启动,串口输出无错误信息即通过。
该行为直接证明设备树中GPIO引脚编号、标志位与SoC实际引脚映射一致,且DT_ALIAS、DT_GPIO_LABEL等宏已从设备树生成有效配置。
常见问题
- 编译报错“node not found”:检查overlay文件名是否与
west build -b指定的板型完全匹配(如nrf52840dk_nrf52840.overlay)。 - 引脚无响应:确认DK板丝印标注的Button 1对应P0.11,LED1对应P0.20;不同板卡版本可能引脚不同,以官方原理图为准。