Devicetree API
This is a reference page for the <zephyr/devicetree.h>
API. The API is macro
based. Use of these macros has no impact on scheduling. They can be used from
any calling context and at file scope.
Some of these – the ones beginning with DT_INST_
– require a special
macro named DT_DRV_COMPAT
to be defined before they can be used; these are
discussed individually below. These macros are generally meant for use within
device drivers, though they can be used outside of
drivers with appropriate care.
Generic APIs
The APIs in this section can be used anywhere and do not require
DT_DRV_COMPAT
to be defined.
Node identifiers and helpers
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 devicetree data in C rvalue form using, for example, the Property access API.
The root node /
has node identifier DT_ROOT
. You can create node
identifiers for other devicetree nodes using DT_PATH()
,
DT_NODELABEL()
, DT_ALIAS()
, and DT_INST()
.
There are also DT_PARENT()
and DT_CHILD()
macros which can be
used to create node identifiers for a given node’s parent node or a particular
child node, respectively.
The following macros create or operate on node identifiers.
Property access
The following general-purpose macros can be used to access node properties. There are special-purpose APIs for accessing the ranges property, reg property and interrupts property.
Property values can be read using these macros even if the node is disabled, as long as it has a matching binding.
ranges
property
Use these APIs instead of Property access to access the
ranges
property. Because this property’s semantics are defined by the
devicetree specification, these macros can be used even for nodes without
matching bindings. However, they take on special semantics when the node’s
binding indicates it is a PCIe bus node, as defined in the
PCI Bus Binding to: IEEE Std 1275-1994 Standard for Boot (Initialization Configuration) Firmware
reg
property
Use these APIs instead of Property access to access the
reg
property. Because this property’s semantics are defined by the
devicetree specification, these macros can be used even for nodes without
matching bindings.
interrupts
property
Use these APIs instead of Property access to access the
interrupts
property.
Because this property’s semantics are defined by the devicetree specification, some of these macros can be used even for nodes without matching bindings. This does not apply to macros which take cell names as arguments.
For-each macros
There is currently only one “generic” for-each macro,
DT_FOREACH_CHILD()
, which allows iterating over the children of a
devicetree node.
There are special-purpose for-each macros, like
DT_INST_FOREACH_STATUS_OKAY()
, but these require DT_DRV_COMPAT
to
be defined before use.
Existence checks
This section documents miscellaneous macros that can be used to test if a node
exists, how many nodes of a certain type exist, whether a node has certain
properties, etc. Some macros used for special purposes (such as
DT_IRQ_HAS_IDX()
and all macros which require DT_DRV_COMPAT
) are
documented elsewhere on this page.
Inter-node dependencies
The devicetree.h
API has some support for tracking dependencies between
nodes. Dependency tracking relies on a binary “depends on” relation between
devicetree nodes, which is defined as the transitive closure of the following “directly
depends on” relation:
every non-root node directly depends on its parent node
a node directly depends on any nodes its properties refer to by phandle
a node directly depends on its
interrupt-parent
if it has aninterrupts
propertya parent node inherits all dependencies from its child nodes
A dependency ordering of a devicetree is a list of its nodes, where each node
n
appears earlier in the list than any nodes that depend on n
. A node’s
dependency ordinal is then its zero-based index in that list. Thus, for two
distinct devicetree nodes n1
and n2
with dependency ordinals d1
and
d2
, we have:
d1 != d2
if
n1
depends onn2
, thend1 > d2
d1 > d2
does not necessarily imply thatn1
depends onn2
The Zephyr build system chooses a dependency ordering of the final devicetree and assigns a dependency ordinal to each node. Dependency related information can be accessed using the following macros. The exact dependency ordering chosen is an implementation detail, but cyclic dependencies are detected and cause errors, so it’s safe to assume there are none when using these macros.
There are instance number-based conveniences as well; see
DT_INST_DEP_ORD()
and subsequent documentation.
Bus helpers
Zephyr’s devicetree bindings language supports a bus:
key which allows
bindings to declare that nodes with a given compatible describe system buses.
In this case, child nodes are considered to be on a bus of the given type, and
the following APIs may be used.
Instance-based APIs
These are recommended for use within device drivers. To use them, define
DT_DRV_COMPAT
to the lowercase-and-underscores compatible the device driver
implements support for. Here is an example devicetree fragment:
serial@40001000 {
compatible = "vnd,serial";
status = "okay";
current-speed = <115200>;
};
Example usage, assuming serial@40001000
is the only enabled node
with compatible vnd,serial
:
#define DT_DRV_COMPAT vnd_serial
DT_DRV_INST(0) // node identifier for serial@40001000
DT_INST_PROP(0, current_speed) // 115200
Warning
Be careful making assumptions about instance numbers. See DT_INST()
for the API guarantees.
As shown above, the DT_INST_*
APIs are conveniences for addressing nodes by
instance number. They are almost all defined in terms of one of the
Generic APIs. The equivalent generic API can be found by
removing INST_
from the macro name. For example, DT_INST_PROP(inst,
prop)
is equivalent to DT_PROP(DT_DRV_INST(inst), prop)
. Similarly,
DT_INST_REG_ADDR(inst)
is equivalent to DT_REG_ADDR(DT_DRV_INST(inst))
,
and so on. There are some exceptions: DT_ANY_INST_ON_BUS_STATUS_OKAY()
and DT_INST_FOREACH_STATUS_OKAY()
are special-purpose helpers without
straightforward generic equivalents.
Since DT_DRV_INST()
requires DT_DRV_COMPAT
to be defined, it’s an error
to use any of these without that macro defined.
Note that there are also helpers available for specific hardware; these are documented in Hardware specific APIs.
Hardware specific APIs
The following APIs can also be used by including <devicetree.h>
;
no additional include is needed.
CAN
These conveniences may be used for nodes which describe CAN controllers/transceivers, and properties related to them.
Clocks
These conveniences may be used for nodes which describe clock sources, and properties related to them.
DMA
These conveniences may be used for nodes which describe direct memory access controllers or channels, and properties related to them.
Fixed flash partitions
These conveniences may be used for the special-purpose fixed-partitions
compatible used to encode information about flash memory partitions in the
device tree. See See fixed-partition
for more details.
GPIO
These conveniences may be used for nodes which describe GPIO controllers/pins, and properties related to them.
IO channels
These are commonly used by device drivers which need to use IO channels (e.g. ADC or DAC channels) for conversion.
MBOX
These conveniences may be used for nodes which describe MBOX controllers/users, and properties related to them.
Pinctrl (pin control)
These are used to access pin control properties by name or index.
Devicetree nodes may have properties which specify pin control (sometimes known
as pin mux) settings. These are expressed using pinctrl-<index>
properties
within the node, where the <index>
values are contiguous integers starting
from 0. These may also be named using the pinctrl-names
property.
Here is an example:
node {
...
pinctrl-0 = <&foo &bar ...>;
pinctrl-1 = <&baz ...>;
pinctrl-names = "default", "sleep";
};
Above, pinctrl-0
has name "default"
, and pinctrl-1
has name
"sleep"
. The pinctrl-<index>
property values contain phandles. The
&foo
, &bar
, etc. phandles within the properties point to nodes whose
contents vary by platform, and which describe a pin configuration for the node.
PWM
These conveniences may be used for nodes which describe PWM controllers and properties related to them.
Reset Controller
These conveniences may be used for nodes which describe reset controllers and properties related to them.
SPI
These conveniences may be used for nodes which describe either SPI controllers or devices, depending on the case.
Chosen nodes
The special /chosen
node contains properties whose values describe
system-wide settings. The DT_CHOSEN()
macro can be used to get a node
identifier for a chosen node.
Zephyr-specific chosen nodes
The following table documents some commonly used Zephyr-specific chosen nodes.
Sometimes, a chosen node’s label property will be used to set the default value of a Kconfig option which in turn configures a hardware-specific device. This is usually for backwards compatibility in cases when the Kconfig option predates devicetree support in Zephyr. In other cases, there is no Kconfig option, and the devicetree node is used directly in the source code to select a device.
Property |
Purpose |
---|---|
zephyr,bt-c2h-uart |
Selects the UART used for host communication in the HCI UART |
zephyr,bt-mon-uart |
Sets UART device used for the Bluetooth monitor logging |
zephyr,bt-hci |
Selects the HCI device used by the Bluetooth host stack |
zephyr,canbus |
Sets the default CAN controller |
zephyr,ccm |
Core-Coupled Memory node on some STM32 SoCs |
zephyr,code-partition |
Flash partition that the Zephyr image’s text section should be linked into |
zephyr,console |
Sets UART device used by console driver |
zephyr,display |
Sets the default display controller |
zephyr,keyboard-scan |
Sets the default keyboard scan controller |
zephyr,dtcm |
Data Tightly Coupled Memory node on some Arm SoCs |
zephyr,entropy |
A device which can be used as a system-wide entropy source |
zephyr,flash |
A node whose |
zephyr,flash-controller |
The node corresponding to the flash controller device for
the |
zephyr,gdbstub-uart |
Sets UART device used by the GDB stub subsystem |
zephyr,ieee802154 |
Used by the networking subsystem to set the IEEE 802.15.4 device |
zephyr,ipc |
Used by the OpenAMP subsystem to specify the inter-process communication (IPC) device |
zephyr,ipc_shm |
A node whose |
zephyr,itcm |
Instruction Tightly Coupled Memory node on some Arm SoCs |
zephyr,log-uart |
Sets the UART device(s) used by the logging subsystem’s UART backend. If defined, the UART log backend would output to the devices listed in this node. |
zephyr,ocm |
On-chip memory node on Xilinx Zynq-7000 and ZynqMP SoCs |
zephyr,osdp-uart |
Sets UART device used by OSDP subsystem |
zephyr,ot-uart |
Used by the OpenThread to specify UART device for Spinel protocol |
zephyr,pcie-controller |
The node corresponding to the PCIe Controller |
zephyr,ppp-uart |
Sets UART device used by PPP |
zephyr,settings-partition |
Fixed partition node. If defined this selects the partition used by the NVS and FCB settings backends. |
zephyr,shell-uart |
Sets UART device used by serial shell backend |
zephyr,sram |
A node whose |
zephyr,tracing-uart |
Sets UART device used by tracing subsystem |
zephyr,uart-mcumgr |
UART used for Device Management |
zephyr,uart-pipe |
Sets UART device used by serial pipe driver |
zephyr,usb-device |
USB device node. If defined and has a |
zephyr,led-strip |
A LED-strip node which is used to determine the timings of the WS2812 GPIO driver |
zephyr,touch |
touchscreen controller device node. |