NVIDIA Jetson - Device Tree Overlay: Difference between revisions
mNo edit summary |
|||
(43 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
== | <seo title="NVIDIA Jetson Device Tree Overlay | Device Tree Overlay | RidgeRun Developer" titlemode="replace" keywords="NVIDIA Jetson, Jetson, NVIDIA, Device Tree, Device Tree Overlay, Jetson developer kit, Jetson‑IO tool, DT overlay, Jetson Xavier NX Developer Kit, Jetson Expansion Header Tool, Jetson‑IO, NVIDIA Jetson board, device tree overlay, Device tree overlay structure, Simple Device Tree Overlay, GStreamer, TX1, TX2, Jetson AGX Xavier, Xavier, AI, Deep Learning, TX1, TX2, Jetson TX1, Jetson TX2, Jetson Xavier, NVIDIA Jetson Xavier, NVIDIA Jetson Orin, Jetson Orin, Orin, NVIDIA Orin, NVIDIA Jetson AGX Orin, Jetson AGX Orin" description="This wiki page from RidgeRun is about the reference if you want to create a Device Tree (DT) overlay for a custom hardware module."></seo> | ||
This wiki is | |||
<table> | |||
<tr> | |||
<td><div class="clear; float:right">__TOC__</div></td> | |||
<br> | |||
<td> | |||
<td> | |||
<br> | |||
<table> | |||
<tr> | |||
<td><div class="clear; float:right">__TOC__</div></td> | |||
<td> | |||
{{NVIDIA Preferred Partner logo}} | |||
<td> | |||
<center> | |||
{{ContactUs Button}} | |||
</center> | |||
</tr> | |||
</table> | |||
</td> | |||
</td> | |||
</tr> | |||
</table> | |||
== | ==Introduction to Device Tree Overlay== | ||
This wiki is intended to be used as a reference if you want to create a Device Tree (DT) overlay for a custom hardware module. DT overlays are used to configure various hardware devices that may be attached to the system. | |||
NVIDIA Jetson kernels use a device tree to describe the hardware present in the NVIDIA Jetson board. You can use Jetson‑IO tool to support a custom hardware module by creating a device tree overlay for the hardware module to allow optional external hardware to be described and configured. | |||
==Create a Device Tree Overlay== | |||
===Jetson‑IO=== | ===Jetson‑IO=== | ||
NVIDIA provides the Jetson Expansion Header Tool also known as Jetson‑IO) | NVIDIA provides the Jetson Expansion Header Tool (also known as Jetson‑IO). It is a Python script that runs on a Jetson developer kit and lets you apply a DT overlay configuration through a graphic user interface. Jetson‑IO finds the overlay file and allows you to apply it. | ||
You can use Jetson‑IO to perform 2 | You can use Jetson‑IO to perform 2 tasks: | ||
# '''Configure header pins manually''': | # '''Configure header pins manually''': displays the expansion header configuration screen, which lets you specify which functions to enable on the header. The application creates the DT overlay and it is applied. | ||
#'''Configure for compatible hardware''': | #'''Configure for compatible hardware''': displays the compatible hardware screen, which lets you select from a list of configurations for hardware modules that can be attached to the header. You can use a pre-created DT overlay for certain hardware or create your custom DT overlay and select it from the list. | ||
This guide uses the second option to apply a custom DT overlay. | This guide uses the second option to apply a custom DT overlay. | ||
===Device | ===Device Tree Overlay structure=== | ||
A device tree overlay for a hardware module must define the property: | A device tree overlay for a hardware module must define the property: | ||
* '''<code>overlay-name</code>''': | * '''<code>overlay-name</code>''': specifies a name for the hardware module. | ||
* '''<code>jetson-header-name</code>''': | * '''<code>jetson-header-name</code>''': specifies the expansion header to which the hardware module is associated; it must specify one of the values described in the table [https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/hw_setup_jetson_io.html#wwpID0E03B0HA jetson-header-name property values]. | ||
* '''<code>compatible</code>''': | * '''<code>compatible</code>''': indicates which combination of Jetson module and carrier board the overlay supports; t must specify one or more of the values described in the table [https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/hw_setup_jetson_io.html#wwpID0E03B0HA compatible property values]. | ||
* '''<code>fragment</code>''': | * '''<code>fragment</code>''': a DT overlay comprises a number of fragments, each of them indicates child nodes and the target. | ||
* '''<code>target</code>''': phandle target of the overlay. | * '''<code>target</code>''': phandle target of the overlay. | ||
* '''<code>target-path</code>''': target path of the overlay. | * '''<code>target-path</code>''': target path of the overlay. | ||
Line 29: | Line 54: | ||
===Creating a Simple Device Tree Overlay=== | ===Creating a Simple Device Tree Overlay=== | ||
To create a simple device tree overlay to add a new custom property for Jetson Xavier NX Developer Kit and attach it to the 40‑pin expansion header, create a file named my-overlay.dts on the target platform with the following contents: | To create a simple device tree overlay to add a new custom property for Jetson Xavier NX Developer Kit and attach it to the 40‑pin expansion header, create a file named <code>my-overlay.dts</code> on the target platform with the following contents: | ||
< | <syntaxhighlight lang="C"> | ||
/dts-v1/; | /dts-v1/; | ||
/ { | / { | ||
Line 47: | Line 71: | ||
}; | }; | ||
}; | }; | ||
</ | </syntaxhighlight> | ||
Enter the following command to compile the DTS source file into an overlay file: | Enter the following command to compile the DTS source file into an overlay file: | ||
< | <syntaxhighlight lang="bash"> | ||
dtc -O dtb -o my-overlay.dtbo -@ my-overlay.dts | dtc -O dtb -o my-overlay.dtbo -@ my-overlay.dts | ||
</ | </syntaxhighlight> | ||
After you copy the new overlay file to the /boot directory, Jetson‑IO finds the overlay file and allows you to apply it | After you copy the new overlay file to the <code>/boot</code> directory, the Jetson‑IO tool finds the overlay file and allows you to apply it. If you use an incorrect compatible value the DT overlay will not be listed. | ||
< | <syntaxhighlight lang="bash"> | ||
sudo cp my-overlay.dtbo /boot | sudo cp my-overlay.dtbo /boot | ||
sudo /opt/nvidia/jetson-io/config-by-hardware.py -l | sudo /opt/nvidia/jetson-io/config-by-hardware.py -l | ||
</ | </syntaxhighlight> | ||
Configuration listed from Xavier NX | Configuration listed from Xavier NX: | ||
< | <syntaxhighlight lang="bash"> | ||
Configurations for the following hardware modules are available: | Configurations for the following hardware modules are available: | ||
1. Adafruit SPH0645LM4H | 1. Adafruit SPH0645LM4H | ||
Line 65: | Line 89: | ||
3. My Jetson Overlay example | 3. My Jetson Overlay example | ||
4. ReSpeaker 4 Mic Array | 4. ReSpeaker 4 Mic Array | ||
</ | </syntaxhighlight> | ||
Apply the device tree overlay created | Apply the device tree overlay created | ||
< | <syntaxhighlight lang="bash"> | ||
sudo /opt/nvidia/jetson-io/config-by-hardware.py -n "My Jetson Overlay example" | sudo /opt/nvidia/jetson-io/config-by-hardware.py -n "My Jetson Overlay example" | ||
</ | </syntaxhighlight> | ||
To apply the changes | To apply the changes, the board needs to be rebooted. After rebooting the board, you can read the new property defined in the device tree using the DT overlay. | ||
< | <syntaxhighlight lang="bash"> | ||
cat /proc/device-tree/my-custom-property | cat /proc/device-tree/my-custom-property | ||
</ | </syntaxhighlight> | ||
Output: | Output: | ||
< | <syntaxhighlight lang="bash"> | ||
This Is My Overlay | This Is My Overlay | ||
</ | </syntaxhighlight> | ||
===Remove overlay changes applied=== | ===Remove overlay changes applied=== | ||
The changes of the DT overlay are applied over the DT | The changes of the DT overlay are applied over the original DT and a new device tree is created. The name of the resulting device tree combines the original DT name and the overlay name. <code>/boot/kernel_tegra194-p3668-all-p3509-0000-my-jetson-overlay-example.dtb</code> | ||
To use the new DT, Jetson‑IO creates a new entry in <code>/boot/extlinux/extlinux.conf</code> | To use the new DT, Jetson‑IO creates a new entry in <code>/boot/extlinux/extlinux.conf</code> | ||
This is the new entry added | This is the new entry added that is added to the <code>/boot/extlinux/extlinux.conf</code> file when the overlay support has been added: | ||
< | <syntaxhighlight lang="conf"> | ||
LABEL My Jetson Overlay example | LABEL My Jetson Overlay example | ||
MENU LABEL My Jetson Overlay example | MENU LABEL My Jetson Overlay example | ||
Line 95: | Line 118: | ||
INITRD /boot/initrd | INITRD /boot/initrd | ||
APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyTCU0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0 | APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyTCU0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0 | ||
</ | </syntaxhighlight> | ||
To remove the new overlay support, simply delete the new entry from the <code>/boot/extlinux/extlinux.conf</code> file, and then reboot the board. After rebooting the board, you can confirm that the property defined in the DT overlay is no longer defined since now we are using the original device tree. | |||
< | <syntaxhighlight lang="bash"> | ||
cat /proc/device-tree/my-custom-property | cat /proc/device-tree/my-custom-property | ||
</ | </syntaxhighlight> | ||
Output: | Output: | ||
< | <syntaxhighlight lang="bash"> | ||
cat: /proc/device-tree/my-custom-property: No such file or directory | cat: /proc/device-tree/my-custom-property: No such file or directory | ||
</ | </syntaxhighlight> | ||
==Device tree overlay nodes== | |||
In a device tree overlay, symbols and labels that are not defined in the device tree overlay can not be used, since they are only defined in the original device tree. To manage these cases, the device tree overlay creates extra nodes to define symbols and labels that are not defined. | |||
This extra node can be created manually, or you can use the tag <code>/plugin/</code> and the device tree compiler dynamically resolves all the references to the device tree using the nodes below: | |||
*'''__overlay__''': contains the body of which is added to the target node. | |||
*'''__symbols__''': this node is only required for the target=<phandle> method, since it contains the information required to map from a phandle to a tree location. | |||
*'''__fixups__''': contains a list of properties that map the names of unresolved symbols to the lists of paths to cells within the fragments that need patching with the phandle of the target node. This section only is created if the device tree contains /plugin/ tag. | |||
*'''__local_fixups__:''' holds the locations of any references to labels that exist within the overlay. | |||
To show the device tree nodes work, we are going to create a device tree overlay to add a change to the GPIO configuration for Jetson TX2 Developer Kit. | |||
Create a file named tx2-uart-overlay.dts on the target platform with the following contents: | |||
<syntaxhighlight lang="C"> | |||
/dts-v1/; | |||
/plugin/; | |||
/ { | |||
overlay-name = "tx2_uart_overlay"; | |||
compatible = "nvidia,p2597-0000+p3310-1000"; | |||
fragment@0 { | |||
target = <&pinmux>; | |||
__overlay__ { | |||
pinctrl-names = "default"; | |||
pinctrl-0 = <&hdr40_pinmux>; | |||
hdr40_pinmux: header-40pin-pinmux { | |||
pin8 { | |||
nvidia,function = "uarta"; | |||
nvidia,pins = "uart1_tx_pt0"; | |||
nvidia,pull = <0x0>; | |||
nvidia,tristate = <0x0>; | |||
nvidia,enable-input = <0x0>; | |||
nvidia,lpdr = <0x0>; | |||
}; | |||
pin10 { | |||
nvidia,function = "uarta"; | |||
nvidia,pins = "uart1_rx_pt1"; | |||
nvidia,pull = <0x2>; | |||
nvidia,tristate = <0x1>; | |||
nvidia,enable-input = <0x01>; | |||
nvidia,lpdr = <0x0>; | |||
}; | |||
}; | |||
}; | |||
}; | |||
}; | |||
</syntaxhighlight> | |||
The device tree overlays contains: | |||
* label: <code>hdr40_pinmux</code> | |||
* Properties that map the names of unresolved symbols: <code>target = <&pinmux>;</code> | |||
* References to labels that exist within the overlay: <code>hdr40_pinmux</code> | |||
To see how the compiler dynamically resolves these labels and symbols, you can see the dtbo file generated. Compile the device tree and use <code>fdtdump</code> to see the device tree overlay content. | |||
<syntaxhighlight lang="bash"> | |||
dtc -O dtb -o tx2-uart-overlay.dtbo -@ tx2-uart-overlay.dts | |||
fdtdump tx2-uart-overlay.dtbo | |||
</syntaxhighlight> | |||
This is the <code>fdtdump</code> tool output, since the tag <code>/plugin/</code> was added to the overlay, the nodes <code>__symbols__</code>, <code>__fixups__</code> and <code>__local_fixups__</code> are created automatically. | |||
<syntaxhighlight lang="bash"> | |||
/dts-v1/; | |||
// magic: 0xd00dfeed | |||
// totalsize: 0x394 (916) | |||
// off_dt_struct: 0x38 | |||
// off_dt_strings: 0x2f0 | |||
// off_mem_rsvmap: 0x28 | |||
// version: 17 | |||
// last_comp_version: 16 | |||
// boot_cpuid_phys: 0x0 | |||
// size_dt_strings: 0xa4 | |||
// size_dt_struct: 0x2b8 | |||
/ { | |||
overlay-name = "d3_overlay_v4"; | |||
compatible = "nvidia,p2597-0000+p3310-1000"; | |||
fragment@0 { | |||
target = <0xffffffff>; | |||
__overlay__ { | |||
pinctrl-names = "default"; | |||
pinctrl-0 = <0x00000001>; | |||
header-40pin-pinmux { | |||
phandle = <0x00000001>; | |||
pin8 { | |||
nvidia,function = "uarta"; | |||
nvidia,pins = "uart1_tx_pt0"; | |||
nvidia,pull = <0x00000000>; | |||
nvidia,tristate = <0x00000000>; | |||
nvidia,enable-input = <0x00000000>; | |||
nvidia,lpdr = <0x00000000>; | |||
}; | |||
pin10 { | |||
nvidia,function = "uarta"; | |||
nvidia,pins = "uart1_rx_pt1"; | |||
nvidia,pull = <0x00000002>; | |||
nvidia,tristate = <0x00000001>; | |||
nvidia,enable-input = <0x00000001>; | |||
nvidia,lpdr = <0x00000000>; | |||
}; | |||
}; | |||
}; | |||
}; | |||
__symbols__ { | |||
hdr40_pinmux = "/fragment@0/__overlay__/header-40pin-pinmux"; | |||
}; | |||
__fixups__ { | |||
pinmux = "/fragment@0:target:0"; | |||
}; | |||
__local_fixups__ { | |||
fragment@0 { | |||
__overlay__ { | |||
pinctrl-0 = <0x00000000>; | |||
}; | |||
}; | |||
}; | |||
}; | |||
</syntaxhighlight> | |||
=== Notes=== | |||
{{Ambox | |||
|type=notice | |||
|small=left | |||
|issue='''Note:''' Make sure to add the parameter <code>-@</code> to dtc compilation line in order to enable the generation of symbols. | |||
|style=width:unset; | |||
}} | |||
{{Ambox | |||
|type=notice | |||
|small=left | |||
|issue='''Note:''' Add the tag <code>/plugin/</code> in the device tree overlay, if the tag is not added, the dtc reports the error: <code>Reference to a non-existent node or label</code>. | |||
|style=width:unset; | |||
}} | |||
{{Ambox | |||
|type=notice | |||
|small=left | |||
|issue='''Note:''' Is not possible to use as a target a label of a node that is created by the overlay but it doesn't exist in the original device tree.</code>. | |||
|style=width:unset; | |||
}} | |||
Example: Since <code>ub953_0</code> is created and used also as a target, This will produce an error when is applied the overlay. | |||
<syntaxhighlight lang="C"> | |||
fragment@0 { | |||
target = <&i2c_fpdlink>; // i2c2 = "i2c_fpdlink: i2c@0" | |||
__overlay__ { | |||
ub953_0: ub953@40 { | |||
compatible = "d3,ub953"; | |||
status = "disabled"; | |||
. . . | |||
}; | |||
}; | |||
}; | |||
fragment@1 { | |||
target = <&ub953_0>; | |||
__overlay__ { | |||
ov10640_0: ov10640@60 { | |||
status = "disabled"; | |||
compatible = "d3,ov10640"; | |||
. . . | |||
}; /* End __overlay__ */ | |||
}; /* End fragment@1 */ | |||
</syntaxhighlight> | |||
==Pre-process the DT overlay file with the C preprocessor (cpp)== | |||
If you want to include kernel definition since the device tree compiler doesn't support C definition syntax you have to use C Pre-process (cpp) to create a file that can be compiled by the Device Tree compiler. | |||
Example: This is the same previous device tree but using pinctrl tegra definitions to set GPIO configuration: | |||
<syntaxhighlight lang="C"> | |||
/dts-v1/; | |||
/plugin/; | |||
#include <dt-bindings/pinctrl/pinctrl-tegra.h> | |||
#define OVERLAY_VERSION "0.1" | |||
/ { | |||
overlay-name = "tx2_uart_overlay"; | |||
compatible = "nvidia,p2597-0000+p3310-1000"; | |||
fragment@0 { | |||
target-path = "/"; | |||
__overlay__ { | |||
d3,dts-overlay = __FILE__; | |||
d3,dts-overlay-version = OVERLAY_VERSION; | |||
}; | |||
}; | |||
fragment@1 { | |||
target = <&pinmux>; | |||
__overlay__ { | |||
pinctrl-names = "default"; | |||
pinctrl-0 = <&hdr40_pinmux>; | |||
hdr40_pinmux: header-40pin-pinmux { | |||
pin8 { | |||
nvidia,function = "uarta"; | |||
nvidia,pins = "uart1_tx_pt0"; | |||
nvidia,pull = <TEGRA_PIN_PULL_NONE>; | |||
nvidia,tristate = <TEGRA_PIN_DISABLE>; | |||
nvidia,enable-input = <TEGRA_PIN_DISABLE>; | |||
nvidia,lpdr = <TEGRA_PIN_DISABLE>; | |||
}; | |||
pin10 { | |||
nvidia,function = "uarta"; | |||
nvidia,pins = "uart1_rx_pt1"; | |||
nvidia,pull = <TEGRA_PIN_PULL_UP>; | |||
nvidia,tristate = <TEGRA_PIN_ENABLE>; | |||
nvidia,enable-input = <TEGRA_PIN_ENABLE>; | |||
nvidia,lpdr = <TEGRA_PIN_DISABLE>; | |||
}; | |||
}; | |||
}; | |||
}; | |||
}; | |||
</syntaxhighlight> | |||
Use the C Pre-process (cpp) to replace Constants in the device tree overlay | |||
<syntaxhighlight lang="bash"> | |||
cpp -nostdinc -I kernel/kernel-4.9/include/ -undef -x assembler-with-cpp tx2-uart-overlay.dts tx2-uart-overlay.dts.preprocessed | |||
</syntaxhighlight> | |||
Parameter description: | |||
* -nostdinc: Do not search the standard system directories for header files. | |||
* -undef: Do not predefine any system-specific or GCC-specific macros. | |||
* -x assembler-with-cpp: Allow #tags in the code (example: #address-cells) | |||
==Applying the overlay manually== | |||
The compiled overlay can be applied to an already existing device tree blob without the Jetson IO tool by using the <code>fdtoverlay</code> command. This is particularly useful in platforms that don't support the Jetson IO tool, such as the production version of the Jetson Nano (with EMMC). | |||
The ftdoverlay command takes the base device tree blob and applies the overlay on it, generating a new device tree. | |||
<pre> | |||
$ fdtoverlay --help | |||
Usage: apply a number of overlays to a base blob | |||
fdtoverlay <options> [<overlay.dtbo> [<overlay.dtbo>]] | |||
<type> s=string, i=int, u=unsigned, x=hex | |||
Optional modifier prefix: | |||
hh or b=byte, h=2 byte, l=4 byte (default) | |||
Options: -[i:o:vhV] | |||
-i, --input <arg> Input base DT blob | |||
-o, --output <arg> Output DT blob | |||
-v, --verbose Verbose messages | |||
-h, --help Print this help and exit | |||
-V, --version Print version and exit | |||
</pre> | |||
The usual use case looks like the following: | |||
<pre> | |||
fdtoverlay -i tegra210-p3448-0002-p3449-0000-b00.dtb -o tegra210-p3448-0002-p3449-0000-b00-extended.dtb my-overlay.dtbo | |||
</pre> | |||
In order for the new overlaid device tree to be used, a new entry in <code>/boot/extlinux/extlinux.conf</code> needs to be added; pointing to the proper kernel Image and DTB. As previously mentioned, the Jetson IO tool does this automatically. | |||
==See Also== | |||
* [https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/hw_setup_jetson_io.html#wwpID0E03B0HA NVIDIA device tree overlay] | |||
* [https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/hw_setup_jetson_io.html#wwpID0E0ZE0HA Running Jetson-IO] | |||
[https:// | * [https://www.kernel.org/doc/html/latest/devicetree/overlay-notes.html kernel.org devicetree overlay notes] | ||
{{ContactUs}} | |||
[[Category:Jetson]][[Category:JetsonNano]][[Category:JetsonTX2]][[Category: | [[Category:Jetson]][[Category:NVIDIA Xavier]][[Category:JetsonNano]][[Category:JetsonTX2]][[Category:JetsonXavierNX]][[Category:NVIDIA Jetson Orin]] |
Latest revision as of 20:42, 15 May 2024
|
Introduction to Device Tree Overlay
This wiki is intended to be used as a reference if you want to create a Device Tree (DT) overlay for a custom hardware module. DT overlays are used to configure various hardware devices that may be attached to the system.
NVIDIA Jetson kernels use a device tree to describe the hardware present in the NVIDIA Jetson board. You can use Jetson‑IO tool to support a custom hardware module by creating a device tree overlay for the hardware module to allow optional external hardware to be described and configured.
Create a Device Tree Overlay
Jetson‑IO
NVIDIA provides the Jetson Expansion Header Tool (also known as Jetson‑IO). It is a Python script that runs on a Jetson developer kit and lets you apply a DT overlay configuration through a graphic user interface. Jetson‑IO finds the overlay file and allows you to apply it.
You can use Jetson‑IO to perform 2 tasks:
- Configure header pins manually: displays the expansion header configuration screen, which lets you specify which functions to enable on the header. The application creates the DT overlay and it is applied.
- Configure for compatible hardware: displays the compatible hardware screen, which lets you select from a list of configurations for hardware modules that can be attached to the header. You can use a pre-created DT overlay for certain hardware or create your custom DT overlay and select it from the list.
This guide uses the second option to apply a custom DT overlay.
Device Tree Overlay structure
A device tree overlay for a hardware module must define the property:
overlay-name
: specifies a name for the hardware module.jetson-header-name
: specifies the expansion header to which the hardware module is associated; it must specify one of the values described in the table jetson-header-name property values.compatible
: indicates which combination of Jetson module and carrier board the overlay supports; t must specify one or more of the values described in the table compatible property values.fragment
: a DT overlay comprises a number of fragments, each of them indicates child nodes and the target.target
: phandle target of the overlay.target-path
: target path of the overlay.
Creating a Simple Device Tree Overlay
To create a simple device tree overlay to add a new custom property for Jetson Xavier NX Developer Kit and attach it to the 40‑pin expansion header, create a file named my-overlay.dts
on the target platform with the following contents:
/dts-v1/; / { overlay-name = "My Jetson Overlay Example"; jetson-header-name = "Jetson 40pin Header"; compatible = "nvidia,p3509-0000+p3668-0001"; fragment@0 { target-path = "/"; __overlay__ { my-custom-property = "This Is My Overlay"; }; }; };
Enter the following command to compile the DTS source file into an overlay file:
dtc -O dtb -o my-overlay.dtbo -@ my-overlay.dts
After you copy the new overlay file to the /boot
directory, the Jetson‑IO tool finds the overlay file and allows you to apply it. If you use an incorrect compatible value the DT overlay will not be listed.
sudo cp my-overlay.dtbo /boot sudo /opt/nvidia/jetson-io/config-by-hardware.py -l
Configuration listed from Xavier NX:
Configurations for the following hardware modules are available: 1. Adafruit SPH0645LM4H 2. FE-PI Audio V1 and Z V2 3. My Jetson Overlay example 4. ReSpeaker 4 Mic Array
Apply the device tree overlay created
sudo /opt/nvidia/jetson-io/config-by-hardware.py -n "My Jetson Overlay example"
To apply the changes, the board needs to be rebooted. After rebooting the board, you can read the new property defined in the device tree using the DT overlay.
cat /proc/device-tree/my-custom-property
Output:
This Is My Overlay
Remove overlay changes applied
The changes of the DT overlay are applied over the original DT and a new device tree is created. The name of the resulting device tree combines the original DT name and the overlay name. /boot/kernel_tegra194-p3668-all-p3509-0000-my-jetson-overlay-example.dtb
To use the new DT, Jetson‑IO creates a new entry in /boot/extlinux/extlinux.conf
This is the new entry added that is added to the /boot/extlinux/extlinux.conf
file when the overlay support has been added:
LABEL My Jetson Overlay example MENU LABEL My Jetson Overlay example LINUX /boot/Image FDT /boot/kernel_tegra194-p3668-all-p3509-0000-my-jetson-overlay-example.dtb INITRD /boot/initrd APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyTCU0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0
To remove the new overlay support, simply delete the new entry from the /boot/extlinux/extlinux.conf
file, and then reboot the board. After rebooting the board, you can confirm that the property defined in the DT overlay is no longer defined since now we are using the original device tree.
cat /proc/device-tree/my-custom-property
Output:
cat: /proc/device-tree/my-custom-property: No such file or directory
Device tree overlay nodes
In a device tree overlay, symbols and labels that are not defined in the device tree overlay can not be used, since they are only defined in the original device tree. To manage these cases, the device tree overlay creates extra nodes to define symbols and labels that are not defined.
This extra node can be created manually, or you can use the tag /plugin/
and the device tree compiler dynamically resolves all the references to the device tree using the nodes below:
- __overlay__: contains the body of which is added to the target node.
- __symbols__: this node is only required for the target=<phandle> method, since it contains the information required to map from a phandle to a tree location.
- __fixups__: contains a list of properties that map the names of unresolved symbols to the lists of paths to cells within the fragments that need patching with the phandle of the target node. This section only is created if the device tree contains /plugin/ tag.
- __local_fixups__: holds the locations of any references to labels that exist within the overlay.
To show the device tree nodes work, we are going to create a device tree overlay to add a change to the GPIO configuration for Jetson TX2 Developer Kit.
Create a file named tx2-uart-overlay.dts on the target platform with the following contents:
/dts-v1/; /plugin/; / { overlay-name = "tx2_uart_overlay"; compatible = "nvidia,p2597-0000+p3310-1000"; fragment@0 { target = <&pinmux>; __overlay__ { pinctrl-names = "default"; pinctrl-0 = <&hdr40_pinmux>; hdr40_pinmux: header-40pin-pinmux { pin8 { nvidia,function = "uarta"; nvidia,pins = "uart1_tx_pt0"; nvidia,pull = <0x0>; nvidia,tristate = <0x0>; nvidia,enable-input = <0x0>; nvidia,lpdr = <0x0>; }; pin10 { nvidia,function = "uarta"; nvidia,pins = "uart1_rx_pt1"; nvidia,pull = <0x2>; nvidia,tristate = <0x1>; nvidia,enable-input = <0x01>; nvidia,lpdr = <0x0>; }; }; }; }; };
The device tree overlays contains:
- label:
hdr40_pinmux
- Properties that map the names of unresolved symbols:
target = <&pinmux>;
- References to labels that exist within the overlay:
hdr40_pinmux
To see how the compiler dynamically resolves these labels and symbols, you can see the dtbo file generated. Compile the device tree and use fdtdump
to see the device tree overlay content.
dtc -O dtb -o tx2-uart-overlay.dtbo -@ tx2-uart-overlay.dts fdtdump tx2-uart-overlay.dtbo
This is the fdtdump
tool output, since the tag /plugin/
was added to the overlay, the nodes __symbols__
, __fixups__
and __local_fixups__
are created automatically.
/dts-v1/; // magic: 0xd00dfeed // totalsize: 0x394 (916) // off_dt_struct: 0x38 // off_dt_strings: 0x2f0 // off_mem_rsvmap: 0x28 // version: 17 // last_comp_version: 16 // boot_cpuid_phys: 0x0 // size_dt_strings: 0xa4 // size_dt_struct: 0x2b8 / { overlay-name = "d3_overlay_v4"; compatible = "nvidia,p2597-0000+p3310-1000"; fragment@0 { target = <0xffffffff>; __overlay__ { pinctrl-names = "default"; pinctrl-0 = <0x00000001>; header-40pin-pinmux { phandle = <0x00000001>; pin8 { nvidia,function = "uarta"; nvidia,pins = "uart1_tx_pt0"; nvidia,pull = <0x00000000>; nvidia,tristate = <0x00000000>; nvidia,enable-input = <0x00000000>; nvidia,lpdr = <0x00000000>; }; pin10 { nvidia,function = "uarta"; nvidia,pins = "uart1_rx_pt1"; nvidia,pull = <0x00000002>; nvidia,tristate = <0x00000001>; nvidia,enable-input = <0x00000001>; nvidia,lpdr = <0x00000000>; }; }; }; }; __symbols__ { hdr40_pinmux = "/fragment@0/__overlay__/header-40pin-pinmux"; }; __fixups__ { pinmux = "/fragment@0:target:0"; }; __local_fixups__ { fragment@0 { __overlay__ { pinctrl-0 = <0x00000000>; }; }; }; };
Notes
Note: Make sure to add the parameter -@ to dtc compilation line in order to enable the generation of symbols. |
Note: Add the tag /plugin/ in the device tree overlay, if the tag is not added, the dtc reports the error: Reference to a non-existent node or label . |
Note: Is not possible to use as a target a label of a node that is created by the overlay but it doesn't exist in the original device tree.. |
Example: Since ub953_0
is created and used also as a target, This will produce an error when is applied the overlay.
fragment@0 { target = <&i2c_fpdlink>; // i2c2 = "i2c_fpdlink: i2c@0" __overlay__ { ub953_0: ub953@40 { compatible = "d3,ub953"; status = "disabled"; . . . }; }; }; fragment@1 { target = <&ub953_0>; __overlay__ { ov10640_0: ov10640@60 { status = "disabled"; compatible = "d3,ov10640"; . . . }; /* End __overlay__ */ }; /* End fragment@1 */
Pre-process the DT overlay file with the C preprocessor (cpp)
If you want to include kernel definition since the device tree compiler doesn't support C definition syntax you have to use C Pre-process (cpp) to create a file that can be compiled by the Device Tree compiler.
Example: This is the same previous device tree but using pinctrl tegra definitions to set GPIO configuration:
/dts-v1/; /plugin/; #include <dt-bindings/pinctrl/pinctrl-tegra.h> #define OVERLAY_VERSION "0.1" / { overlay-name = "tx2_uart_overlay"; compatible = "nvidia,p2597-0000+p3310-1000"; fragment@0 { target-path = "/"; __overlay__ { d3,dts-overlay = __FILE__; d3,dts-overlay-version = OVERLAY_VERSION; }; }; fragment@1 { target = <&pinmux>; __overlay__ { pinctrl-names = "default"; pinctrl-0 = <&hdr40_pinmux>; hdr40_pinmux: header-40pin-pinmux { pin8 { nvidia,function = "uarta"; nvidia,pins = "uart1_tx_pt0"; nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_DISABLE>; nvidia,lpdr = <TEGRA_PIN_DISABLE>; }; pin10 { nvidia,function = "uarta"; nvidia,pins = "uart1_rx_pt1"; nvidia,pull = <TEGRA_PIN_PULL_UP>; nvidia,tristate = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,lpdr = <TEGRA_PIN_DISABLE>; }; }; }; }; };
Use the C Pre-process (cpp) to replace Constants in the device tree overlay
cpp -nostdinc -I kernel/kernel-4.9/include/ -undef -x assembler-with-cpp tx2-uart-overlay.dts tx2-uart-overlay.dts.preprocessed
Parameter description:
- -nostdinc: Do not search the standard system directories for header files.
- -undef: Do not predefine any system-specific or GCC-specific macros.
- -x assembler-with-cpp: Allow #tags in the code (example: #address-cells)
Applying the overlay manually
The compiled overlay can be applied to an already existing device tree blob without the Jetson IO tool by using the fdtoverlay
command. This is particularly useful in platforms that don't support the Jetson IO tool, such as the production version of the Jetson Nano (with EMMC).
The ftdoverlay command takes the base device tree blob and applies the overlay on it, generating a new device tree.
$ fdtoverlay --help Usage: apply a number of overlays to a base blob fdtoverlay <options> [<overlay.dtbo> [<overlay.dtbo>]] <type> s=string, i=int, u=unsigned, x=hex Optional modifier prefix: hh or b=byte, h=2 byte, l=4 byte (default) Options: -[i:o:vhV] -i, --input <arg> Input base DT blob -o, --output <arg> Output DT blob -v, --verbose Verbose messages -h, --help Print this help and exit -V, --version Print version and exit
The usual use case looks like the following:
fdtoverlay -i tegra210-p3448-0002-p3449-0000-b00.dtb -o tegra210-p3448-0002-p3449-0000-b00-extended.dtb my-overlay.dtbo
In order for the new overlaid device tree to be used, a new entry in /boot/extlinux/extlinux.conf
needs to be added; pointing to the proper kernel Image and DTB. As previously mentioned, the Jetson IO tool does this automatically.
See Also
RidgeRun Resources | |||||
Contact Us
|