Author Topic: Any Linux device tree syntax experts here?  (Read 1208 times)

0 Members and 1 Guest are viewing this topic.

Offline HwAoRrDk

  • Super Contributor
  • ***
  • Posts: 1096
  • Country: gb
Any Linux device tree syntax experts here?
« on: August 11, 2022, 03:08:36 pm »
For a Raspberry Pi, I'm trying to customise a standard device tree overlay, gpio-shutdown-overlay.dts, that enables you to use a GPIO pin as a shutdown button. What I want to do is change the GPIO pin that it uses.

Yes, I know you can specify parameters to this overlay to change the GPIO pin. But for reasons I won't bore you with, I can't do that, so instead I want to compile a custom .dtbo that has the desired GPIO pin as the hard-coded default.

But I'm struggling to understand the syntax of device tree files, and I'm not sure exactly what parts do or do not need to be changed. Is there anyone here who is familiar with this stuff that can advise?

I won't quote the whole .dts file - it's linked above - just excerpts from areas I have questions about:

Code: [Select]
pin_state: shutdown_button_pins@3 {
brcm,pins = <3>; // gpio number
brcm,function = <0>; // 0 = input, 1 = output
brcm,pull = <2>; // 0 = none, 1 = pull down, 2 = pull up
};

Here, the GPIO number is obvious - I change the <3>. But the shutdown_button_pins@3 is confusing me. Is it also referencing the GPIO number? Do I need to change the '@3' here too? Or is it referencing the number of elements within the following block? I can't find out what this '@' syntax is supposed to be.

