1.. _dt-from-c: 2 3Devicetree access from C/C++ 4############################ 5 6This guide describes Zephyr's ``<zephyr/devicetree.h>`` API for reading the 7devicetree from C source files. It assumes you're familiar with the concepts in 8:ref:`devicetree-intro` and :ref:`dt-bindings`. See :ref:`dt-reference` for 9reference material. 10 11A note for Linux developers 12*************************** 13 14Linux developers familiar with devicetree should be warned that the API 15described here differs significantly from how devicetree is used on Linux. 16 17Instead of generating a C header with all the devicetree data which is then 18abstracted behind a macro API, the Linux kernel would instead read the 19devicetree data structure in its binary form. The binary representation is 20parsed at runtime, for example to load and initialize device drivers. 21 22Zephyr does not work this way because the size of the devicetree binary and 23associated handling code would be too large to fit comfortably on the 24relatively constrained devices Zephyr supports. 25 26.. _dt-node-identifiers: 27 28Node identifiers 29**************** 30 31To get information about a particular devicetree node, you need a *node 32identifier* for it. This is a just a C macro that refers to the node. 33 34These are the main ways to get a node identifier: 35 36By path 37 Use :c:macro:`DT_PATH()` along with the node's full path in the devicetree, 38 starting from the root node. This is mostly useful if you happen to know the 39 exact node you're looking for. 40 41By node label 42 Use :c:macro:`DT_NODELABEL()` to get a node identifier from a :ref:`node 43 label <dt-node-labels>`. Node labels are often provided by SoC :file:`.dtsi` 44 files to give nodes names that match the SoC datasheet, like ``i2c1``, 45 ``spi2``, etc. 46 47By alias 48 Use :c:macro:`DT_ALIAS()` to get a node identifier for a property of the 49 special ``/aliases`` node. This is sometimes done by applications (like 50 :zephyr:code-sample:`blinky`, which uses the ``led0`` alias) that need to 51 refer to *some* device of a particular type ("the board's user LED") but 52 don't care which one is used. 53 You may also use :c:macro:`DT_HAS_ALIAS()` to verify whether an alias 54 node exists. 55 56By instance number 57 This is done primarily by device drivers, as instance numbers are a way to 58 refer to individual nodes based on a matching compatible. Get these with 59 :c:macro:`DT_INST()`, but be careful doing so. See below. 60 61By chosen node 62 Use :c:macro:`DT_CHOSEN()` to get a node identifier for ``/chosen`` node 63 properties. 64 65By parent/child 66 Use :c:macro:`DT_PARENT()` and :c:macro:`DT_CHILD()` to get a node identifier 67 for a parent or child node, starting from a node identifier you already have. 68 69Two node identifiers which refer to the same node are identical and can be used 70interchangeably. 71 72.. _dt-node-main-ex: 73 74Here's a DTS fragment for some imaginary hardware we'll return to throughout 75this file for examples: 76 77.. literalinclude:: main-example.dts 78 :language: devicetree 79 :start-after: start-after-here 80 81Here are a few ways to get node identifiers for the ``i2c@40002000`` node: 82 83- ``DT_PATH(soc, i2c_40002000)`` 84- ``DT_NODELABEL(i2c1)`` 85- ``DT_ALIAS(sensor_controller)`` 86- ``DT_INST(x, vnd_soc_i2c)`` for some unknown number ``x``. See the 87 :c:macro:`DT_INST()` documentation for details. 88 89.. important:: 90 91 Non-alphanumeric characters like dash (``-``) and the at sign (``@``) in 92 devicetree names are converted to underscores (``_``). The names in a DTS 93 are also converted to lowercase. 94 95.. _node-ids-are-not-values: 96 97Node identifiers are not values 98******************************* 99 100There is no way to store one in a variable. You cannot write: 101 102.. code-block:: c 103 104 /* These will give you compiler errors: */ 105 106 void *i2c_0 = DT_INST(0, vnd_soc_i2c); 107 unsigned int i2c_1 = DT_INST(1, vnd_soc_i2c); 108 long my_i2c = DT_NODELABEL(i2c1); 109 110If you want something short to save typing, use C macros: 111 112.. code-block:: c 113 114 /* Use something like this instead: */ 115 116 #define MY_I2C DT_NODELABEL(i2c1) 117 118 #define INST(i) DT_INST(i, vnd_soc_i2c) 119 #define I2C_0 INST(0) 120 #define I2C_1 INST(1) 121 122Property access 123*************** 124 125The right API to use to read property values depends on the node and property. 126 127- :ref:`dt-checking-property-exists` 128- :ref:`simple-properties` 129- :ref:`reg-properties` 130- :ref:`interrupts-properties` 131- :ref:`phandle-properties` 132 133.. _dt-checking-property-exists: 134 135Checking properties and values 136============================== 137 138You can use :c:macro:`DT_NODE_HAS_PROP()` to check if a node has a property. For 139the :ref:`example devicetree <dt-node-main-ex>` above: 140 141.. code-block:: c 142 143 DT_NODE_HAS_PROP(DT_NODELABEL(i2c1), clock_frequency) /* expands to 1 */ 144 DT_NODE_HAS_PROP(DT_NODELABEL(i2c1), not_a_property) /* expands to 0 */ 145 146.. _simple-properties: 147 148Simple properties 149================= 150 151Use ``DT_PROP(node_id, property)`` to read basic integer, boolean, string, 152numeric array, and string array properties. 153 154For example, to read the ``clock-frequency`` property's value in the 155:ref:`above example <dt-node-main-ex>`: 156 157.. code-block:: c 158 159 DT_PROP(DT_PATH(soc, i2c_40002000), clock_frequency) /* This is 100000, */ 160 DT_PROP(DT_NODELABEL(i2c1), clock_frequency) /* and so is this, */ 161 DT_PROP(DT_ALIAS(sensor_controller), clock_frequency) /* and this. */ 162 163.. important:: 164 165 The DTS property ``clock-frequency`` is spelled ``clock_frequency`` in C. 166 That is, properties also need special characters converted to underscores. 167 Their names are also forced to lowercase. 168 169Properties with ``string`` and ``boolean`` types work the exact same way. The 170``DT_PROP()`` macro expands to a string literal in the case of strings, and the 171number 0 or 1 in the case of booleans. For example: 172 173.. code-block:: c 174 175 #define I2C1 DT_NODELABEL(i2c1) 176 177 DT_PROP(I2C1, status) /* expands to the string literal "okay" */ 178 179.. note:: 180 181 Don't use DT_NODE_HAS_PROP() for boolean properties. Use DT_PROP() instead 182 as shown above. It will expand to either 0 or 1 depending on if the property 183 is present or absent. 184 185Properties with type ``array``, ``uint8-array``, and ``string-array`` work 186similarly, except ``DT_PROP()`` expands to an array initializer in these cases. 187Here is an example devicetree fragment: 188 189.. code-block:: devicetree 190 191 foo: foo@1234 { 192 a = <1000 2000 3000>; /* array */ 193 b = [aa bb cc dd]; /* uint8-array */ 194 c = "bar", "baz"; /* string-array */ 195 }; 196 197Its properties can be accessed like this: 198 199.. code-block:: c 200 201 #define FOO DT_NODELABEL(foo) 202 203 int a[] = DT_PROP(FOO, a); /* {1000, 2000, 3000} */ 204 unsigned char b[] = DT_PROP(FOO, b); /* {0xaa, 0xbb, 0xcc, 0xdd} */ 205 char* c[] = DT_PROP(FOO, c); /* {"foo", "bar"} */ 206 207You can use :c:macro:`DT_PROP_LEN()` to get logical array lengths in number of 208elements. 209 210.. code-block:: c 211 212 size_t a_len = DT_PROP_LEN(FOO, a); /* 3 */ 213 size_t b_len = DT_PROP_LEN(FOO, b); /* 4 */ 214 size_t c_len = DT_PROP_LEN(FOO, c); /* 2 */ 215 216``DT_PROP_LEN()`` cannot be used with the special ``reg`` or ``interrupts`` 217properties. These have alternative macros which are described next. 218 219.. _reg-properties: 220 221reg properties 222============== 223 224See :ref:`dt-important-props` for an introduction to ``reg``. 225 226Given a node identifier ``node_id``, ``DT_NUM_REGS(node_id)`` is the 227total number of register blocks in the node's ``reg`` property. 228 229You **cannot** read register block addresses and lengths with ``DT_PROP(node, 230reg)``. Instead, if a node only has one register block, use 231:c:macro:`DT_REG_ADDR` or :c:macro:`DT_REG_SIZE`: 232 233- ``DT_REG_ADDR(node_id)``: the given node's register block address 234- ``DT_REG_SIZE(node_id)``: its size 235 236Use :c:macro:`DT_REG_ADDR_BY_IDX` or :c:macro:`DT_REG_SIZE_BY_IDX` instead if the 237node has multiple register blocks: 238 239- ``DT_REG_ADDR_BY_IDX(node_id, idx)``: address of register block at index 240 ``idx`` 241- ``DT_REG_SIZE_BY_IDX(node_id, idx)``: size of block at index ``idx`` 242 243The ``idx`` argument to these must be an integer literal or a macro that 244expands to one without requiring any arithmetic. In particular, ``idx`` cannot 245be a variable. This won't work: 246 247.. code-block:: c 248 249 /* This will cause a compiler error. */ 250 251 for (size_t i = 0; i < DT_NUM_REGS(node_id); i++) { 252 size_t addr = DT_REG_ADDR_BY_IDX(node_id, i); 253 } 254 255.. _interrupts-properties: 256 257interrupts properties 258===================== 259 260See :ref:`dt-important-props` for a brief introduction to ``interrupts``. 261 262Given a node identifier ``node_id``, ``DT_NUM_IRQS(node_id)`` is the total 263number of interrupt specifiers in the node's ``interrupts`` property. 264 265The most general purpose API macro for accessing these is 266:c:macro:`DT_IRQ_BY_IDX`: 267 268.. code-block:: c 269 270 DT_IRQ_BY_IDX(node_id, idx, val) 271 272Here, ``idx`` is the logical index into the ``interrupts`` array, i.e. it is 273the index of an individual interrupt specifier in the property. The ``val`` 274argument is the name of a cell within the interrupt specifier. To use this 275macro, check the bindings file for the node you are interested in to find the 276``val`` names. 277 278Most Zephyr devicetree bindings have a cell named ``irq``, which is the 279interrupt number. You can use :c:macro:`DT_IRQN` as a convenient way to get a 280processed view of this value. 281 282.. warning:: 283 284 Here, "processed" reflects Zephyr's devicetree :ref:`dt-scripts`, which 285 change the ``irq`` number in :ref:`zephyr.dts <devicetree-in-out-files>` to 286 handle hardware constraints on some SoCs and in accordance with Zephyr's 287 multilevel interrupt numbering. 288 289 This is currently not very well documented, and you'll need to read the 290 scripts' source code and existing drivers for more details if you are writing 291 a device driver. 292 293.. _phandle-properties: 294 295phandle properties 296================== 297 298.. note:: 299 300 See :ref:`dt-phandles` for a detailed guide to phandles. 301 302Property values can refer to other nodes using the ``&another-node`` phandle 303syntax introduced in :ref:`dt-writing-property-values`. Properties which 304contain phandles have type ``phandle``, ``phandles``, or ``phandle-array`` in 305their bindings. We'll call these "phandle properties" for short. 306 307You can convert a phandle to a node identifier using :c:macro:`DT_PHANDLE`, 308:c:macro:`DT_PHANDLE_BY_IDX`, or :c:macro:`DT_PHANDLE_BY_NAME`, depending on the 309type of property you are working with. 310 311One common use case for phandle properties is referring to other hardware in 312the tree. In this case, you usually want to convert the devicetree-level 313phandle to a Zephyr driver-level :ref:`struct device <device_model_api>`. 314See :ref:`dt-get-device` for ways to do that. 315 316Another common use case is accessing specifier values in a phandle array. The 317general purpose APIs for this are :c:macro:`DT_PHA_BY_IDX` and :c:macro:`DT_PHA`. 318There are also hardware-specific shorthands like :c:macro:`DT_GPIO_CTLR_BY_IDX`, 319:c:macro:`DT_GPIO_CTLR`, 320:c:macro:`DT_GPIO_PIN_BY_IDX`, :c:macro:`DT_GPIO_PIN`, 321:c:macro:`DT_GPIO_FLAGS_BY_IDX`, and :c:macro:`DT_GPIO_FLAGS`. 322 323See :c:macro:`DT_PHA_HAS_CELL_AT_IDX` and :c:macro:`DT_PROP_HAS_IDX` for ways to 324check if a specifier value is present in a phandle property. 325 326.. _other-devicetree-apis: 327 328Other APIs 329********** 330 331Here are pointers to some other available APIs. 332 333- :c:macro:`DT_CHOSEN`, :c:macro:`DT_HAS_CHOSEN`: for properties 334 of the special ``/chosen`` node 335- :c:macro:`DT_HAS_COMPAT_STATUS_OKAY`, :c:macro:`DT_NODE_HAS_COMPAT`: global- and 336 node-specific tests related to the ``compatible`` property 337- :c:macro:`DT_BUS`: get a node's bus controller, if there is one 338- :c:macro:`DT_ENUM_IDX`: for properties whose values are among a fixed list of 339 choices 340- :ref:`devicetree-flash-api`: APIs for managing fixed flash partitions. 341 Also see :ref:`flash_map_api`, which wraps this in a more user-friendly API. 342 343Device driver conveniences 344************************** 345 346Special purpose macros are available for writing device drivers, which usually 347rely on :ref:`instance identifiers <dt-node-identifiers>`. 348 349To use these, you must define ``DT_DRV_COMPAT`` to the ``compat`` value your 350driver implements support for. This ``compat`` value is what you would pass to 351:c:macro:`DT_INST`. 352 353If you do that, you can access the properties of individual instances of your 354compatible with less typing, like this: 355 356.. code-block:: c 357 358 #include <zephyr/devicetree.h> 359 360 #define DT_DRV_COMPAT my_driver_compat 361 362 /* This is same thing as DT_INST(0, my_driver_compat): */ 363 DT_DRV_INST(0) 364 365 /* 366 * This is the same thing as 367 * DT_PROP(DT_INST(0, my_driver_compat), clock_frequency) 368 */ 369 DT_INST_PROP(0, clock_frequency) 370 371See :ref:`devicetree-inst-apis` for a generic API reference. 372 373Hardware specific APIs 374********************** 375 376Convenience macros built on top of the above APIs are also defined to help 377readability for hardware specific code. See :ref:`devicetree-hw-api` for 378details. 379 380Generated macros 381**************** 382 383While the :file:`zephyr/devicetree.h` API is not generated, it does rely on a 384generated C header which is put into every application build directory: 385:ref:`devicetree_generated.h <dt-outputs>`. This file contains macros with 386devicetree data. 387 388These macros have tricky naming conventions which the :ref:`devicetree_api` API 389abstracts away. They should be considered an implementation detail, but it's 390useful to understand them since they will frequently be seen in compiler error 391messages. 392 393This section contains an Augmented Backus-Naur Form grammar for these 394generated macros, with examples and more details in comments. See `RFC 7405`_ 395(which extends `RFC 5234`_) for a syntax specification. 396 397.. literalinclude:: macros.bnf 398 :language: abnf 399 400.. _RFC 7405: https://tools.ietf.org/html/rfc7405 401.. _RFC 5234: https://tools.ietf.org/html/rfc5234 402