doc: guides: dts improvements
People seem to miss the troubleshooting page a lot, since nobody ever mentions that they tried its steps and they didn't work. Promote it to a top level page to make it easier to see. Add cross-references between the two to keep them well linked together. Add a couple of extra links to the bindings related HOWTO while we are here, now that the bindings docs are a bit better off than they were when this content was originally written. Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
parent
574746e7dc
commit
7e7f4201df
3 changed files with 140 additions and 129 deletions
|
@ -5,6 +5,8 @@ Devicetree HOWTOs
|
||||||
|
|
||||||
This page has step-by-step advice for getting things done with devicetree.
|
This page has step-by-step advice for getting things done with devicetree.
|
||||||
|
|
||||||
|
.. tip:: See :ref:`dt-trouble` for troubleshooting advice.
|
||||||
|
|
||||||
.. _get-devicetree-outputs:
|
.. _get-devicetree-outputs:
|
||||||
|
|
||||||
Get your devicetree and generated header
|
Get your devicetree and generated header
|
||||||
|
@ -153,8 +155,9 @@ creating the device, or the device's initialization function failed.
|
||||||
Find a devicetree binding
|
Find a devicetree binding
|
||||||
*************************
|
*************************
|
||||||
|
|
||||||
Devicetree binding YAML files document what you can do with the nodes they
|
:ref:`dt-bindings` are YAML files which declare what you can do with the nodes
|
||||||
describe, so it's critical to be able to find them for the nodes you are using.
|
they describe, so it's critical to be able to find them for the nodes you are
|
||||||
|
using.
|
||||||
|
|
||||||
If you don't have them already, :ref:`get-devicetree-outputs`. To find a node's
|
If you don't have them already, :ref:`get-devicetree-outputs`. To find a node's
|
||||||
binding, open the generated header file, which starts with a list of nodes in a
|
binding, open the generated header file, which starts with a list of nodes in a
|
||||||
|
@ -597,130 +600,3 @@ supporting a devicetree alias to specify the hardware specific portions, as is
|
||||||
done in the :ref:`blinky-sample`. The application can then be configured in
|
done in the :ref:`blinky-sample`. The application can then be configured in
|
||||||
:ref:`BOARD.dts <devicetree-in-out-files>` files or via :ref:`devicetree
|
:ref:`BOARD.dts <devicetree-in-out-files>` files or via :ref:`devicetree
|
||||||
overlays <use-dt-overlays>`.
|
overlays <use-dt-overlays>`.
|
||||||
|
|
||||||
.. _dt-trouble:
|
|
||||||
|
|
||||||
Troubleshoot devicetree issues
|
|
||||||
******************************
|
|
||||||
|
|
||||||
Here are some tips for fixing misbehaving devicetree code.
|
|
||||||
|
|
||||||
Try again with a pristine build directory
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
See :ref:`west-building-pristine` for examples, or just delete the build
|
|
||||||
directory completely and retry.
|
|
||||||
|
|
||||||
This is general advice which is especially applicable to debugging devicetree
|
|
||||||
issues, because the outputs are created at CMake configuration time, and are
|
|
||||||
not always regenerated when one of their inputs changes.
|
|
||||||
|
|
||||||
Make sure <devicetree.h> is included
|
|
||||||
====================================
|
|
||||||
|
|
||||||
Unlike Kconfig symbols, the :file:`devicetree.h` header must be included
|
|
||||||
explicitly.
|
|
||||||
|
|
||||||
Many Zephyr header files rely on information from devicetree, so including some
|
|
||||||
other API may transitively include :file:`devicetree.h`, but that's not
|
|
||||||
guaranteed.
|
|
||||||
|
|
||||||
.. _dt-use-the-right-names:
|
|
||||||
|
|
||||||
Make sure you're using the right names
|
|
||||||
======================================
|
|
||||||
|
|
||||||
Remember that:
|
|
||||||
|
|
||||||
- In C/C++, devicetree names must be lowercased and special characters must be
|
|
||||||
converted to underscores. Zephyr's generated devicetree header has DTS names
|
|
||||||
converted in this way into the C tokens used by the preprocessor-based
|
|
||||||
``<devicetree.h>`` API.
|
|
||||||
- In overlays, use devicetree node and property names the same way they
|
|
||||||
would appear in any DTS file. Zephyr overlays are just DTS fragments.
|
|
||||||
|
|
||||||
For example, if you're trying to **get** the ``clock-frequency`` property of a
|
|
||||||
node with path ``/soc/i2c@12340000`` in a C/C++ file:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
/*
|
|
||||||
* foo.c: lowercase-and-underscores names
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Don't do this: */
|
|
||||||
#define MY_CLOCK_FREQ DT_PROP(DT_PATH(soc, i2c@1234000), clock-frequency)
|
|
||||||
/* ^ ^
|
|
||||||
* @ should be _ - should be _ */
|
|
||||||
|
|
||||||
/* Do this instead: */
|
|
||||||
#define MY_CLOCK_FREQ DT_PROP(DT_PATH(soc, i2c_1234000), clock_frequency)
|
|
||||||
/* ^ ^ */
|
|
||||||
|
|
||||||
And if you're trying to **set** that property in a devicetree overlay:
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
|
|
||||||
/*
|
|
||||||
* foo.overlay: DTS names with special characters, etc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Don't do this; you'll get devicetree errors. */
|
|
||||||
&{/soc/i2c_12340000/} {
|
|
||||||
clock_frequency = <115200>;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Do this instead. Overlays are just DTS fragments. */
|
|
||||||
&{/soc/i2c@12340000/} {
|
|
||||||
clock-frequency = <115200>;
|
|
||||||
};
|
|
||||||
|
|
||||||
Validate properties
|
|
||||||
===================
|
|
||||||
|
|
||||||
If you're getting a compile error reading a node property, check your node
|
|
||||||
identifier and property. For example, if you get a build error on a line that
|
|
||||||
looks like this:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
int baud_rate = DT_PROP(DT_NODELABEL(my_serial), current_speed);
|
|
||||||
|
|
||||||
Try checking the node by adding this to the file and recompiling:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
#if !DT_NODE_EXISTS(DT_NODELABEL(my_serial))
|
|
||||||
#error "whoops"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
If you see the "whoops" error message when you rebuild, the node identifier
|
|
||||||
isn't referring to a valid node. :ref:`get-devicetree-outputs` and debug from
|
|
||||||
there.
|
|
||||||
|
|
||||||
Some hints for what to check next if you don't see the "whoops" error message:
|
|
||||||
|
|
||||||
- did you :ref:`dt-use-the-right-names`?
|
|
||||||
- does the :ref:`property exist <dt-checking-property-exists>`?
|
|
||||||
- does the node have a :ref:`matching binding <dt-bindings>`?
|
|
||||||
|
|
||||||
.. _missing-dt-binding:
|
|
||||||
|
|
||||||
Check for missing bindings
|
|
||||||
==========================
|
|
||||||
|
|
||||||
If the build fails to :ref:`dts-find-binding` for a node, then either the
|
|
||||||
node's ``compatible`` property is not defined, or its value has no matching
|
|
||||||
binding. If the property is set, check for typos in its name. In a devicetree
|
|
||||||
source file, ``compatible`` should look like ``"vnd,some-device"`` --
|
|
||||||
:ref:`dt-use-the-right-names`.
|
|
||||||
|
|
||||||
If your binding file is not under :file:`zephyr/dts`, you may need to set
|
|
||||||
:ref:`DTS_ROOT <dts_root>`.
|
|
||||||
|
|
||||||
Errors with DT_INST_() APIs
|
|
||||||
===========================
|
|
||||||
|
|
||||||
If you're using an API like :c:func:`DT_INST_PROP`, you must define
|
|
||||||
``DT_DRV_COMPAT`` to the lowercase-and-underscores version of the compatible
|
|
||||||
you are interested in. See :ref:`dt-create-devices-inst`.
|
|
||||||
|
|
|
@ -14,4 +14,5 @@ See :ref:`devicetree` for reference material.
|
||||||
bindings.rst
|
bindings.rst
|
||||||
api-usage.rst
|
api-usage.rst
|
||||||
howtos.rst
|
howtos.rst
|
||||||
|
troubleshooting.rst
|
||||||
dt-vs-kconfig.rst
|
dt-vs-kconfig.rst
|
||||||
|
|
134
doc/guides/dts/troubleshooting.rst
Normal file
134
doc/guides/dts/troubleshooting.rst
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
.. _dt-trouble:
|
||||||
|
|
||||||
|
Troubleshooting devicetree
|
||||||
|
##########################
|
||||||
|
|
||||||
|
Here are some tips for fixing misbehaving devicetree related code.
|
||||||
|
|
||||||
|
See :ref:`dt-howtos` for other "HOWTO" style information.
|
||||||
|
|
||||||
|
Try again with a pristine build directory
|
||||||
|
*****************************************
|
||||||
|
|
||||||
|
.. important:: Try this first, before doing anything else.
|
||||||
|
|
||||||
|
See :ref:`west-building-pristine` for examples, or just delete the build
|
||||||
|
directory completely and retry.
|
||||||
|
|
||||||
|
This is general advice which is especially applicable to debugging devicetree
|
||||||
|
issues, because the outputs are created during the CMake configuration phase,
|
||||||
|
and are not always regenerated when one of their inputs changes.
|
||||||
|
|
||||||
|
Make sure <devicetree.h> is included
|
||||||
|
************************************
|
||||||
|
|
||||||
|
Unlike Kconfig symbols, the :file:`devicetree.h` header must be included
|
||||||
|
explicitly.
|
||||||
|
|
||||||
|
Many Zephyr header files rely on information from devicetree, so including some
|
||||||
|
other API may transitively include :file:`devicetree.h`, but that's not
|
||||||
|
guaranteed.
|
||||||
|
|
||||||
|
.. _dt-use-the-right-names:
|
||||||
|
|
||||||
|
Make sure you're using the right names
|
||||||
|
**************************************
|
||||||
|
|
||||||
|
Remember that:
|
||||||
|
|
||||||
|
- In C/C++, devicetree names must be lowercased and special characters must be
|
||||||
|
converted to underscores. Zephyr's generated devicetree header has DTS names
|
||||||
|
converted in this way into the C tokens used by the preprocessor-based
|
||||||
|
``<devicetree.h>`` API.
|
||||||
|
- In overlays, use devicetree node and property names the same way they
|
||||||
|
would appear in any DTS file. Zephyr overlays are just DTS fragments.
|
||||||
|
|
||||||
|
For example, if you're trying to **get** the ``clock-frequency`` property of a
|
||||||
|
node with path ``/soc/i2c@12340000`` in a C/C++ file:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
/*
|
||||||
|
* foo.c: lowercase-and-underscores names
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Don't do this: */
|
||||||
|
#define MY_CLOCK_FREQ DT_PROP(DT_PATH(soc, i2c@1234000), clock-frequency)
|
||||||
|
/* ^ ^
|
||||||
|
* @ should be _ - should be _ */
|
||||||
|
|
||||||
|
/* Do this instead: */
|
||||||
|
#define MY_CLOCK_FREQ DT_PROP(DT_PATH(soc, i2c_1234000), clock_frequency)
|
||||||
|
/* ^ ^ */
|
||||||
|
|
||||||
|
And if you're trying to **set** that property in a devicetree overlay:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
/*
|
||||||
|
* foo.overlay: DTS names with special characters, etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Don't do this; you'll get devicetree errors. */
|
||||||
|
&{/soc/i2c_12340000/} {
|
||||||
|
clock_frequency = <115200>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Do this instead. Overlays are just DTS fragments. */
|
||||||
|
&{/soc/i2c@12340000/} {
|
||||||
|
clock-frequency = <115200>;
|
||||||
|
};
|
||||||
|
|
||||||
|
Validate properties
|
||||||
|
*******************
|
||||||
|
|
||||||
|
If you're getting a compile error reading a node property, check your node
|
||||||
|
identifier and property. For example, if you get a build error on a line that
|
||||||
|
looks like this:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
int baud_rate = DT_PROP(DT_NODELABEL(my_serial), current_speed);
|
||||||
|
|
||||||
|
Try checking the node by adding this to the file and recompiling:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
#if !DT_NODE_EXISTS(DT_NODELABEL(my_serial))
|
||||||
|
#error "whoops"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
If you see the "whoops" error message when you rebuild, the node identifier
|
||||||
|
isn't referring to a valid node. :ref:`get-devicetree-outputs` and debug from
|
||||||
|
there.
|
||||||
|
|
||||||
|
Some hints for what to check next if you don't see the "whoops" error message:
|
||||||
|
|
||||||
|
- did you :ref:`dt-use-the-right-names`?
|
||||||
|
- does the :ref:`property exist <dt-checking-property-exists>`?
|
||||||
|
- does the node have a :ref:`matching binding <dt-bindings>`?
|
||||||
|
- does the binding define the property?
|
||||||
|
|
||||||
|
.. _missing-dt-binding:
|
||||||
|
|
||||||
|
Check for missing bindings
|
||||||
|
**************************
|
||||||
|
|
||||||
|
See :ref:`dt-bindings` for information about bindings, and
|
||||||
|
:ref:`devicetree_binding_index` for information on bindings built into Zephyr.
|
||||||
|
|
||||||
|
If the build fails to :ref:`dts-find-binding` for a node, then either the
|
||||||
|
node's ``compatible`` property is not defined, or its value has no matching
|
||||||
|
binding. If the property is set, check for typos in its name. In a devicetree
|
||||||
|
source file, ``compatible`` should look like ``"vnd,some-device"`` --
|
||||||
|
:ref:`dt-use-the-right-names`.
|
||||||
|
|
||||||
|
If your binding file is not under :file:`zephyr/dts`, you may need to set
|
||||||
|
:ref:`DTS_ROOT <dts_root>`; see :ref:`dt-where-bindings-are-located`.
|
||||||
|
|
||||||
|
Errors with DT_INST_() APIs
|
||||||
|
***************************
|
||||||
|
|
||||||
|
If you're using an API like :c:func:`DT_INST_PROP`, you must define
|
||||||
|
``DT_DRV_COMPAT`` to the lowercase-and-underscores version of the compatible
|
||||||
|
you are interested in. See :ref:`dt-create-devices-inst`.
|
Loading…
Add table
Add a link
Reference in a new issue