devicetree: add DT_INST_FOREACH_CHILD macro

The macro iterates through the list of child nodes in a DT_DRV_COMPAT
instance and invokes provided macro for each node.

Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
This commit is contained in:
Gerard Marull-Paretas 2020-05-11 12:56:55 +02:00 committed by Carles Cufí
commit b35152ed4b
4 changed files with 56 additions and 21 deletions

View file

@ -0,0 +1,15 @@
# Copyright (c) 2020, Teslabs Engineering S.L.
# SPDX-License-Identifier: Apache-2.0
description: Test child bindings
compatible: "vnd,child-bindings"
include: [base.yaml]
child-binding:
description: Test child binding
properties:
val:
type: int
required: true

View file

@ -1163,6 +1163,17 @@
*/
#define DT_DRV_INST(inst) DT_INST(inst, DT_DRV_COMPAT)
/**
* @brief Invokes given macro for all child nodes of DT_DRV_COMPAT instance.
*
* @param inst instance number
* @param fn macro to invoke
*
* @see DT_FOREACH_CHILD
*/
#define DT_INST_FOREACH_CHILD(inst, fn) \
DT_FOREACH_CHILD(DT_DRV_INST(inst), fn)
/**
* @brief Get a DT_DRV_COMPAT instance property
* @param inst instance number

View file

@ -320,17 +320,16 @@
};
test_children: test-children {
test_child_alpha: child-alpha {
compatible = "vnd,enum-holder";
val = "zero";
compatible = "vnd,child-bindings";
test_child_a: child-a {
val = <0>;
};
test_child_beta: child-beta {
compatible = "vnd,enum-holder";
val = "one";
test_child_b: child-b {
val = <1>;
};
test_child_charlie: child-charlie {
compatible = "vnd,enum-holder";
val = "two";
test_child_c: child-c {
val = <2>;
};
};
};

View file

@ -1404,30 +1404,40 @@ static void test_parent(void)
"round trip through node with no compatible");
}
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT vnd_child_bindings
static void test_child_nodes_list(void)
{
#define TEST_FUNC(child) { DT_PROP(child, val) },
#define TEST_MKSTR(a) _TEST_MKSTR(a)
#define _TEST_MKSTR(a) #a
#define TEST_PARENT DT_PATH(test, test_children)
static struct {
const char *v;
} vals[] = {
#define TEST_PARENT DT_PARENT(DT_NODELABEL(test_child_a))
struct vnd_child_binding {
int val;
};
struct vnd_child_binding vals[] = {
DT_FOREACH_CHILD(TEST_PARENT, TEST_FUNC)
};
struct vnd_child_binding vals_inst[] = {
DT_INST_FOREACH_CHILD(0, TEST_FUNC)
};
zassert_equal(ARRAY_SIZE(vals), 3,
"Bad number of children");
zassert_equal(ARRAY_SIZE(vals_inst), 3,
"Bad number of children");
zassert_false(strlen(TEST_MKSTR(TEST_PARENT)) == 0,
zassert_false(strlen(STRINGIFY(TEST_PARENT)) == 0,
"TEST_PARENT evaluated to empty string");
zassert_equal(vals[0].v, "zero", "Child 0 did not match");
zassert_equal(vals[1].v, "one", "Child 1 did not match");
zassert_equal(vals[2].v, "two", "Child 2 did not match");
zassert_equal(vals[0].val, 0, "Child 0 did not match");
zassert_equal(vals[1].val, 1, "Child 1 did not match");
zassert_equal(vals[2].val, 2, "Child 2 did not match");
zassert_equal(vals_inst[0].val, 0, "Child 0 did not match");
zassert_equal(vals_inst[1].val, 1, "Child 1 did not match");
zassert_equal(vals_inst[2].val, 2, "Child 2 did not match");
#undef TEST_MKSTR
#undef _TEST_MKSTR
#undef TEST_PARENT
#undef TEST_FUNC
}