Skip to content

Commit 6f69749

Browse files
committed
include: devicetree: Generate defines for map property
This change introduces generating definitions corresponding to `*-map` property, which was currently discarded. The `*-map` data is like a two-dimensional array, so it is difficult to handle with the existing APIs, so we will also provide new APIs. Signed-off-by: TOKITA Hiroshi <[email protected]>
1 parent 5e7f72c commit 6f69749

File tree

7 files changed

+588
-0
lines changed

7 files changed

+588
-0
lines changed

dts/bindings/test/vnd,gpio-nexus.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2025, TOKITA Hiroshi
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: VND GPIO nexus
5+
6+
include: [gpio-nexus.yaml]
7+
8+
compatible: "vnd,gpio-nexus"

dts/bindings/test/vnd,intr-nexus.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2025, TOKITA Hiroshi
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: VND interrupt nexus
5+
6+
include: [interrupt-nexus.yaml]
7+
8+
compatible: "vnd,intr-nexus"

include/zephyr/devicetree.h

+1
Original file line numberDiff line numberDiff line change
@@ -5343,5 +5343,6 @@
53435343
#include <zephyr/devicetree/reset.h>
53445344
#include <zephyr/devicetree/mbox.h>
53455345
#include <zephyr/devicetree/port-endpoint.h>
5346+
#include <zephyr/devicetree/map.h>
53465347

53475348
#endif /* ZEPHYR_INCLUDE_DEVICETREE_H_ */

include/zephyr/devicetree/map.h

