devicetree: add DT_SAME_NODE()

It can be useful to check if an unknown devicetree node identifier
refers to a known node. Add a helper for this. Under the hood, we take
advantage of the ordinals API, which provides the unique identifiers
we need.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
Martí Bolívar 2020-12-11 13:51:36 -08:00 committed by Anas Nashif
commit 8fef65392d
3 changed files with 34 additions and 4 deletions

View file

@ -20,8 +20,8 @@ Generic APIs
The APIs in this section can be used anywhere and do not require The APIs in this section can be used anywhere and do not require
``DT_DRV_COMPAT`` to be defined. ``DT_DRV_COMPAT`` to be defined.
Node identifiers Node identifiers and helpers
================ ============================
A *node identifier* is a way to refer to a devicetree node at C preprocessor A *node identifier* is a way to refer to a devicetree node at C preprocessor
time. While node identifiers are not C values, you can use them to access time. While node identifiers are not C values, you can use them to access
@ -36,6 +36,8 @@ There are also :c:func:`DT_PARENT` and :c:func:`DT_CHILD` macros which can be
used to create node identifiers for a given node's parent node or a particular used to create node identifiers for a given node's parent node or a particular
child node, respectively. child node, respectively.
The following macros create or operate on node identifiers.
.. doxygengroup:: devicetree-generic-id .. doxygengroup:: devicetree-generic-id
:project: Zephyr :project: Zephyr

View file

@ -65,7 +65,7 @@
*/ */
/** /**
* @defgroup devicetree-generic-id Node identifiers * @defgroup devicetree-generic-id Node identifiers and helpers
* @ingroup devicetree * @ingroup devicetree
* @{ * @{
*/ */
@ -399,6 +399,27 @@
*/ */
#define DT_NODE_PATH(node_id) DT_CAT(node_id, _PATH) #define DT_NODE_PATH(node_id) DT_CAT(node_id, _PATH)
/**
* @brief Do node_id1 and node_id2 refer to the same node?
*
* Both "node_id1" and "node_id2" must be node identifiers for nodes
* that exist in the devicetree (if unsure, you can check with
* DT_NODE_EXISTS()).
*
* The expansion evaluates to 0 or 1, but may not be a literal integer
* 0 or 1.
*
* @param node_id1 first node identifer
* @param node_id2 second node identifier
* @return an expression that evaluates to 1 if the node identifiers
* refer to the same node, and evaluates to 0 otherwise
*/
#define DT_SAME_NODE(node_id1, node_id2) \
(DT_DEP_ORD(node_id1) == (DT_DEP_ORD(node_id2)))
/* Implementation note: distinct nodes have distinct node identifiers.
* See include/devicetree/ordinals.h. */
/** /**
* @} * @}
*/ */

View file

@ -1545,6 +1545,12 @@ static void test_path(void)
"/test/gpio@deadbeef"), ""); "/test/gpio@deadbeef"), "");
} }
static void test_same_node(void)
{
zassert_true(DT_SAME_NODE(TEST_DEADBEEF, TEST_DEADBEEF), "");
zassert_false(DT_SAME_NODE(TEST_DEADBEEF, TEST_ABCD1234), "");
}
void test_main(void) void test_main(void)
{ {
ztest_test_suite(devicetree_api, ztest_test_suite(devicetree_api,
@ -1579,7 +1585,8 @@ void test_main(void)
ztest_unit_test(test_child_nodes_list), ztest_unit_test(test_child_nodes_list),
ztest_unit_test(test_great_grandchild), ztest_unit_test(test_great_grandchild),
ztest_unit_test(test_dep_ord), ztest_unit_test(test_dep_ord),
ztest_unit_test(test_path) ztest_unit_test(test_path),
ztest_unit_test(test_same_node)
); );
ztest_run_test_suite(devicetree_api); ztest_run_test_suite(devicetree_api);
} }