Adding to the device tree with overlays - Zephyr

I'm still new to Zephyr, so this could be an easy question that I'm googling poorly - if so, sorry in advance.  I just wanted to add an extra LED, led4, to the existing nrf9160dk device tree.  I tried adding it directly to the device tree like so

...

leds {
	compatible = "gpio-leds";
	led0: led_0 {
		gpios = <&gpio0 2 0>;
		label = "Green LED 1";
	};
	led1: led_1 {
		gpios = <&gpio0 3 0>;
		label = "Green LED 2";
	};
	led2: led_2 {
		gpios = <&gpio0 4 0>;
		label = "Green LED 3";
	};
	led3: led_3 {
		gpios = <&gpio0 5 0>;
		label = "Green LED 4";
	};
	led4: led_4 {
		gpios = <&gpio0 10 0>;
		label = "My red LED";
	};
};

...

aliases {
	led0 = &led0;
	led1 = &led1;
	led2 = &led2;
	led3 = &led3;
	led4 = &led4;
	pwm-led0 = &pwm_led0;
	sw0 = &button2;
	
...

but I get errors when trying to use DT_ALIAS(led4) telling me that there is no such device (error: 'DT_N_ALIAS_led4_P_gpios_IDX_0_VAL_pin' undeclared). Everything works fine for LEDs 0 - 3.

I figure that there is some juju with the using the dts files themselves (some command that you have to run in west to rebuild device trees?) so that overlays are preferred for this sort of thing.  So instead, I added the data in an overlay like this

/ {
	leds {
		led4: led_4 {
			gpios = <&gpio0 10 0>;
			label = "My red LED";
		};
	};

	aliases {
		led4 = &led4;
    };
};

with no change to the result.  I am fairly sure that I'm just missing the part of the documentation that tells you how to extend an existing device tree or overlay to accommodate new functionality, so if someone could point me in that direction it would be very helpful!

*EDIT:* I should add that I also added the overlay to CMakeLists.txt and I can see that it looks in the overlay, so I'm pretty confident that it is getting seen during build.

  • Hello SmallerPond,

    Regarding your situation with a build time, device tree source (DTS) error when adding an LED to your targeted board and project, your DTS syntax looks correct in the first and longer code excerpt.  You do not mention which board you are programming, whether it is an off shelf dev kit like Thingy91 or a custom board.

    As an upfront comment, changes to a project's device tree files are pick up automatically by `west` based builds.  Not sure of most of the mechanisms for this, but when you name and locate your overlays per Zephyr (or DTS?) convention, changes there will compel a rebuild of most if not all your project sources.

    If you are using a Zephyr supported board, changing the board's primary DTS file will potentially impact various sample apps which ship with Nordic's nRF SDK.  Perhaps you have chosen a GPIO that's available for developer's use choice, so such an impact is benign.  You mention also the term "overlay", which is a really handy feature of device tree source.  Your second code excerpt looks like a reasonable "dot overlay" file to add an LED to your project.

    Where is your overlay file located?  How is it named?

    Also, do you mean to assign the &led4 node to a DTS alias named led1?

    You may also want to add to your smaller overlay block of code the line `compatible = "gpio-leds";`.  Not sure if that is required, but I don't think that will hurt anything, and may add some readability.

    When I first got .overlay files working, while programming a Sparkfun Thing Plus nRF9160 development board, I learned that I needed to locate and name my first .overlay file in a particular way.  My project was one I "spun off" from a Nordic Semi ncs 1.6.1 sample app, so it stood in its own directory, which contains a `src` subdir and a `boards` subdir.  My targeted board has a corresponding DTS board file named `sparkfun_thing_plus_nrf9160ns.dts`, in a deep branch of the ncs 1.6.1 Zephyr Project 2.6.0 fork.  In my project's `boards` directory, I created a file named:

       sparkfun_thing_plus_nrf9160ns.overlay

    The basename of my first overlay file must match the basename of my targeted board file.

    Device tree source files are meta-compiled into C by the compiling tool `dtc`.  This compiler is installed somewhere on your work station.  Further, somewhere in the Zephyr based build configuration I am guessing there is a rule which informs `dtc` to check for overlay files in a project's `boards` directory.  You can have multiple .overlay files.  There is an `include` keyword in device tree source, which functions much like C language #include statements.  That is how you can add .overlay files to your project and give them arbitrary names.

    I ask about your filename choice of the overlay file and its location, because for the Zephyr based builds there is a naming convention in place.  I could be wrong, but from what I can tell it is necessary for at least the first "dot overlay" file basename to match your targeted board's board file basename, in order to be found and processed by `dtc`.

    One last caveat:  I have noticed something now that I am developing firmware which targets a custom board.  To build for a custom board I needed to create a full set of board files for that board.  Following the .dts and .yml board filename conventions I could see in Zephyr supported boards, I created several files.  One in particular seems to be the "primary" DTS file, the file which contains a complete device tree for my custom board.  It is to this file that any overlays make or apply changes.  The filename form of this file -- and this goes for all the boards I see in ncs 1.6.1 supported ARM based boards directories -- is of the form "board_name_common.dts".  No other board files among Zephyr's many supported boards contains the pattern "common".  From time to time when I edit this file, upon first re-compilation I see errors relating to my latest DTS change in that file.  This so even when I have built with the "dash pristine" -p option.  I must build a second time for the DTS amendment to be properly compiled.

    This has happened only when I edit my custom board's primary, main .dts file.  Not when I edit overlay files.

    My toolchain is up to date, and I don't see this behavior all the time, but thought I would mention it.  Building twice doesn't cost too much, and perhaps someone else has seen and solved this intermittent issue with `west` based command line builds.

    - Ted

  • Hey Ted, very helpful comment!  Actually, I think you have helped me before (or your posts have) at Jared Wolff's forum :-)

    The led1 was a typo, it's led4 in the file - fixed that.

    I'm doing this on the nRF9160DK, but just for kicks I tried on on the CircuitDojo nRF Feather/Sparkfun Thing Plus board as well and get the same results. In all cases I triple checked that I am using a free GPIO pin.

    Now that I type that, it would likely be easier to focus on the CircuitDojo board since that overlay works well aside from the addition of my LED.  In that overlay (../nfed/shared/conf/mcuboot/circuitdojo_feather_nrf9160ns.overlay) I add an entry for my new LED (a little different from above because that board has only one LED otherwise)

    / {
    	leds {
    		white_led: led_1 {
    			gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
    			label = "White external LED (external D1)";
    		};
    	};
    
    	aliases {
    		bootloader-led0 = &blue_led;
    		led1 = &white_led;
        };
    };
    
    // Full speed ahead
    &uart0 {
    	status = "okay";
    	current-speed = <1000000>;
    	tx-pin = <6>;
    	rx-pin = <5>;
    };

    Doing this gives me the exact same message as in my OP, but now with a 1 instead of a 4:

    error: 'DT_N_ALIAS_led1_P_gpios_IDX_0_VAL_pin' undeclared

    I also get this error when adding compatible = "gpio-leds".  Also in this case multiple builds doesn't have an effect.  Could I be getting the error it because I'm trying to add a device to an existing list of devices (leds)?

    It seems difficult to track down the process in the documentation, they don't have any information (that I can see) about adding to existing lists - everything seems to be about completely new components/functionality.

  • Hi SmallerPond,

    Good to see you here on another useful tech forum!  Also good steps you have tried this past hour, switching to alternate board and related.  I don't know whether I'll help you get further on this issue, but a couple of points to explore and or consider:

    (1)  Your build environment permitting, try to locate the build artifact [project_top_dir]/build/zephyr/zephyr.dts.

    (2)  Be cautious and use only alphas and numerics in DTS alias names, no dashes or underscores.

    As I develop on Linux hosts, I get to run `west` at the command line and I have a now easy time locating and reviewing all custom project sources, as well as familiarity with the neighboring dirs along side my project's top dir, namely `nrf`, `zephyr`, `modules`, the major parts of Nordics ncs Software Development Kit.  This file locating ability has given me quick access to an intermediate dtc artifact, a combined project device tree file which I can review for errors.

    The file `zephyr.dts` is a culmination of all board dts files and dot overlays, with latest ones read "winning" in any places they've amended preexisting device nodes.  By reviewing zephyr.dts and searching for the newer nodes you added, you might be able to make sense of what's causing the later error.  One thing to look for might be repeatedly defined names (symbols) or repeatedly referenced peripheral resources.  Without seeing more of your project's dts code I may not be able to say more.

    The second point relates to your alias name `bootloader-led`.  This feels like an obscure, undocumented one to me.  Through trial and error I found that I could only employ DTS alias names which contains just alphas and numerics.  All my attempts to put underscores in alias names resulted in compile time errors, either at the `dtc` stage or later when cross-ng pre-processor hits certain Zephyr macros which expand my device aliases.

    I can understand the import to keep dashes out of device tree aliases, and other symbols which get meta-compiled into C code.  The dash is a basic C operator, and so without some kind of dts name "sanitizing" a dash or other character-that-is-C-operator is likely to break the, in this case, intermediate C code compiled from Device Tree Source.  Be cautious with alias names in your DTS files, .dts and .overlay.

    Unwinding Zephyr macros can be mentally challenging, and it is possible that a malformed DTS alias that appears before the alias that throws an error is responsible for that error.  Again that goes to the complexity of DTS getting converted to C source, which is on some level parsed sequentially.  These nested macros constructs of Zephyr combined with an unintended C operator can make compile-time debugging hard!

    - Ted

  • Hello

    Using devicetree overlays in Zephyr is documented here:

    http://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/build/dts/howtos.html#set-devicetree-overlays

    You might find the information you need there, if you're still having problems please let me know.

    Best regards,

    Einar

  • Hello ,

    While not a deal breaker to keep dashes and underscores out of device tree alias names, I believe I made a mistake when I said they may not be allowed.  Last night I was reviewing the main DTS board file for the Thingy91.  In the aliases section of Thingy91 DTS board file I see several alias names with dashes in them!  This naming convention must be ok.  The error I was running into while adding aliases to my own custom board file must be due to something else.

    The only difference I can think might matter here is that I am building against ncs v1.6.1, and I believe the latest release as of 2022-05-13 is v1.9.1.  I have not found a ready way to reach older ncs release tags on github's web interface, for the nrfconnect collection of code repositories.  Nordic Semi seems to have configured things so older releases when selected just appear as zip archives.  Not quite as manually searchable on line that way . . . :/

    I think it is unlikely a DTS naming convention such as allowed characters in alias names has changed in the past few months.

    - Ted

Related