Code: [Select]
shutdown_button: shutdown_button@3 {

Again, same as above. But because this block has more than 3 elements contained within, I assume this '@3' isn't actually a count, but something else. :-// I also note it's not the same name as above either (no '_pins' suffix).

Code: [Select]
button: shutdown {
label = "shutdown";
linux,code = <116>; // KEY_POWER
gpios = <&gpio 3 1>;
debounce-interval = <100>; // ms
};

It seems obvious what to change here, the '3' in the line containing <&gpio 3 1>. But what is the '1' part? There's only supposed to be a single GPIO pin in play here.

Code: [Select]
__overrides__ {
// Allow overriding the GPIO number.
gpio_pin = <&button>,"gpios:4",
   <&shutdown_button>,"reg:0",
   <&pin_state>,"reg:0",
           <&pin_state>,"brcm,pins:0";

What is the relevance here of "gpios:4"? That's obviously not the GPIO number, so why is it '4'? Also, if I don't want any parameters at all for my overlay, can I just omit the whole __overrides__ block?
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 4726
  • Country: fi
    • My home page and email address
Re: Any Linux device tree syntax experts here?
« Reply #1 on: August 11, 2022, 07:19:28 pm »
But I'm struggling to understand the syntax of device tree files, and I'm not sure exactly what parts do or do not need to be changed. Is there anyone here who is familiar with this stuff that can advise?
Why not head over to the Device Tree Specifications, and learn it for yourself instead?

In particular, in devicetree-specification-v0.3.pdf, section 2.2.1 Node Names, on page 7 explains that nodes are named using node-name@unit-address, with the unit-address part match the first reg property of the node; here, the GPIO number.  So, if you change the default to say 5, you need to change the @3 to @5 also.

It seems obvious what to change here, the '3' in the line containing <&gpio 3 1>. But what is the '1' part? There's only supposed to be a single GPIO pin in play here.
It is equivalent to GPIO_ACTIVE_LOW.  (0 corresponds to GPIO_ACTIVE_HIGH).

The button: buttonname { gpios: <&controller pin state>; } syntax is described in the Linux Kernel Documentation, GPIO Device Tree section.  Essentially, that snippet defines the data that the actual Kernel driver uses to determine which GPIO pin it should monitor or link to.  (I could find the actual snippet in the kernel using Bootlin Elixir Cross Referencer, but I'm too lazy; sorry  :-[.)

In other words, that snippet tells the actual kernel driver that it should monitor pin 3 in gpio controller, active low.  (Which makes sense, because earlier the snippet defined internal pull-up resistors.  I do the same in my own microcontroller projects, as then my buttons only short the pin to ground.  Safer that way, at least for someone with my sausagey fingers.)

If you had bothered to open the link in the comment, https://www.kernel.org/doc/Documentation/devicetree/bindings/input/gpio-keys.txt, you would already know this.  (Yes, I do get to be snarky while being helpful at the same time.  The mix of positive and negative reinforcement is supposed to strengthen your will to find out more, spend a bit more effort, before asking others; and to give you a serotonin boost when do learn –– it is your body telling you win that way.)

Code: [Select]
__overrides__ {
// Allow overriding the GPIO number.
gpio_pin = <&button>,"gpios:4",
   <&shutdown_button>,"reg:0",
   <&pin_state>,"reg:0",
           <&pin_state>,"brcm,pins:0";
These are parameter declarations.  They form a list of pairs
    <&label>, "property.offset8"
    <&label>, "property;offset16"
    <&label>, "property:offset32"
    <&label>, "property#offset64"

It describes the parameters that can be used to override specific values in the DT snippet.  It does not describe what those values are, but where.
 

Offline HwAoRrDk

  • Super Contributor
  • ***
  • Posts: 1096
  • Country: gb
Re: Any Linux device tree syntax experts here?
« Reply #2 on: August 11, 2022, 08:46:05 pm »
Thanks for your help. My mind has been running in circles trying to make sense of this stuff today. :scared:

I had actually started reading some of the links in the .dts file comments, as well as the Raspberry Pi docs, which covers a lot of the stuff mentioned elsewhere.

In particular, in devicetree-specification-v0.3.pdf, section 2.2.1 Node Names, on page 7 explains that nodes are named using node-name@unit-address, with the unit-address part match the first reg property of the node; here, the GPIO number.  So, if you change the default to say 5, you need to change the @3 to @5 also.

Okay, thanks for confirming. Since posting I did come across a description of the '@' syntax as being for unit-address, but it's hard to know whether things that have the same number are correlated, or it's just coincidence but otherwise unrelated, or what.

This is part of the larger confusion I'm having - coming at this as a noob, it's so difficult to understand what are names/labels/IDs that have been devised and specified only within the .dts file, and what are references to other pre-existing things elsewhere.

It is equivalent to GPIO_ACTIVE_LOW.  (0 corresponds to GPIO_ACTIVE_HIGH).

The button: buttonname { gpios: <&controller pin state>; } syntax is described in the Linux Kernel Documentation, GPIO Device Tree section. ...

If you had bothered to open the link in the comment, https://www.kernel.org/doc/Documentation/devicetree/bindings/input/gpio-keys.txt, you would already know this.

Actually, that document doesn't explain the <&gpio ...> specifier - it only says "OF device-tree gpio specification" (WTF does "OF" stand for?). :P But I have now found yet another Linux kernel doc that does: https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt. It seems the state 'cell' is actually a bit-field, of which active-high/low is only 1 flag. Seems there is others for push-pull, open-drain, etc. but I assume it's okay to leave them all zero (as they'll be when specifying a 0/1 decimal value for state).

Can I actually use the constant symbol GPIO_ACTIVE_LOW instead, or does that depend on some include somewhere?

(Yes, I do get to be snarky while being helpful at the same time.  The mix of positive and negative reinforcement is supposed to strengthen your will to find out more, spend a bit more effort, before asking others; and to give you a serotonin boost when do learn –– it is your body telling you win that way.)

Thank you for being so mindful of my physiological and mental wellbeing. ::) ;D

These are parameter declarations.  They form a list of pairs
    <&label>, "property.offset8"
    <&label>, "property;offset16"
    <&label>, "property:offset32"
    <&label>, "property#offset64"

It describes the parameters that can be used to override specific values in the DT snippet.  It does not describe what those values are, but where.

Okay, so ':4' (or ':0') is an offset... relative to what exactly? I assume that <&button> refers to the same label declared on line 54, and similar for others (<&shutdown_button>, line 38; <&pin_state>, line 27). But the gpios element of the button block only has 3 elements, so how can the offset be 4?! And I still don't understand what an offset of zero into 'reg' is? What is 'reg'?
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 4726
  • Country: fi
    • My home page and email address
Re: Any Linux device tree syntax experts here?
« Reply #3 on: August 12, 2022, 12:40:22 am »
Thanks for your help. My mind has been running in circles trying to make sense of this stuff today. :scared:
It's doubly hard when you need to do a real-world change, and would rather go on with that than try reading "documentation" often written by humans who perhaps would be better doing something else but do mean well.
At least, it is for me.

Okay, thanks for confirming. Since posting I did come across a description of the '@' syntax as being for unit-address, but it's hard to know whether things that have the same number are correlated, or it's just coincidence but otherwise unrelated, or what.
I suspect the original intent is to make sure that node identifiers are unique; that two identifiers, if they are the same, always and for sure refer to the same node.  I could be wrong, though.

This is part of the larger confusion I'm having - coming at this as a noob, it's so difficult to understand what are names/labels/IDs that have been devised and specified only within the .dts file, and what are references to other pre-existing things elsewhere.
I can sympathise.  When trying to unravel this kind of stuff, I look for real-world examples I can test and investigate, and compare against the descriptions.  It is slow going, unless you have a virtual machine (since those can boot in fractions of a second).  Even then, it takes time.

WTF does "OF" stand for?
Open Firmware.  That's where the entire idea of a device tree comes from.

Can I actually use the constant symbol GPIO_ACTIVE_LOW instead, or does that depend on some include somewhere?
They are available if you #include <dt-bindings/gpio/gpio.h>.

Thank you for being so mindful of my physiological and mental wellbeing. ::) ;D
I thought it would be useful to know there was a positive purpose behind the varying tone.

Bah, get off my lawn you irreverent whippersnapper.  It's time for my nap anyway.

Okay, so ':4' (or ':0') is an offset... relative to what exactly? I assume that <&button> refers to the same label declared on line 54, and similar for others (<&shutdown_button>, line 38; <&pin_state>, line 27). But the gpios element of the button block only has 3 elements, so how can the offset be 4?! And I still don't understand what an offset of zero into 'reg' is? What is 'reg'?
"gpios:4" refers to the fifth byte in the gpios property.  The offset is always in bytes, the delimiter defines the size of the target.  (I don't get why RPi uses "gpios:4" here either, but a lot of their code makes little sense anyway.)

reg is a property that can override the unit-address part, or refer to the unit-address part when used in relation to some node.
That is, <&pin_state>,"reg:0" refers to the unit-address part of the pin_state node in the same section.

There are multiple entries in this list because when one changes the pin number, it has to be changed at multiple places.  This overlay snippet lists those places.
 

Offline HwAoRrDk

  • Super Contributor
  • ***
  • Posts: 1096
  • Country: gb
Re: Any Linux device tree syntax experts here?
« Reply #4 on: August 12, 2022, 01:24:06 pm »
They are available if you #include <dt-bindings/gpio/gpio.h>.

But that's a C thing. I was talking about DTS /include/ statements, or whatever.

"gpios:4" refers to the fifth byte in the gpios property.  The offset is always in bytes, the delimiter defines the size of the target.  (I don't get why RPi uses "gpios:4" here either, but a lot of their code makes little sense anyway.)

That seems... crazy. That means you have to have intimate knowledge of the target property value. That'd be like in C having to access struct members by byte offset rather than name - you'd need to know how the compiler had organised that particular struct. :o

So, if I am interpreting things correctly, "gpios:4" is saying "access from the 5th byte onwards (at offset 4) of the 'gpios' property and interpret it as a 32-bit integer", regardless of whatever structure that property may have. I guess that makes sense for <&gpio 3 1> if it is a 'cells' array consisting of 32-bit values. A byte offset of 4 will indeed access the second 'cell', which is the pin number.

reg is a property that can override the unit-address part, or refer to the unit-address part when used in relation to some node.
That is, <&pin_state>,"reg:0" refers to the unit-address part of the pin_state node in the same section.

Ah, I see now. Thanks.

I wonder why it's called 'reg'. That makes me think 'register', but I doubt we're dealing with hardware registers here.

Edit: After reading the 'Node Names' section of https://elinux.org/Device_Tree_Usage, I get it now - 'reg' is an implied property that each (every?) node with a unit-address has that is equal to the address, even when not explicitly specified.
« Last Edit: August 12, 2022, 01:34:35 pm by HwAoRrDk »
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 4726
  • Country: fi
    • My home page and email address
Re: Any Linux device tree syntax experts here?
« Reply #5 on: August 13, 2022, 12:36:59 am »
But that's a C thing. I was talking about DTS /include/ statements, or whatever.
Eh? At least the ones in the Linux kernel tree support #include and #define.  Even the one for Raspberry Pi Model 4 B uses them.

So, if I am interpreting things correctly, "gpios:4" is saying "access from the 5th byte onwards (at offset 4) of the 'gpios' property and interpret it as a 32-bit integer
Yes, I agree.  Remember, this entire __overrides__ facililty seems to only be used with RPis, so having some Broadcom inanity in them is to be expected.

I do believe the idea is that the gpios property consists of an unsigned 32-bit identifier (referring to the gpio node), followed by two 32-bit unsigned 32-byte values: the pin number, and the active state identifier.  Thus, <&button>,"gpios:4" refers to the pin number in the gpios property of the button node, and <&button>,"gpios:8" refers to the active state identifier in the gpios property of the button node.  This seems to match the DTS in question (linked to in your first post).

Edit: After reading the 'Node Names' section of https://elinux.org/Device_Tree_Usage, I get it now - 'reg' is an implied property that each (every?) node with a unit-address has that is equal to the address, even when not explicitly specified.
Yes, except DT does not make any distinction between implied and explicit properties.

Anyway, the eLinux page and linux kernel docs explain things much better than I can; I'm definitely not a Linux device tree syntax expert.

Probably should have not posted, but I just couldn't help myself.  :'(
 

Offline HwAoRrDk

  • Super Contributor
  • ***
  • Posts: 1096
  • Country: gb
Re: Any Linux device tree syntax experts here?
« Reply #6 on: August 13, 2022, 12:58:07 pm »
Eh? At least the ones in the Linux kernel tree support #include and #define.  Even the one for Raspberry Pi Model 4 B uses them.

Huh. So they do. So why does /include/ exist then?

Is the device tree compiler just some bastardisation of the C pre-processor, which is translating down to C code and compiling, or something like that? :o
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 4726
  • Country: fi
    • My home page and email address
Re: Any Linux device tree syntax experts here?
« Reply #7 on: August 13, 2022, 01:42:49 pm »
Eh? At least the ones in the Linux kernel tree support #include and #define.  Even the one for Raspberry Pi Model 4 B uses them.

Huh. So they do. So why does /include/ exist then?
Actually, it's the other way around.  Linux dts files use #include, because they're built using the kernel build machinery.
The dtc in Linux kernel supports both.

Is the device tree compiler just some bastardisation of the C pre-processor, which is translating down to C code and compiling, or something like that? :o
No.  It's a proper compiler built using flex and bison.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf