gnosis.farm

Getting started with Zephyr

This article will explain how to setup a local Zephyr development environment. I will do this for development on de NXP FRDM-MCXA156, but you can use this tutorial for any board supported on Zephyr. I will mention every platform specific setup I do, so you can alter it for your usecase.

Setting up a west workspace

First we need to create a workspace. In this tutorial I chose to go for topology 2, where our application is the manifest repository. For more information about the supported toplogies refer to this.

Creating the workspace folder

To start setting up a workspace we make a new folder in a suitable location, for example the home directory.

1mkdir zephyr-ws

The name of this folder does not matter. In Zephyr development this folder is called the topdir. Next we go into this folder

1cd zephyr-ws

Adding a basic application

Inside this folder we create a new directory where our application will live. I named it app, but this name also doesn’t matter.

A folder alone isn’t an application so we will need some files.

zephyr-ws
└── app
    ├── CMakeLists.txt
    ├── prj.conf
    ├── src
    │   └── main.c
    └── west.yml

This is the tree structure of a minimal Zephyr application. For this tutorial I went with a basic blink program.

west.yml

 1manifest:
 2  version: 1.0
 3
 4  projects:
 5    - name: zephyr
 6      url: https://github.com/zephyrproject-rtos/zephyr
 7      revision: v4.4.0
 8      import:
 9        name-allowlist:
10          - hal_nxp
11          - cmsis_6

This is the manifest file. I used version 1.0 and included Zephyr v4.4.0. You can of course choose whatever version you want. I also import the necessary projects from the Zephyr west.yml file which, in my case, are hal_nxp and cmsis_6. This will be different depending on what boards you are using. I’m using a NXP board, so this is what I need for my basic project.

main.c

 1#include <zephyr/drivers/gpio.h>
 2#include <zephyr/kernel.h>
 3
 4#define LED_NODE DT_ALIAS(led0)
 5#define BLINK_MS 1000
 6
 7static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED_NODE, gpios);
 8
 9int main(void)
10{
11    bool led_state = true;
12
13    if (!gpio_is_ready_dt(&led)) {
14        return 0;
15    }
16
17    if (gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE) < 0) {
18        return 0;
19    }
20
21    while (true) {
22        if (gpio_pin_toggle_dt(&led) < 0) {
23            return 0;
24        }
25
26        led_state = !led_state;
27        k_msleep(BLINK_MS);
28    }
29
30    return 0;
31}

This blink code should work on any board with led0 defined.

prj.conf

CONFIG_GPIO=y

We only need to enable the GPIO for this basic example.

CMakeLists.txt

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(blink)

target_sources(app PRIVATE src/main.c)

With all these files you now have a minimal blink application. If you use git, the content of this folder is the thing you manage. Anything outside this folder does not need to be tracked by git.

Installing and initializing west

west is installed via pip, so we will need to create a virtual environment (or venv).

Run this in the topdir, in my case zephyr-ws:

1python3 -m venv .venv
2source .venv/bin/activate
3pip install west

This will install the west application in the virtual environment. Everytime you want to work with west, you will have to activate the venv.

Next we actually initialize our workspace:

1west init -l app/

This command will create a workspace around our application in the manifest repository; app in my case. The output of this command will tell you to run west update, so we will do this next.

1west update

This will update the projects defined in the manifest file. In my case it will download Zephyr V4.4.0 and the imports I’ve allowed: hal_nxp and cmsis_6.

Next we will run:

1west zephyr-export

This will register the Zephyr installation with CMake, so we can succesfully build it.

Installing the Zephyr SDK

Now we will finally install the SDK. This only takes one command to do:

1west sdk install

Building and flashing

To build the application we use the west build command:

1west build -b frdm_mcxa156 app --pristine

Here I choose to build app for my NXP board. If you use another board, choose that one instead of course. The pristine flag tells west to build everything, everytime. That way I can be sure the build file always represents the current code.

Next comes flashing. For this you will need a runner that can flash your specific board. In my case I can use pyocd, so I will need to install it.

1pip install pyocd

I will also install the pack for my specific chip:

1pyocd pack install MCXA156

If everything works well, and you connect your board to your computer and run

1pyocd list

you should see your board in the list. If this does not happen you might not be part of the dialout group or you don’t have the correct udev rules installed.

To fix this run

1sudo usermod -aG dialout $USER

to add your user to the dialout group. You might need to restart your computer for this to take effect.

If you use a NXP board, to set the correct udev rules you can download the rules from the pyocd github and add them to /etc/udev/rules.d/.

After you’ve done this run

1sudo udevadm control --reload-rules
2sudo udevadm trigger

to register these rules.

To flash your board just run:

1west flash --runner pyocd

Result

If everything went well you should have a board with a blinking LED running Zephyr.

<< Previous Post

|

Next Post >>

#Embedded #Zephyr