diff --git a/doc/guides/dts/howtos.rst b/doc/guides/dts/howtos.rst index 5e5fa2be098..0fc0c0b5e3e 100644 --- a/doc/guides/dts/howtos.rst +++ b/doc/guides/dts/howtos.rst @@ -5,6 +5,8 @@ Devicetree HOWTOs 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 your devicetree and generated header @@ -153,8 +155,9 @@ creating the device, or the device's initialization function failed. Find a devicetree binding ************************* -Devicetree binding YAML files document what you can do with the nodes they -describe, so it's critical to be able to find them for the nodes you are using. +:ref:`dt-bindings` are YAML files which declare what you can do with the nodes +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 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 :ref:`BOARD.dts ` files or via :ref:`devicetree 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 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 - ```` 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 `? -- does the node have a :ref:`matching binding `? - -.. _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 `. - -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`. diff --git a/doc/guides/dts/index.rst b/doc/guides/dts/index.rst index bc3747b6f15..ca6c748738e 100644 --- a/doc/guides/dts/index.rst +++ b/doc/guides/dts/index.rst @@ -14,4 +14,5 @@ See :ref:`devicetree` for reference material. bindings.rst api-usage.rst howtos.rst + troubleshooting.rst dt-vs-kconfig.rst diff --git a/doc/guides/dts/troubleshooting.rst b/doc/guides/dts/troubleshooting.rst new file mode 100644 index 00000000000..8d80780dc79 --- /dev/null +++ b/doc/guides/dts/troubleshooting.rst @@ -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 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 + ```` 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 `? +- does the node have a :ref:`matching binding `? +- 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 `; 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`.