+344
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
/*
2+
* Copyright 2025 TOKITA Hiroshi
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDE_DEVICETREE_MAP_H_
8+
#define ZEPHYR_INCLUDE_DEVICETREE_MAP_H_
9+
10+
#ifdef __cplusplus
11+
extern "C" {
12+
#endif
13+
14+
/**
15+
* Helper macro for extract args and execute GET_ARGS_LESS_N and GET_ARGS_FIRST_N.
16+
*/
17+
#define DT_MAP_HELPER_DO_ARGS_RANGE(start, len, ...) \
18+
GET_ARGS_FIRST_N(len, GET_ARGS_LESS_N(start, __VA_ARGS__))
19+
20+
/**
21+
* Helper macro for extract _IDX and _LEN macro.
22+
*/
23+
#define DT_MAP_HELPER_ARGS_RANGE(name, node_id, prop, idx, ...) \
24+
DT_MAP_HELPER_DO_ARGS_RANGE(DT_CAT3(DT_MAP_, name, _IDX)(node_id, prop, idx), \
25+
DT_CAT3(DT_MAP_, name, _LEN)(node_id, prop, idx), __VA_ARGS__)
26+
27+
/**
28+
* Helper macro for extract args and execute GET_ARGS_LESS_N.
29+
*/
30+
#define DT_MAP_HELPER_ARGS_LESS_N(N, ...) GET_ARGS_LESS_N(N, __VA_ARGS__)
31+
32+
/**
33+
* @brief Invokes @p fn for each map entry.
34+
*
35+
* The macro @p fn must take three parameters(node_id, prop, idx)
36+
* and variable arguments.
37+
*
38+
* @p node_id and @p prop are the same as what is passed to
39+
* DT_MAP_FOREACH(), and @p idx is the current index into the array.
40+
* The @p idx values are integer literals starting from 0.
41+
*
42+
* The @p prop argument must refer to a property that can be passed to
43+
* DT_MAP_LEN().
44+
*
45+
* Example devicetree fragment:
46+
*
47+
* @code{.dts}
48+
* n: node {
49+
* gpio-map = <0 1 &gpio0 2 3>, <4 5 &gpio0 6 7>;
50+
* };
51+
* @endcode
52+
*
53+
* Example usage:
54+
*
55+
* @code{.c}
56+
* #define SRC_AND_DST(node_id, prop, idx, ...) \
57+
* { GET_ARG_N(1, DT_MAP_ARGS_CHILD_CELL(node_id, prop, idx, __VA_ARGS__), \
58+
* GET_ARG_N(1, DT_MAP_ARGS_PARENT_CELL(node_id, prop, idx, __VA_ARGS__) }
59+
*
60+
* int src_and_dst[2][] = {
61+
* DT_MAP_FOREACH_SEP(DT_NODELABEL(n), gpio_map, SRC_AND_DST, (,))
62+
* };
63+
* @endcode
64+
*
65+
* This expands to:
66+
*
67+
* @code{.c}
68+
* int src_and_dst[2][] = {{0, 2}, {4, 6}};
69+
* @endcode
70+
*
71+
* In general, this macro expands to:
72+
*
73+
* fn(node_id, prop, 0, <map[0] cells...>)
74+
* fn(node_id, prop, 1, <map[1] cells...>)
75+
* [...]
76+
* fn(node_id, prop, n-1, <map[n-1] cells ...>)
77+
*
78+
* where `n` is the number of map entries, as it would be
79+
* returned by `DT_MAP_LEN(node_id, prop)`.
80+
*
81+
* @param node_id node identifier
82+
* @param prop lowercase-and-underscores property name
83+
* @param fn macro to invoke
84+
* @see DT_MAP_FOREACH_SEP
85+
* @see DT_MAP_FOREACH_VARGS
86+
* @see DT_MAP_FOREACH_SEP_VARGS
87+
* @see DT_PROP_ELEM_FOREACH
88+
*/
89+
#define DT_MAP_FOREACH(node_id, prop, fn) DT_CAT4(node_id, _P_, prop, _MAP_FOREACH)(fn)
90+
91+
/**
92+
* @brief Invokes @p fn for each map entry with multiple separator.
93+
*
94+
* The @p prop parameter has the same restrictions as the same parameter
95+
* given to DT_MAP_FOREACH().
96+
*
97+
* @param node_id node identifier
98+
* @param prop lowercase-and-underscores property name
99+
* @param fn macro to invoke
100+
* @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
101+
* this is required to enable providing a comma as separator.
102+
*
103+
* @see DT_MAP_FOREACH
104+
* @see DT_PROP_ELEM_FOREACH_SEP
105+
*/
106+
#define DT_MAP_FOREACH_SEP(node_id, prop, fn, sep) \
107+
DT_CAT4(node_id, _P_, prop, _MAP_FOREACH_SEP)(fn, sep)
108+
109+
/**
110+
* @brief Invokes @p fn for each map entry with multiple arguments.
111+
*
112+
* The @p prop parameter has the same restrictions as the same parameter
113+
* given to DT_MAP_FOREACH().
114+
*
115+
* @param node_id node identifier
116+
* @param prop lowercase-and-underscores property name
117+
* @param fn macro to invoke
118+
* @param ... variable number of arguments to pass to @p fn
119+
*
120+
* @see DT_MAP_FOREACH
121+
* @see DT_PROP_ELEM_FOREACH_VARGS
122+
*/
123+
#define DT_MAP_FOREACH_VARGS(node_id, prop, fn, ...) \
124+
DT_CAT4(node_id, _P_, prop, _MAP_FOREACH_VARGS)(fn, __VA_ARGS__)
125+
126+
/**
127+
* @brief Invokes @p fn for each map entry with multiple arguments and separator.
128+
*
129+
* The @p prop parameter has the same restrictions as the same parameter
130+
* given to DT_MAP_FOREACH().
131+
*
132+
* @param node_id node identifier
133+
* @param prop lowercase-and-underscores property name
134+
* @param fn macro to invoke
135+
* @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
136+
* this is required to enable providing a comma as separator.
137+
* @param ... variable number of arguments to pass to fn
138+
*
139+
* @see DT_MAP_FOREACH
140+
* @see DT_PROP_ELEM_FOREACH_SEP_VARGS
141+
*/
142+
#define DT_MAP_FOREACH_SEP_VARGS(node_id, prop, fn, sep, ...) \
143+
DT_CAT4(node_id, _P_, prop, _MAP_FOREACH_SEP_VARGS)(fn, sep, __VA_ARGS__)
144+
145+
/**
146+
* @brief Get a map entry by idx.
147+
* @param node_id node identifier
148+
* @param prop lowercase-and-underscores property name
149+
* @param idx the index to get
150+
* @return The map entry that corresponds to the @p idx.
151+
* The map entry is comma-separated values.
152+
*/
153+
#define DT_MAP_IDX(node_id, prop, idx) DT_CAT5(node_id, _P_, prop, _MAP_IDX_, idx)
154+
155+
/**
156+
* @brief Get a number of map entry.
157+
* @param node_id node identifier
158+
* @param prop lowercase-and-underscores property name
159+
* @return The number of maps that the @p prop has.
160+
*/
161+
#define DT_MAP_LEN(node_id, prop) DT_CAT4(node_id, _P_, prop, _MAP_LEN)
162+
163+
/**
164+
* @brief Get the start index of the child address cell.
165+
* @param node_id node identifier
166+
* @param prop lowercase-and-underscores property name
167+
* @param idx the index to get
168+
* @return The start index of the child address cell in map entry.
169+
*/
170+
#define DT_MAP_CHILD_ADDR_IDX(node_id, prop, idx) \
171+
DT_CAT7(node_id, _P_, prop, _MAP_IDX_, idx, _, CHILD_ADDR_IDX)
172+
173+
/**
174+
* @brief Get the length of the child address cell.
175+
* @param node_id node identifier
176+
* @param prop lowercase-and-underscores property name
177+
* @param idx the index to get
178+
* @return The length of the child address cell in map entry.
179+
*/
180+
#define DT_MAP_CHILD_ADDR_LEN(node_id, prop, idx) \
181+
DT_CAT7(node_id, _P_, prop, _MAP_IDX_, idx, _, CHILD_ADDR_LEN)
182+
183+
/**
184+
* @brief Get the start index of the child address cell.
185+
* @param node_id node identifier
186+
* @param prop lowercase-and-underscores property name
187+
* @param idx the index to get
188+
* @return The start index of the child address cell in map entry.
189+
*/
190+
#define DT_MAP_CHILD_CELL_IDX(node_id, prop, idx) \
191+
DT_CAT7(node_id, _P_, prop, _MAP_IDX_, idx, _, CHILD_CELL_IDX)
192+
193+
/**
194+
* @brief Get the length of the child address cell.
195+
* @param node_id node identifier
196+
* @param prop lowercase-and-underscores property name
197+
* @param idx the index to get
198+
* @return The length of the child address cell in map entry.
199+
*/
200+
#define DT_MAP_CHILD_CELL_LEN(node_id, prop, idx) \
201+
DT_CAT7(node_id, _P_, prop, _MAP_IDX_, idx, _, CHILD_CELL_LEN)
202+
203+
/**
204+
* @brief Get the start index of the child address cell.
205+
* @param node_id node identifier
206+
* @param prop lowercase-and-underscores property name
207+
* @param idx the index to get
208+
* @return The start index of the child address cell in map entry.
209+
*/
210+
#define DT_MAP_PARENT_IDX(node_id, prop, idx) \
211+
DT_CAT7(node_id, _P_, prop, _MAP_IDX_, idx, _, PARENT_IDX)
212+
213+
/**
214+
* @brief Get the length of the child address cell.
215+
* @param node_id node identifier
216+
* @param prop lowercase-and-underscores property name
217+
* @param idx the index to get
218+
* @return The length of the child address cell in map entry.
219+
*/
220+
#define DT_MAP_PARENT_LEN(node_id, prop, idx) \
221+
DT_CAT7(node_id, _P_, prop, _MAP_IDX_, idx, _, PARENT_LEN)
222+
223+
/**
224+
* @brief Get the start index of the child address cell.
225+
* @param node_id node identifier
226+
* @param prop lowercase-and-underscores property name
227+
* @param idx the index to get
228+
* @return The start index of the child address cell in map entry.
229+
*/
230+
#define DT_MAP_PARENT_ADDR_IDX(node_id, prop, idx) \
231+
DT_CAT7(node_id, _P_, prop, _MAP_IDX_, idx, _, PARENT_ADDR_IDX)
232+
233+
/**
234+
* @brief Get the length of the child address cell.
235+
* @param node_id node identifier
236+
* @param prop lowercase-and-underscores property name
237+
* @param idx the index to get
238+
* @return The length of the child address cell in map entry.
239+
*/
240+
#define DT_MAP_PARENT_ADDR_LEN(node_id, prop, idx) \
241+
DT_CAT7(node_id, _P_, prop, _MAP_IDX_, idx, _, PARENT_ADDR_LEN)
242+
243+
/**
244+
* @brief Get the start index of the child address cell.
245+
* @param node_id node identifier
246+
* @param prop lowercase-and-underscores property name
247+
* @param idx the index to get
248+
* @return The start index of the child address cell in map entry.
249+
*/
250+
#define DT_MAP_PARENT_CELL_IDX(node_id, prop, idx) \
251+
DT_CAT7(node_id, _P_, prop, _MAP_IDX_, idx, _, PARENT_CELL_IDX)
252+
253+
/**
254+
* @brief Get the length of the child address cell.
255+
* @param node_id node identifier
256+
* @param prop lowercase-and-underscores property name
257+
* @param idx the index to get
258+
* @return The length of the child address cell in map entry.
259+
*/
260+
#define DT_MAP_PARENT_CELL_LEN(node_id, prop, idx) \
261+
DT_CAT7(node_id, _P_, prop, _MAP_IDX_, idx, _, PARENT_CELL_LEN)
262+
263+
/**
264+
* @brief Get the start index of the child address cell.
265+
* @param node_id node identifier
266+
* @param prop lowercase-and-underscores property name
267+
* @param idx the index to get
268+
* @return The start index of the child address cell in map entry.
269+
*/
270+
#define DT_MAP_VA_ARGS_IDX(node_id, prop, idx) \
271+
DT_MAP_HELPER_IDX_CAT(PARENT_CELL_IDX, node_id, prop, idx)
272+
273+
/**
274+
* @brief Get the child address args of map entry.
275+
* @param node_id node identifier
276+
* @param prop lowercase-and-underscores property name
277+
* @param idx the index to get
278+
* @param ... The map entry args
279+
* @return The child address args
280+
*/
281+
#define DT_MAP_ARGS_CHILD_ADDR(node_id, prop, idx, ...) \
282+
DT_MAP_HELPER_ARGS_RANGE(CHILD_ADDR, node_id, prop, idx, __VA_ARGS__)
283+
284+
/**
285+
* @brief Get the child cell args of map entry.
286+
* @param node_id node identifier
287+
* @param prop lowercase-and-underscores property name
288+
* @param idx the index to get
289+
* @param ... The map entry args
290+
* @return The child cell args
291+
*/
292+
#define DT_MAP_ARGS_CHILD_CELL(node_id, prop, idx, ...) \
293+
DT_MAP_HELPER_ARGS_RANGE(CHILD_CELL, node_id, prop, idx, __VA_ARGS__)
294+
295+
/**
296+
* @brief Get the parent args of map entry.
297+
* @param node_id node identifier
298+
* @param prop lowercase-and-underscores property name
299+
* @param idx the index to get
300+
* @param ... The map entry args
301+
* @return The parent args
302+
*/
303+
#define DT_MAP_ARGS_PARENT(node_id, prop, idx, ...) \
304+
DT_MAP_HELPER_ARGS_RANGE(PARENT, node_id, prop, idx, __VA_ARGS__)
305+
306+
/**
307+
* @brief Get the parent address args of map entry.
308+
* @param node_id node identifier
309+
* @param prop lowercase-and-underscores property name
310+
* @param idx the index to get
311+
* @param ... The map entry args
312+
* @return The parent address args
313+
*/
314+
#define DT_MAP_ARGS_PARENT_ADDR(node_id, prop, idx, ...) \
315+
DT_MAP_HELPER_ARGS_RANGE(PARENT_ADDR, node_id, prop, idx, __VA_ARGS__)
316+
317+
/**
318+
* @brief Get the parent cell args of map entry.
319+
* @param node_id node identifier
320+
* @param prop lowercase-and-underscores property name
321+
* @param idx the index to get
322+
* @param ... The map entry args
323+
* @return The parent cell args
324+
*/
325+
#define DT_MAP_ARGS_PARENT_CELL(node_id, prop, idx, ...) \
326+
DT_MAP_HELPER_ARGS_RANGE(PARENT_CELL, node_id, prop, idx, __VA_ARGS__)
327+
328+
/**
329+
* @brief Get the variable arguments part.
330+
* @param node_id node identifier
331+
* @param prop lowercase-and-underscores property name
332+
* @param idx the index to get
333+
* @param ... The map entry args
334+
* @return The variable arguments part
335+
*/
336+
#define DT_MAP_ARGS_VARGS(node_id, prop, idx, ...) \
337+
DT_MAP_HELPER_ARGS_LESS_N(DT_MAP_VARGS_IDX(node_id, prop, idx), node_id, prop, idx, \
338+
__VA_ARGS__)
339+
340+
#ifdef __cplusplus
341+
}
342+
#endif
343+
344+
#endif

0 commit comments

Comments
 (0)