How to program Linux .dts device tree files?
Take a look at the dts of the board which most closely resembles your dev-board. Use that as a reference and make changes to the dts according to the differences between the reference board and your dev-board.
Also checkout the following :
- Device-tree Documentation project at eLinux (has a vast collection of links to start reading).
- Series of articles on the basics of device tree.
- Walkthrough of migrating to device-tree.
Minimal reg
+ interrupt
example with QEMU virtual device
Our example will add the following device tree node to the versatilepb
device tree which QEMU will use due to -M versatilepb
:
lkmc_platform_device@101e9000 {
compatible = "lkmc_platform_device";
reg = <0x101e9000 0x1000>;
interrupts = <18>;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&pclk>;
clock-names = "apb_pclk";
lkmc-asdf = <0x12345678>;
};
Then, by using a Linux kernel module to interact with the device, we will test the following DTS features:
- registers addresses
- IRQs
- read custom properties from the driver
These are the main components of the example:
- Linux versatile
.dts
patch on Linux forkreg
andinterrupt
match numbers hard-coded in the QEMU versatile machine (which represents the SoC)compatible
matches theplatform_driver.name
in the kernel module, and informs the kernel which module will handle this device- we also pass a custom property to the driver:
lkmc-asdf = <0x12345678>;
, which is read withof_property_read_u32
- the device tree is passed to QEMU's firmware with the
-dtb
argument
- QEMU fork:
- device that reads a register and generates interrupts
- insert device into
-M versatilepb
- kernel module Writes to memory on probe to test things out, which also generates an IRQ.
Device trees have many more features that we haven't covered, but this example should get you started, and easily allow you to play around with any new features that come up.
Further resources:
- indispensable elinux tutorial: http://elinux.org/Device_Tree_Usage
- play around with
dtc
for purely syntaxical questions. E.g., it shows how nodes are simply merged by path: https://unix.stackexchange.com/a/375923/32558 - https://unix.stackexchange.com/questions/118683/what-is-a-device-tree-and-a-device-tree-blob
Lets take a example and I will explain each one of them as below
auart0: serial@8006a000 {
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x8006a000 0x2000>;
interrupts = <112>;
dmas = <&dma_apbx 8>, <&dma_apbx 9>;
dma-names = "rx", "tx";
};
Required properties:
- compatible : Should be "fsl,-auart". The supported SoCs include
imx23 and imx28.
- reg : Address and length of the register set for the device
- interrupts : Should contain the auart interrupt numbers
- dmas: DMA specifier, consisting of a phandle to DMA controller node
and AUART DMA channel ID.
- dma-names: "rx" for RX channel, "tx" for TX channel.
Note: Each auart port should have an alias correctly numbered in "aliases"
node.
For more advance properties, please go to this link, it is very useful
Device Tree Explanation
Hope it helps!