如何使用DT_FOREACH_CHILD在Zephyr中访问设备树(DTS)中的子节点

发布于 2025-01-26 22:48:17 字数 1841 浏览 4 评论 0原文

我正在为NRF52 SOC开发一个应用程序以访问某些外部设备,在这种情况下是一种检测器,因此我为我的设备访问说明定义了自定义格式(及其相应的yaml文件) 。这是一种:

n: detectors {
    compatible = "foo-detectors";
        
    // Definition of first channel
    det0: det_0 {
        irq-pins = <13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
        label = "Bar detector channel 1";
    };
    // Definition of second channel
    det1: det_1 {
        irq-pins = <17 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
        label = "Bar detector channel 2";
    };
};

假设我有一个结构定义,用于持有这些设备是物理连接的引脚的数据,例如:

struct foo_detector_desc { 
    int irqpin; 
    int irqpin_flags;
}

使用Zephyr宏,我可以从代码中使用这些节点的单个值。例如,dt_prop_by_idx(dt_nodelabel(det0),irq_pins,0) 扩展到13dt_prop_by_idx(dt_nodelabel(det0),irq_pins,1),1) 扩展到OR'ED标志的值gpio_pull_up | gpio_active_low

但是我不想创建一个十页的代码,其中包含形式的条件dt_node_exists(dt_alias(det#)),但更紧凑,灵活和可维护的东西。

我遇到了Zephyr Macro DT_FOREACH_CHILD,该旨在在这种情况下使用,我可以使用标签创建列表,如文档中嵌入的示例中所示:

#define LABEL_AND_COMMA(node_id) DT_LABEL(node_id),
const char *child_labels[] = {
    DT_FOREACH_CHILD(DT_NODELABEL(n), LABEL_AND_COMMA)
};

试图使用该列表:静态结构数组,我尝试了遵循代码,但是,但是它扩展到数组中的两个元素,结构字段并未以所需的值初始化。

#define PIN_INFO_AND_COMMA(node_id) \
    { \
        .pin=DT_PROP_BY_IDX(node_id, irq_pins, 0),\
        .flags=DT_PROP_BY_IDX(node_id, irq_pins, 1),\
    },

const struct detector_data _det_data[] = {
    DT_FOREACH_CHILD(DT_NODELABEL(n), PIN_INFO_AND_COMMA)
};

我正在使用NRF Connect插件使用Visual Studio代码。

有没有一种方法可以生成/查看这些宏是如何扩展的?

初始化结构字段(引脚,标志)的正确方法是什么?

br

I'm developing an application for an nRF52 SoC to access some external devices, kind of detectors in this case, so I have defined a custom format (and its corresponding yaml file) for my device access description node. It is kind of:

n: detectors {
    compatible = "foo-detectors";
        
    // Definition of first channel
    det0: det_0 {
        irq-pins = <13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
        label = "Bar detector channel 1";
    };
    // Definition of second channel
    det1: det_1 {
        irq-pins = <17 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
        label = "Bar detector channel 2";
    };
};

Suppose I have a structure definition for holding data about the pins to which those devices are physically connected, say:

struct foo_detector_desc { 
    int irqpin; 
    int irqpin_flags;
}

Using Zephyr macros, I can use from my code the individual values for those nodes. For instance, DT_PROP_BY_IDX(DT_NODELABEL(det0), irq_pins, 0) expands to 13, DT_PROP_BY_IDX(DT_NODELABEL(det0), irq_pins, 1) expands to the value of OR'ed flags GPIO_PULL_UP | GPIO_ACTIVE_LOW.

But I don't want to create a ten-page code full of conditionals in the form DT_NODE_EXISTS(DT_ALIAS(det#)), but something more compact, flexible and maintainable.

I came across Zephyr macro DT_FOREACH_CHILD that is intended for being used in that scenario with which I can create a list with the labels, as showcased in the example embedded in the documentation:

#define LABEL_AND_COMMA(node_id) DT_LABEL(node_id),
const char *child_labels[] = {
    DT_FOREACH_CHILD(DT_NODELABEL(n), LABEL_AND_COMMA)
};

Trying to use that for filling a static structures array, I tried following code but, yet it expands to two elements in the array, the structure fields are not initialised with desired values.

#define PIN_INFO_AND_COMMA(node_id) \
    { \
        .pin=DT_PROP_BY_IDX(node_id, irq_pins, 0),\
        .flags=DT_PROP_BY_IDX(node_id, irq_pins, 1),\
    },

const struct detector_data _det_data[] = {
    DT_FOREACH_CHILD(DT_NODELABEL(n), PIN_INFO_AND_COMMA)
};

I'm using Visual Studio Code with the nRF Connect plugin.

Is there a way to generate/see how those macros expand when compiled?

What is the correct way for initialising the structure fields (pins, flags)?

BR

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

往日 2025-02-02 22:48:17

可以在VS代码中一次扩展宏一级。它需要单击宏,然后双击它,然后通过双击它来选择它,最终将出现灯泡灯。选项插入宏将用其扩展代替宏。

关于在代码中使用 dts ,我在上一篇文章中编写的代码还可以,但是我认为我在调试器中找到了一个错误。如果我不使用_DET_DATA的值包含任何代码,则调试器不会说常数是拟议的,并且在检查其内容时会显示错误的值。那使我浪费了很多时间。

对于对Zephyr中NRF设备使用 dts 文件感兴趣的任何人,我在Nordic的开发人员论坛的线程中发布了所有详细信息(在这里)。

br

It is possible to expand the macros one level at a time in VS Code. It is needed to click over the macro, then select it by double-clicking on it, and a bulb light will, eventually, show up. The option Insert Macro will replace the macro with its expansion.

Regarding using the DTS in code, the code I wrote in my previous post is OK, but I think I found a bug in the debugger. If I don't include any code using the value of _det_data, the debugger doesn't say the constant was optimised-out and displays wrong values when inspecting its content. That made me waste a lot of time.

For anyone interested on using DTS files for nRF devices in Zephyr, I posted all details in a thread in Nordic's developers forum (here).

BR

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文