Skip to content

Zephyr Lab RT1060 Devicetree

Derek Snell edited this page May 1, 2024 · 1 revision

Objectives

In this lab, you will learn:

  • How to use the MCUXpresso Device Tree viewer for VS Code
  • How to verify devicetree settings for a Zephyr application
  • How to modify devicetree source files
  • How to create a devicetree board overlay file
  • How to change the devicetree pin properties for GPIO
  • How to change the baud rate property for a UART in the devicetree

Devicetree Lab

This lab uses the Zephyr button sample application, which reacts when a button on the board is pressed. The following sections will make changes to the devicetree, and use the button sample to confirm these changes. These devicetree changes include the polarity of the GPIO signal for the button, and the baud rate of the Console UART.

1. Devicetree Overview

A devicetree is a hierarchical data structure that is used to describe and configure hardware. Like Linux, Zephyr uses devicetree to describe the hardware platform. Unlike Linux, Zephyr’s devicetree uses very little memory, is static, and set at build-time.

The devicetree is a hierarchy of nodes and sub-nodes. A node typically describes a hardware component. Nodes have properties that describe the characteristics of the node, and can be used to configure the hardware. Below is an example of a GPIO node from the MIMXRT1060-EVK devicetree board file. This is the GPIO signal connected to the button on the board. The node name is button-1, and has a node label user_button. The properties of this node tie it to GPIO port5 pin0, and configure it as an active-low signal with a pull-up resistor enabled. In this lab, we will change the property of this pin to active-high, and confirm how this changes the behavior of the button sample application.

user_button: button-1 {
        gpios = <&gpio5 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
};

The button application code interacts with this button hardware using a devicetree alias named sw0. An alias creates another devicetree name to reference a specific node. For example, the MIMXRT1060-EVK devicetree board file defines the sw0 alias below, which points to the node label user_button. Aliases are convenient for hardware abstraction, and Zephyr sample applications use aliases frequently. For example, the button sample application runs on dozens of boards supported by Zephyr. The requirements of this button sample to run on a board are:

  1. the board must support the GPIO driver, and
  2. the board’s devicetree must have an alias sw0 that points to the GPIO pin node of the button.

The board’s devicetree is then free to map the sw0 alias to any GPIO pin.

aliases {
        sw0 = &user_button;
        led0 = &green_led;
};

Devicetrees can also include chosen nodes. Chosen nodes are similar to aliases, because they point software to specific devicetree nodes for hardware abstraction. For example, most Zephyr applications use Zephyr’s Console subsystem, including this button sample application. This Console uses the chosen node zephyr,console to know which hardware interface should be used. Below are some chosen node examples from the MIMXRT1060-EVK board devicetree file. This EVK uses the lpuart1 peripheral for the Console interface. In this lab, we will change the baud rate in the devicetree for this lpuart1 node, and confirm how the change affects the Console interface.

        chosen {
                zephyr,console = &lpuart1;
                zephyr,flash = &is25wp064;
                zephyr,shell-uart = &lpuart1;
                zephyr,canbus = &flexcan2;
                zephyr,display = &lcdif;
        };

2. Explore with the MCUXpresso Device Tree viewer

First we will import the Zephyr button sample application into VS Code, build it, and explore the devicetree.

  1. Open VS Code. In the Quickstart Panel, click Import Example from Repository. If needed, the steps to import an example, build, and debug it are included in Zephyr Lab RT1060 Hello World.

    Import Repository

  2. Import the button sample with the following settings:

  • For the board, you can type RT1060 to filter the board arm/mimxrt1060_evkb. Be sure this is the board with ‘B’ on the end of the EVKB name, otherwise the LED will not toggle on your board.

  • For the example template, type button to filter the app samples/basic/button

  • For Application type, select Repository Application

  • Click Create

    Import Button Example

  1. Build the button project

    Build Project

  2. If not already connected to the board, connect the micro-USB cable to J1, to power and debug the EVK. In VS Code, connect the Serial Monitor to the EVK’s COM port, and click Start Monitoring.

    Open Serial Monitor

  3. When the build completes, the Output view shows the image executable zephyr.elf was built, and gives a summary of the memory usage.

    Button build completed

  4. Debug the button project.

    Debug Button

  5. When first connecting to a device and using the LinkServer debug probe, VS Code will use a pop-up to ask for the device part number. In the search field, enter MIMXRT1062xxxxx:MIMXRT1060-EVKB. You can search with part of the device or board part number.

    Select device

