zephyr的设备树脚本将/zephyr,user节点作为特例处理:可以在其中放置任意的属性,并在不需要编写的绑定的情况下检索它们的值

简单值

在构建时通过设备树进行配置,可以将数字或数组存储在节点中

/ {
     zephyr,user {
             boolean;
             bytes = [81 82 83];
             number = <23>;
             numbers = <1>, <2>, <3>;
             string = "text";
             strings = "a", "b", "c";
     };
};

在c中通过下面的方式获取

#define ZEPHYR_USER_NODE DT_PATH(zephyr_user)

DT_PROP(ZEPHYR_USER_NODE, boolean) // 1
DT_PROP(ZEPHYR_USER_NODE, bytes)   // {0x81, 0x82, 0x83}
DT_PROP(ZEPHYR_USER_NODE, number)  // 23
DT_PROP(ZEPHYR_USER_NODE, numbers) // {1, 2, 3}
DT_PROP(ZEPHYR_USER_NODE, string)  // "text"
DT_PROP(ZEPHYR_USER_NODE, strings) // {"a", "b", "c"}

设备

在简单情况下使用设备树覆盖重新配置您的应用程序使用的设备

/ {
     zephyr,user {
             handle = <&gpio0>;
             handles = <&gpio0>, <&gpio1>;
     };
};

可以将handle和handles属性中的phandles转换为设备指针

/*
 * Same thing as:
 *
 * ... my_dev = DEVICE_DT_GET(DT_NODELABEL(gpio0));
 */
const struct device *my_device =
     DEVICE_DT_GET(DT_PROP(ZEPHYR_USER_NODE, handle));

#define PHANDLE_TO_DEVICE(node_id, prop, idx) \
     DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)),

/*
 * Same thing as:
 *
 * ... *my_devices[] = {
 *         DEVICE_DT_GET(DT_NODELABEL(gpio0)),
 *         DEVICE_DT_GET(DT_NODELABEL(gpio1)),
 * };
 */
const struct device *my_devices[] = {
     DT_FOREACH_PROP_ELEM(ZEPHYR_USER_NODE, handles, PHANDLE_TO_DEVICE)
};

GPIOs

用于存储您希望能够通过设备树覆盖进行重新配置的特定于应用程序的GPIO

#include <zephyr/dt-bindings/gpio/gpio.h>

/ {
     zephyr,user {
             signal-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
     };
};

可以将signal-gpios中定义的引脚转换为源码中的struct gpio_dt_spec

#include <zephyr/drivers/gpio.h>

#define ZEPHYR_USER_NODE DT_PATH(zephyr_user)

const struct gpio_dt_spec signal =
        GPIO_DT_SPEC_GET(ZEPHYR_USER_NODE, signal_gpios);

/* Configure the pin */
gpio_pin_configure_dt(&signal, GPIO_OUTPUT_INACTIVE);

/* Set the pin to its active level */
gpio_pin_set_dt(&signal, 1);

具体用法

  1. 我使用的是NCS,也就是nordic的开发包,在vscode中开发,通过图形界面添加,所以打开自己已有的工程
  2. 点击设备树

  3. 找到GPIOs框
  4. 点击加号,弹出命名窗口
  5. 点击确认,然后选择没有使用的引脚即可
  6. 窗口会出现如下的界面
  7. 然后保存,到overlay文件中,看到如下的内容
  8. 选择自己的需要的驱动方式,具体提示,鼠标放到上面会提示,上拉,激活方式,驱动方式等,重新保存就会得到atk_8266_reset-gpios类似的结构
  9. 应用,以atk_8266_reset-gpios为例
#define ZEPHYR_USER_NODE DT_PATH(zephyr_user)

// 获取reset GPIO
static const struct gpio_dt_spec atk_mw8266d_reset = GPIO_DT_SPEC_GET(ZEPHYR_USER_NODE, atk_8266_reset_gpios);

/* IO操作 */
// 注意,这里需要根据配置的激活方式进行配置,因为我选择了(GPIO_ACTIVE_LOW | GPIO_PULL_UP)
// ATK_MW8266D_RST(1) -> gpio_pin_set_dt(&atk_mw8266d_reset, 0) -> 输出高电平
// ATK_MW8266D_RST(0) -> gpio_pin_set_dt(&atk_mw8266d_reset, 1) -> 输出低电平
#define ATK_MW8266D_RST(x)                  do{ x ?                                         \

                                                gpio_pin_set_dt(&atk_mw8266d_reset, 0) :    \

                                                gpio_pin_set_dt(&atk_mw8266d_reset, 1);     \

                                            }while(0)

// 配置为输出
gpio_pin_configure_dt(&atk_mw8266d_reset, GPIO_OUTPUT_ACTIVE);