Zephyr RTOS: Setting up a clean workspace with west.yml for your project

Jun 25, 2025

Creating your project workspace - The Background (for Nordic)

If you're new to Zephyr RTOS I recommend starting with my previous post: Zephyr RTOS: Setting up a clean workspace with west.yml for your project.

There are some ways, to do this. Nordic, if you follow their docs and dev academy courses, has a beguinner friendly setup, that gets even simpler with their integration in VS Code. Zephyr also shows multiple ways to do this, possibly not so beguinner friendly if you don't know where to start but very well documented. You can read more about it here: Zephyr Application Development .

The setup I like the most, to keep everything simple, and dependencies clearly specified is the "Zephyr workspace application" method that is explained in the previous link, normally, depending on the project, following T2 topology. This basically allows us to have a private repository with our application, boards, drivers, ... alongside a manifest file that specifies all the depencies and dependency versions required to build the application without having to keep copies of them in our repository.

This setup starts with a west.yml file that points to the path of your application within the repository and lists all the dependencies, including Zephyr RTOS at a specific version. It's like a receipt that lists all the ingredients to get your app ready.

A Zephyr application can have many dependencies, even Zephyr can support or not many features of a specific board. Sine we are using a Nordic board, nordic frequently releases the nRF Connect SDK. Which is a group of forks, libraries, tools, in a specific version, alongside with Zephyr at a specific version, this is maintained and created by Nordic. This is available at nordic github in nRF Connect SDK. and the easiest to way to start a project is to define a west.yml for our application that starts by including the one defined by nordic at a specific version that they track here: nRF Connect SDK Release Notes.

Creating your project - the action

1. Workspace and Project/application folders

To do this, we start with an empty folder, lets call it my_workspace:

mkdir my_workspace
cd my_workspace

Inside the workspace we create the folder for our project:

mkdir my_project
cd my_project

2. Define the west.yml file

Then, inside the my_project folder, we create a west.yml file that references Nordic sdk-nrf at a specific version. For example, if we want to use the latest version of the nRF Connect SDK at the time of writing this post, we add the sdk-nrf project and explictly specify to import everything (or only some required projects to enhance workspace setup time1) and also the west-commands, also, we should include what will be our project path:

manifest:
# your project
  self:
    path: my_project
# nRF Connect SDK project
  projects:
    - name: sdk-nrf
      repo-path: sdk-nrf
      url: https://github.com/nrfconnect/sdk-nrf.git
      # version of sdk-nrf to import
      revision: v3.0.2
      # path within our repo
      path: nrf
      # import west-commands defined in the sdk-nrf project
      west-commands: scripts/west-commands.yml
      #import all the projects at versions specified in sdk-nrf west.yml
      import: true
      

This will import everything specified in sdk-nrf: west.yml file.

If you are using a version control system for yout project (like you should!) the my_project folder, that has the west.yml file inside is your repository root folder.

3. Init the workspace based on the west.yml file using west

Now in the my_workspace folder (which is not tracked by git) we init create the workspace we run:

cd ..
west init
west update

This will init the workspace and download all the dependencies. Time for coffee! since this will take some time2.

4. Your application

Now that the workspace is ready is probably a good time to init p.ex. git inside your project folder and make the initial commit with the west.yml file we just created.

So, now, inside the my_project folder, we can add as many applications as we want and track changes only to this folder and the manifest file, west.yml, that describes our dependencies (in our case inheriting everything for nRF Connect SDK since we are targeting Nordic).

Just to end this post with our own application we can copy the blinky sample to our own folder and change it! From your workspace root do:

cp zephyr/samples/basic/blinky my_project/
cd my_project/blinky

Just to make a small change to the default blinky, let's make the LED blink fastter:

Open the main.c file and change the blink perior to 100 milliseconds:

code src/main.c

And change the code to:

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>

/* 100 msec = 0.1 sec */
#define SLEEP_TIME_MS   100

/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)

/*
 * A build error on this line means your board is unsupported.
 * See the sample documentation for information on how to fix this.
 */
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);

int main(void)
{
	int ret;
	bool led_state = true;

	if (!gpio_is_ready_dt(&led)) {
		return 0;
	}

	ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
	if (ret < 0) {
		return 0;
	}

	while (1) {
		ret = gpio_pin_toggle_dt(&led);
		if (ret < 0) {
			return 0;
		}

		led_state = !led_state;
		printf("LED state: %s\n", led_state ? "ON" : "OFF");
		k_msleep(SLEEP_TIME_MS);
	}
	return 0;
}

Then build and flash the application for nrf54l15-dk:

west build -b nrf54l15dk/nrf54l15/cpuapp  -p
west flash

And you will see the led blinks a lot faster than the sample from zephyr without changes.

5. (Bonus) Sharing/Setting the workspace for your team mates

Now that we have a project tracking in git th

Conclusion

Now, I hope, you know how to setup a workspace for development with Nordic boards in a simple and reproducible way. If you find or have any issues feel free to ping me. This is not the only way to do it but the way I personaly find easier to work and keep everything "clean and tidy" as it must be!

1

In many cases you don't need to import everything and not doing so will significantly reduce the time it takes to update the workspace.For this you can specify import allow lists or block lists. Check the docs: west: Manifest Imports

2

You can improve the time by checking the options for west update command, some allow referencing local caches or not getting the whole history. You can check docs our the PR where this was introduced:PR #496

https://pmsousa.com/blog/posts/feed.xml