diff --git a/dts/bindings/test/vnd,child-bindings.yaml b/dts/bindings/test/vnd,child-bindings.yaml new file mode 100644 index 00000000000..3b5e725f1a5 --- /dev/null +++ b/dts/bindings/test/vnd,child-bindings.yaml @@ -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 diff --git a/include/devicetree.h b/include/devicetree.h index 36849379583..ef0700d93cc 100644 --- a/include/devicetree.h +++ b/include/devicetree.h @@ -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 diff --git a/tests/lib/devicetree/app.overlay b/tests/lib/devicetree/app.overlay index 6eae85f5c54..5ad052821bb 100644 --- a/tests/lib/devicetree/app.overlay +++ b/tests/lib/devicetree/app.overlay @@ -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>; }; }; }; diff --git a/tests/lib/devicetree/src/main.c b/tests/lib/devicetree/src/main.c index 9ef13a925cb..f38922c53f3 100644 --- a/tests/lib/devicetree/src/main.c +++ b/tests/lib/devicetree/src/main.c @@ -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 }