如何使用DT_FOREACH_CHILD在Zephyr中访问设备树(DTS)中的子节点
我正在为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)
扩展到13
,dt_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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
可以在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