Products > Embedded Computing

Any Linux device tree syntax experts here?

(1/2) > >>

HwAoRrDk:
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: --- 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
};

--- End code ---

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: --- shutdown_button: shutdown_button@3 {

--- End code ---

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: --- button: shutdown {
label = "shutdown";
linux,code = <116>; // KEY_POWER
gpios = <&gpio 3 1>;
debounce-interval = <100>; // ms
};

--- End code ---

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: --- __overrides__ {
// Allow overriding the GPIO number.
gpio_pin = <&button>,"gpios:4",
   <&shutdown_button>,"reg:0",
   <&pin_state>,"reg:0",
           <&pin_state>,"brcm,pins:0";

--- End code ---

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?

Nominal Animal:

--- Quote from: HwAoRrDk on August 11, 2022, 03:08:36 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?
--- End quote ---
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.


--- Quote from: HwAoRrDk on August 11, 2022, 03:08:36 pm ---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.
--- End quote ---
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.)


--- Quote from: HwAoRrDk on August 11, 2022, 03:08:36 pm ---
--- Code: --- __overrides__ {
// Allow overriding the GPIO number.
gpio_pin = <&button>,"gpios:4",
   <&shutdown_button>,"reg:0",
   <&pin_state>,"reg:0",
           <&pin_state>,"brcm,pins:0";

--- End code ---

--- End quote ---
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.

HwAoRrDk:
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.


--- Quote from: Nominal Animal on August 11, 2022, 07:19:28 pm ---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.

--- End quote ---

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.


--- Quote from: Nominal Animal on August 11, 2022, 07:19:28 pm ---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.

--- End quote ---

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?


--- Quote from: Nominal Animal on August 11, 2022, 07:19:28 pm ---(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.)

--- End quote ---

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


--- Quote from: Nominal Animal on August 11, 2022, 07:19:28 pm ---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.

--- End quote ---

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'?

Nominal Animal:

--- Quote from: HwAoRrDk 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:

--- End quote ---
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.


--- Quote from: HwAoRrDk on August 11, 2022, 08:46:05 pm ---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.
--- End quote ---
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.


--- Quote from: HwAoRrDk on August 11, 2022, 08:46:05 pm ---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.
--- End quote ---
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.


--- Quote from: HwAoRrDk on August 11, 2022, 08:46:05 pm ---WTF does "OF" stand for?
--- End quote ---
Open Firmware.  That's where the entire idea of a device tree comes from.


--- Quote from: HwAoRrDk on August 11, 2022, 08:46:05 pm ---Can I actually use the constant symbol GPIO_ACTIVE_LOW instead, or does that depend on some include somewhere?

--- End quote ---
They are available if you #include <dt-bindings/gpio/gpio.h>.


--- Quote from: HwAoRrDk on August 11, 2022, 08:46:05 pm ---Thank you for being so mindful of my physiological and mental wellbeing. ::) ;D
--- End quote ---
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.


--- Quote from: HwAoRrDk on August 11, 2022, 08:46:05 pm ---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'?

--- End quote ---
"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.

HwAoRrDk:

--- Quote from: Nominal Animal on August 12, 2022, 12:40:22 am ---They are available if you #include <dt-bindings/gpio/gpio.h>.

--- End quote ---

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


--- Quote from: Nominal Animal on August 12, 2022, 12:40:22 am ---"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.)

--- End quote ---

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.


--- Quote from: Nominal Animal on August 12, 2022, 12:40:22 am ---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.

--- End quote ---

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.

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version