251 lines
10 KiB
ReStructuredText
251 lines
10 KiB
ReStructuredText
.. _device-tree:
|
|
|
|
Device Tree in Zephyr
|
|
########################
|
|
|
|
Introduction to Device Tree
|
|
***************************
|
|
|
|
Device tree is a way of describing hardware and configuration information
|
|
for boards. Device tree was adopted for use in the Linux kernel for the
|
|
PowerPC architecture. However, it is now in use for ARM and other
|
|
architectures.
|
|
|
|
The device tree is a data structure for dynamically describing hardware
|
|
using a Device Tree Source (DTS) data structure language, and compiled
|
|
into a compact Device Tree Blob (DTB) using a Device Tree Compiler (DTC).
|
|
Rather than hard coding every detail of a board's hardware into the
|
|
operating system, the hardware-describing DTB is passed to the operating
|
|
system at boot time. This allows the same compiled Linux kernel to support
|
|
different hardware configurations within an architecture family (e.g., ARM,
|
|
x86, PowerPC) and moves a significant part of the hardware description out of
|
|
the kernel binary itself.
|
|
|
|
Traditional usage of device tree involves storing of the Device Tree Blob.
|
|
The DTB is then used during runtime for configuration of device drivers. In
|
|
Zephyr, the DTS information will be used only during compile time.
|
|
Information about the system is extracted from the compiled DTS and used to
|
|
create the application image.
|
|
|
|
Device tree uses a specific format to describe the device nodes in a system.
|
|
This format is described in `EPAPR document`_.
|
|
|
|
.. _EPAPR document: http://www.devicetree.org/specifications-pdf
|
|
|
|
More device tree information can be found at the `device tree repository`_.
|
|
|
|
.. _device tree repository: https://git.kernel.org/pub/scm/utils/dtc/dtc.git
|
|
|
|
|
|
System build requirements
|
|
*************************
|
|
|
|
The Zephyr device tree feature requires a device tree compiler (DTC) and Python
|
|
YAML packages. Refer to the installation guide for your specific host OS:
|
|
|
|
* :ref:`installing_zephyr_win`
|
|
* :ref:`installation_linux`
|
|
* :ref:`installing_zephyr_mac`
|
|
|
|
|
|
Zephyr and Device Tree
|
|
**********************
|
|
|
|
In Zephyr, device tree is used to not only describe hardware, but also to
|
|
describe Zephyr-specific configuration information. The Zephyr-specific
|
|
information is intended to augment the device tree descriptions. The main
|
|
reason for this is to leverage existing device tree files that a SoC vendor may
|
|
already have defined for a given platform.
|
|
|
|
Today, configuration in Zephyr comes from a number of different places. It can
|
|
come from Kconfig files, CMSIS header files, vendor header files, prj.conf
|
|
files, and other miscellaneous sources. The intent of using device tree is to
|
|
replace or curtail the use of Kconfig files throughout the system, and instead
|
|
use device tree files to describe the configuration of device nodes. CMSIS and
|
|
vendor header files can be used in conjunction with the device tree to fully
|
|
describe hardware. Device tree is not intended to replace CMSIS or vendor
|
|
include files.
|
|
|
|
The device tree files are compiled using the device tree compiler. The compiler
|
|
runs the .dts file through the C preprocessor to resolve any macro or #defines
|
|
utilized in the file. The output of the compile is another dts formatted file.
|
|
|
|
After compilation, a python script extracts information from the compiled device
|
|
tree file using a set of rules specified in YAML files. The extracted
|
|
information is placed in a header file that is used by the rest of the code as
|
|
the project is compiled.
|
|
|
|
A temporary fixup file is required for device tree support on most devices.
|
|
This .fixup file resides in the dts architecture directory and has the same
|
|
name as the master .dts file. The only difference is the suffix is .fixup.
|
|
This fixup file maps the generated include information to the current
|
|
driver/source usage.
|
|
|
|
Device tree file formats
|
|
************************
|
|
|
|
Hardware and software is described inside of device tree files in clear text format.
|
|
These files have the file suffix of .dtsi or .dts. The .dtsi files are meant to
|
|
be included by other files. Typically for a given board you have some number of
|
|
.dtsi include files that pull in common device descriptions that are used across
|
|
a given SoC family.
|
|
|
|
Example: FRDM K64F Board and Hexiwear K64
|
|
=========================================
|
|
|
|
Both of these boards are based on the same NXP Kinetis SoC family, the K6X. The
|
|
following shows the include hierarchy for both boards.
|
|
|
|
dts/arm/frdm_k64.dts includes the following two files::
|
|
|
|
dts/arm/nxp/nxp_k6x.dtsi
|
|
dts/arm/armv7-m.dtsi
|
|
|
|
dts/arm/hexiwear_k64.dts includes the same two files::
|
|
|
|
dts/arm/nxp/nxp_k6x.dtsi
|
|
dts/arm/armv7-m.dtsi
|
|
|
|
The board-specific .dts files enable nodes, define the Zephyr-specific items,
|
|
and also adds board-specific changes like gpio/pinmux assignments. These types
|
|
of things will vary based on the board layout and application use.
|
|
|
|
Currently supported boards
|
|
**************************
|
|
|
|
Device tree is currently supported on all ARM targets. Support for all other
|
|
architectures is to be completed by release 1.9.
|
|
|
|
Adding support for a board
|
|
**************************
|
|
|
|
Adding device tree support for a given board requires adding a number of files.
|
|
These files will contain the DTS information that describes a platform, the
|
|
YAML descriptions that define the contents of a given Device Tree peripheral
|
|
node, and also any fixup files required to support the platform.
|
|
|
|
When writing Device Tree Source files, it is good to separate out common
|
|
peripheral information that could be used across multiple SoC families or
|
|
boards. DTS files are identified by their file suffix. A .dtsi suffix denotes
|
|
a DTS file that is used as an include in another DTS file. A .dts suffix
|
|
denotes the primary DTS file for a given board.
|
|
|
|
The primary DTS file will contain at a minimum a version line, optional
|
|
includes, and the root node definition. The root node will contain a model and
|
|
compatible that denotes the unique board described by the .dts file.
|
|
|
|
Device Tree Source File Template
|
|
================================
|
|
|
|
.. code-block:: yaml
|
|
|
|
/dts-v1/
|
|
/ {
|
|
model = "Model name for your board";
|
|
compatible = "compatible for your board";
|
|
/* rest of file */
|
|
};
|
|
|
|
|
|
One suggestion for starting from scratch on a platform/board is to examine other
|
|
boards and their device tree source files.
|
|
|
|
The following is a more precise list of required files:
|
|
|
|
* Base architecture support
|
|
|
|
* Add architecture-specific DTS directory, if not already present.
|
|
Example: dts/arm for ARM.
|
|
* Add target to dts/<ARCH>/Makefile or create Makefile if not present
|
|
* Add target specific device tree files for base SoC. These should be
|
|
.dtsi files to be included in the board-specific device tree files.
|
|
* Add target specific YAML files in the dts/<ARCH>/yaml directory.
|
|
Create the yaml directory if not present.
|
|
|
|
* SoC family support
|
|
|
|
* Add one or more SoC family .dtsi files that describe the hardware
|
|
for a set of devices. The file should contain all the relevant
|
|
nodes and base configuration that would be applicable to all boards
|
|
utilizing that SoC family.
|
|
* Add SoC family YAML files that describe the nodes present in the .dtsi file.
|
|
|
|
* Board specific support
|
|
|
|
* Add a board level .dts file that includes the SoC family .dtsi files
|
|
and enables the nodes required for that specific board.
|
|
* Board .dts file should specify the SRAM and FLASH devices, if present.
|
|
* Add board-specific YAML files, if required. This would occur if the
|
|
board has additional hardware that is not covered by the SoC family
|
|
.dtsi/.yaml files.
|
|
|
|
* Fixup files
|
|
|
|
* Fixup files contain mappings from existing Kconfig options to the actual
|
|
underlying DTS derived configuration #defines. Fixup files are temporary
|
|
artifacts until additional DTS changes are made to make them unnecessary.
|
|
|
|
Adding support for device tree in drivers
|
|
*****************************************
|
|
|
|
As drivers and other source code is converted over to make use of device tree
|
|
generated information, these drivers may require changes to match the generated
|
|
#define information.
|
|
|
|
|
|
Source Tree Hierarchy
|
|
*********************
|
|
|
|
The device tree files are located in a couple of different directories. The
|
|
directory split is done based on architecture, and there is also a common
|
|
directory where architecture agnostic device tree and yaml files are located.
|
|
|
|
Assuming the current working directory is the ZEPHYR_BASE, the directory
|
|
hierarchy looks like the following::
|
|
|
|
dts/common/
|
|
dts/common/yaml
|
|
dts/<ARCH>/
|
|
dts/<ARCH>/yaml
|
|
|
|
The common directories contain a skeleton.dtsi include file that defines the
|
|
address and size cells. The yaml subdirectory contains common yaml files for
|
|
Zephyr-specific nodes/properties and generic device properties common across
|
|
architectures.
|
|
|
|
Example: DTS/YAML files for NXP FRDM K64F::
|
|
|
|
dts/arm/armv7-m.dtsi
|
|
dts/arm/k6x/nxp_k6x.dtsi
|
|
dts/arm/frdm_k64f.dts
|
|
dts/arm/yaml/arm,v7m-nvic.yaml
|
|
dts/arm/yaml/k64gpio.yaml
|
|
dts/arm/yaml/k64pinmux.yaml
|
|
dts/arm/yaml/k64uart.yaml
|
|
|
|
YAML definitions for device nodes
|
|
*********************************
|
|
|
|
Device tree can describe hardware and configuration, but it doesn't tell the
|
|
system which pieces of information are useful, or how to generate configuration
|
|
data from the device tree nodes. For this, we rely on YAML files to describe
|
|
the contents or definition of a device tree node.
|
|
|
|
A YAML description must be provided for every device node that is to be a source
|
|
of information for the system. This YAML description can be used for more than
|
|
one purpose. It can be used in conjunction with the device tree to generate
|
|
include information. It can also be used to validate the device tree files
|
|
themselves. A device tree file can successfully compile and still not contain
|
|
the necessary pieces required to build the rest of the software. YAML provides
|
|
a means to detect that issue.
|
|
|
|
YAML files reside in a subdirectory inside the common and architecture-specific
|
|
device tree directories. A YAML template file is provided to show the required
|
|
format. This file is located at::
|
|
|
|
dts/common/yaml/device_node.yaml.template
|
|
|
|
YAML files must end in a .yaml suffix. YAML files are scanned during the
|
|
information extraction phase and are matched to device tree nodes via the
|
|
compatible property.
|