3. 配置板卡引脚复用

配置板卡引脚复用 学习卡片

任务目标

在Zephyr板卡设备树中定义pinctrl节点,为UART和GPIO外设配置引脚复用功能,并通过设备树编译与运行时API验证引脚配置正确。

环境依赖

本案例基于Zephyr RTOS 3.4+,使用nRF52840DK作为目标板(引脚定义与Nordic SoC一致)。需要安装Zephyr SDK与west工具链,并已创建基础BSP工程。

实现步骤

在板卡设备树文件(boards/arm/your_board/your_board.dts)中完成以下操作:

  1. 定义pinctrl根节点,包含UART0和GPIO0的引脚状态组;
  2. 为UART0配置TX/RX引脚复用(P0.06/P0.08);
  3. 为GPIO0配置LED引脚(P0.13)为输出模式;
  4. 在&uart0和&gpio0节点中通过pinctrl-0引用对应状态。

关键完整代码

以下为your_board.dts中pinctrl配置的核心片段(完整文件需包含SoC头文件与其它外设节点):

#include "your_board_common.dtsi"

&pinctrl {
    uart0_default: uart0_default {
        group1 {
            psels = <NRF_PSEL(UART_TX, 0, 6)>,
                    <NRF_PSEL(UART_RX, 0, 8)>;
            nordic,drive-mode = <NRF_DRIVE_H0H1>;
            bias-pull-up;
        };
    };

    gpio0_default: gpio0_default {
        group1 {
            psels = <NRF_PSEL(GPIO_OUTPUT, 0, 13)>;
            drive-push-pull;
        };
    };
};

&uart0 {
    compatible = "nordic,nrf-uarte";
    current-speed = <115200>;
    pinctrl-0 = <&uart0_default>;
    pinctrl-names = "default";
    status = "okay";
};

&gpio0 {
    status = "okay";
    pinctrl-0 = <&gpio0_default>;
    pinctrl-names = "default";
};

若SoC使用nrf-gpio而非gpio0节点名,需按实际SoC头文件调整。GPIO的pinctrl状态通常仅用于特殊引脚(如模拟功能),普通数字GPIO可直接在gpio0节点下配置,无需pinctrl——此处为演示完整pinctrl语法而保留。

验证方法

  1. 编译验证:执行west build -b your_board,若设备树存在语法错误或引脚冲突,编译将失败并提示具体节点与属性问题。
  2. 运行时验证:在应用代码中调用以下API确认引脚状态:
#include <zephyr/kernel.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/drivers/gpio.h>

void verify_pinctrl(void) {
    const struct device *uart = DEVICE_DT_GET(DT_NODELABEL(uart0));
    const struct device *gpio = DEVICE_DT_GET(DT_NODELABEL(gpio0));

    // 检查UART设备就绪
    if (!device_is_ready(uart)) {
        printk("UART not ready\n");
        return;
    }

    // 检查GPIO引脚可写
    gpio_pin_configure(gpio, 13, GPIO_OUTPUT);
    gpio_pin_set(gpio, 13, 1);
    printk("Pinctrl config verified\n");
}

通过条件:编译无错误;烧录后串口输出Pinctrl config verified;用逻辑分析仪或万用表测量P0.13引脚为高电平(3.3V),P0.06/P0.08在UART空闲时为高电平。

常见问题

  • 引脚冲突:若两个外设使用同一引脚,编译时会出现pin already assigned错误,需检查psels定义。
  • 状态组命名:Zephyr要求pinctrl状态组名唯一,且pinctrl-names中的字符串必须与pinctrl-0等属性顺序对应。
  • SoC差异:不同SoC的NRF_PSEL宏参数含义不同,需查阅对应SoC的dts/arm/nordic头文件。