Note: In future revisions of the tool, this step will go away, and the extension will select the device automatically.

  1. The execution will pause. To continue execution click Continue on the debug options.

    Continue debugging

  2. In the Serial Monitor view, you will see the app prints the following:

    Button sample output in Serial Monitor:

    *** Booting Zephyr OS build zephyr-v3.4.0 ***
    Set up button at gpio@400c0000 pin 0
    Set up LED at gpio@401b8000 pin 8
    Press the button
    
  3. Notice the green LED D8 is lit (near the center of the EVK, close to the RT1060 MCU). Press the button SW5. The green LED turns off when the button is pressed, and turns back on when the button is released. The Console also prints every time the button is pressed.

    Serial Monitor output after button is pressed twice:

    *** Booting Zephyr OS build zephyr-v3.4.0 ***
    Set up button at gpio@400c0000 pin 0
    Set up LED at gpio@401b8000 pin 8
    Press the button
    Button pressed at 1563343033
    Button pressed at 1570503576
    

Also notice the Console prints the “Button pressed” message when the button is pressed, not when the button is released. This is important for a devicetree change we will make in the next lab section. The EVK schematic snippet below shows pressing the button SW5 shorts the GPIO signal to GND. So the Button pressed message occurs on the falling edge of this GPIO signal.

Button Schematic

  1. Stop the debugger

    Stop Debug

Now that we have the default button sample working, we will explore the devicetree, the sw0 alias, and the button-1 GPIO node.

  1. Open the MCUXpresso Device Tree view in VS Code. Click the MCUXpresso extension on the left toolbar, and find the Device Tree view. Click the Refresh Device Tree button. Notice the refresh should be done after the Zephyr application is built. That build generates the devicetree files used by this viewer.

    Devicetree Refresh

  2. If multiple projects are open, VS Code will prompt to select the project of the devicetree to view. Select the button project.

    Devicetree project selection

    The viewer takes some time parsing the devicetree before displaying it:

    Devicetree View

  3. In the Device Tree view, expand the aliases group, and click on the sw0 alias. When clicking a node or property, the MCUXpresso Device Tree viewer will open the source location where that node is defined or a property is set. In this case, the viewer opens the board devicetree file mimxrt1060_evk.dts. And the viewer finds the line of code where the alias sw0 is set to node label user_button.

Because sw0 is an alias, notice in the Device Tree viewer it also shows us the full devicetree path to the aliased node. This shows the sw0 alias points to the sub-node button-1, which is part of the node gpio_keys.

Locate Button Node

  1. In the Device Tree viewer, expand the node gpio_keys, and click on the button-1 node. The viewer finds this node in the same board devicetree file.

    Button Node DTS

  2. Also notice the Device Tree viewer shows the property values for nodes. Here, the property flags GPIO_PULL_UP and GPIO_ACTIVE_LOW combine to the value of 0x11. This will be important in the next section when we modify this property.

    Button Node Properties

3. Modify a board devicetree file

Now that we found the button-1 GPIO node in the board’s devicetree source file, we will modify its properties, and see how it changes the behavior of the button sample application. We will change this pin to be active-high, and confirm that the button event in the app now occurs on the rising-edge of the button release.

  1. The board devicetree file mimxrt1060_evk.dts is already open in the editor. Modify the gpios property for the button-1 node highlighted below, and change it to GPIO_ACTIVE_HIGH. Save the file (Ctrl-S).

    gpio_keys {
            compatible = "gpio-keys";
            user_button: button-1 {
                    label = "User SW8";
    
                    // change the property below to GPIO_ACTIVE_HIGH
                    gpios = <&gpio5 0 (GPIO_PULL_UP | GPIO_ACTIVE_HIGH)>; 
            };
    };
    
  2. Build the button project.

  3. Wait for the build to complete, and then Refresh the Device Tree viewer.

    Refresh Devicetree

    The viewer will take some time to parse the devicetree, and then will show the property update. Notice the property value for the flags has now changed from 0x11 to 0x10.

    New Button Property

  4. Debug the button project.

  5. Continue executing the application.

    Continue Debug

  6. Press the button SW5 on the board. Notice the green LED is now off until the button is pressed. And using the Serial Monitor, notice the Console prints now when the button is released, on the rising-edge of the GPIO signal.

    Button sample Console output

    *** Booting Zephyr OS build zephyr-v3.4.0 ***
    Set up button at gpio@400c0000 pin 0
    Set up LED at gpio@401b8000 pin 8
    Press the button
    Button pressed at 1043892328
    
  7. Stop the debugger

    Stop Debug

4. Create a devicetree overlay file for UART baud rate

