devicetree: Add DT_FOREACH_CHILD_STATUS_OKAY macro

The macro only iterates the enabled child nodes and invokes
provided macro for each node.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
This commit is contained in:
Hou Zhiqiang 2021-04-26 16:22:38 +08:00 committed by Anas Nashif
commit 0700a24276
5 changed files with 41 additions and 0 deletions

View file

@ -51,6 +51,9 @@ node-macro =/ %s"DT_N" path-id %s"_PARENT"
; These are used internally by DT_FOREACH_CHILD, which iterates over
; each child node.
node-macro =/ %s"DT_N" path-id %s"_FOREACH_CHILD"
; These are used internally by DT_FOREACH_CHILD_STATUS_OKAY, which iterates
; over each child node with status "okay".
node-macro =/ %s"DT_N" path-id %s"_FOREACH_CHILD_STATUS_OKAY"
; The node's status macro; dt-name in this case is something like "okay"
; or "disabled".
node-macro =/ %s"DT_N" path-id %s"_STATUS_" dt-name

View file

@ -1485,6 +1485,21 @@
#define DT_FOREACH_CHILD(node_id, fn) \
DT_CAT(node_id, _FOREACH_CHILD)(fn)
/**
* @brief Call "fn" on the child nodes with status "okay"
*
* The macro "fn" should take one argument, which is the node
* identifier for the child node.
*
* As usual, both a missing status and an "ok" status are
* treated as "okay".
*
* @param node_id node identifier
* @param fn macro to invoke
*/
#define DT_FOREACH_CHILD_STATUS_OKAY(node_id, fn) \
DT_CAT(node_id, _FOREACH_CHILD_STATUS_OKAY)(fn)
/**
* @brief Invokes "fn" for each element in the value of property "prop".
*

View file

@ -119,6 +119,7 @@ def main():
f"DT_{node.parent.z_path_id}")
write_child_functions(node)
write_child_functions_status_okay(node)
write_dep_info(node)
write_idents_and_existence(node)
write_bus(node)
@ -479,6 +480,18 @@ def write_child_functions(node):
node.children.values()))
def write_child_functions_status_okay(node):
# Writes macro that are helpers that will call a macro/function
# for each child node with status "okay".
functions = ''
for child in node.children.values():
if child.status == "okay":
functions = functions + f"fn(DT_{child.z_path_id}) "
out_dt_define(f"{node.z_path_id}_FOREACH_CHILD_STATUS_OKAY(fn)", functions)
def write_status(node):
out_dt_define(f"{node.z_path_id}_STATUS_{str2ident(node.status)}", 1)

View file

@ -386,12 +386,15 @@
test_child_a: child-a {
val = <0>;
status = "okay";
};
test_child_b: child-b {
val = <1>;
status = "okay";
};
test_child_c: child-c {
val = <2>;
status = "disabled";
};
};

View file

@ -1568,8 +1568,13 @@ static void test_child_nodes_list(void)
DT_INST_FOREACH_CHILD(0, TEST_FUNC)
};
struct vnd_child_binding vals_status_okay[] = {
DT_FOREACH_CHILD_STATUS_OKAY(TEST_PARENT, TEST_FUNC)
};
zassert_equal(ARRAY_SIZE(vals), 3, "");
zassert_equal(ARRAY_SIZE(vals_inst), 3, "");
zassert_equal(ARRAY_SIZE(vals_status_okay), 2, "");
zassert_false(strlen(STRINGIFY(TEST_PARENT)) == 0, "");
@ -1579,6 +1584,8 @@ static void test_child_nodes_list(void)
zassert_equal(vals_inst[0].val, 0, "");
zassert_equal(vals_inst[1].val, 1, "");
zassert_equal(vals_inst[2].val, 2, "");
zassert_equal(vals_status_okay[0].val, 0, "");
zassert_equal(vals_status_okay[1].val, 1, "");
#undef TEST_PARENT
#undef TEST_FUNC