In the last section, we changed the hardware configuration by modifying the board’s devicetree file. That source file is used by every application built for that board. That is a common method when working with a custom board, which would likely be managed in your personal repository, not in the public Zephyr repository. For a custom board, it is best to clone an existing board using a similar SOC, like NXP’s EVK boards. And then modify that new board’s files to match your hardware and applications. For the specific steps to clone a board, see Zephyr’s Board Porting Guide.

In this section, we will modify the devicetree using a different method: called an overlay file. Overlays work with the existing devicetree files, rather than modifying the original files. The devicetree properties in the overlay files will override the same settings in the board and SOC devicetree files. Basically, the board files create a default hardware configuration used for most applications. But if one application wants a change to the hardware configure, it can add an overlay file. Since Zephyr has hundreds of sample and test applications that run on the same boards, some Zephyr applications use overlay files when hardware changes are required. For example, the Zephyr ADC driver sample at samples/drivers/adc/boards has many board overlay files for different boards, which specify the channel properties for the ADC example. If you test your own application on an EVK, overlay files are a good option to configure the hardware for your needs.

In this lab section, we will create a simple overlay that changes the baud rate of the lpuart1 used for the Console. The first steps will use the MCUXpresso Device Tree viewer to confirm the default baud rate setting.

  1. In VS Code, return to the Device Tree viewer. Expand the chosen group, and click on the zephyr,console node. The viewer will find the line in the MIMXRT1060-EVK board file, which points this chosen node to the lpuart1 node. Notice the viewer gives us the full devicetree path to this node on the left: it’s the sub-node uart, in the SOC node.

    LPUART Node

  2. In the Device Tree viewer, expand the SOC node.

    Expand SoC Node

  3. Scroll down to the UART nodes, and expand the first node lpuart1. The properties for that node are listed. For the baud rate, click on the property current-speed. The viewer finds this property setting in the board file, and we confirmed the default baud rate is 115,200. Notice the viewer shows the current-speed value is 0x1C200; this is the hex equivalent of 115,200.

    LPUART Node Config

Now that we learned how to confirm the default baud rate, and what that rate is, we will create an overlay file to change that baud rate.

  1. In the Device Tree viewer, scroll to the bottom. There is a group listed for Overlay files. Currently, there are no overlay files for this application. Click this line to create one.

    Create Overlay

    When adding an overlay file, the viewer adds a file to this project. The viewer names the file after the board name associated with this project, in this case mimxrt1060_evkb.overlay. The viewer also opens this file in the editor. After creation, this overlay file is an empty template.

    Empty Overlay Template

  2. Modify the file mimxrt1060_evkb.overlay, and add the 3 highlighted lines below to override the lpuart1 property. Save this file (Ctrl-S).

    / {
    };
    
    /* Add these 3 lines below */
    &lpuart1{
            current-speed = <57600>;
    };
  3. Clean the button project. Note that asking VS Code to build the project right now will not work. The build system will not detect that a new overlay file was added to the application, so it will think nothing has changed since the last build. To force the build system to include the new file, go to the MCUXpresso view, right-click the button project, and select Clean Selected.

    Clean Project

  4. Build the button project.

  5. Refresh the Device Tree viewer.

    Refresh Devicetree

    The viewer will take some time to parse the devicetree, and then will show the property update. Notice the property value for the current-speed has now changed from 0x1C200 to 0xE100.

    New UART Node Speed

  6. Debug the button project.

  7. Continue executing the application.

    Continue Debug

  8. The Serial Monitor shows a bunch of garbage characters were received. Or you may find the Serial Monitor is not receiving any characters. Oops, we forgot to update the baud rate to match our devicetree change.

    View Monitor Baud Rate

  9. Click the Stop Monitoring button. Then, change the baud rate to 57,600.

    Correct Monitor Baud Rate

  10. Click the Start Monitoring button with the new baud rate setting.

    Start Monitoring

  11. In the debugger pop-up, click the Restart button.

    Restart Debug

  12. click the Continue button.

    Continue Debug

  13. Much better. This confirms the devicetree overlay file we added changed the lpuart1 baud rate to 57,600.

    Valid Monitor Values

5. Clean up after lab

This Devicetree lab has completed. But the following steps will clean up the VS Code workspace:

  1. Stop the Debugger

    Stop Debug

  2. Close all Editor tabs. Right-Click on a tab, and select Close All.

  3. If this is the last lab and you are done using the board, you should disconnect the Serial Monitor. Find the Serial Monitor view, and click Stop Monitoring.

    Stop Monitoring

Additional Resources


Lab completed. Return to the RT1060 Zephyr Labs Overview Training Zephyr Getting Started RT1060

Clone this wiki locally