In this topic, we will explore the different options to create custom board files and the guidelines for naming your custom board.
We will also cover the mandatory files required to define a custom board in HWMv2, optional files, and revision files used if you create revisions for your board. We will study these files one by one and understand their role.
In Exercise 1 of Lesson 3, we will use the Create a new board GUI in the nRF Connect for VS Code extension to populate most of the mandatory files’ content.
The Create new board GUI in the latest version of nRF Connect for the VS Code extension uses a west
extension command called ncs-genboard
. If you are confident with CLI, you could use it directly.
When naming your custom board, there are some conventions that you need to follow.
west boards
in the nRF Connect Terminal for a list of names that have already been taken; you can’t name your custom board with a name that is already in use. board.yml
fileNote that the Create a new board GUI in nRF Connect for VS Code extension will ask you to provide a human-readable name for your board. The Human-readable name(Also known as full_name) could include whitespaces or capital letters. (Ex: My nRF54L DK , DevAcademyL3E1), and it will automatically generate your board ID (Ex: my_nrf54l_dk
, devacademyl3e1
) that can be used by west build
command or by the Add Build Configration GUI.
In Hardware Model version 2, each board will have a board name. The board name (Board ID) used in the build system is usually the human-readable name, formatted in all lowercase letters and using underscores (_) to replace all whitespaces. Each board must have one SoC at a minimum.
In addition to the board name and SoC. A board could have an optional board revision and board qualifiers. Now let’s take a look at the board terminology used in HWMv2. We will take a look at the BL5340 DVK from Ezurio which is based on the nRF5340 SoC.
Board Target: The full string that can be provided to any of the Zephyr build tools(E.g. west
) to compile and link an image for a particular hardware system. A key point to understand is that boards with single-core SoCs typically have one board target, while more advanced boards with multiple SoCs or multi-core SoCs may have several board targets.
Board qualifiers: The set of additional tokens, separated by a forward slash /
that follows the board name (and optionally board revision).
Variant: In the context of board qualifiers, a variant designates a particular type or configuration of a build for a combination of SoC and CPU clusters. Common uses of the variant concept include introducing both secure and non-secure builds for platforms with TrustedFirmware-M support, or selecting the type of RAM used in a build. Another use of variants is for different builds of hardware(not a revision). For example, if you have a board that includes sensors and another exact one that does not include sensors.
Board revision: This is used to capture new changes in new versions of the hardware(New schematics, new PCB).
For example, a board with a human-readable name “DevAcademyL3E1” will have a board name (board ID) of devacademyl3e1
. Let’s assume the kit is based on the nRF52833 SoC . The board will have the board target devacademyl3e1
/nrf52833
. The board could have an optional revision that can be specified as [email protected]/nrf52833
and it could have an optional variant [email protected]/nrf52833/sense
. The CPU cluster(s) is defined by the SoC layer as we will see later. The nRF52833 SoC does not include any clusters.
There are three options for where to store custom board files with varying advantages and disadvantages:
boards
folder in your application directory. Suitable for prototyping/debugging.As we mentioned before, we will use the nRF Connect for VS Code to create the template files for a new development kit called “DevAcademyL3E1” which is based on the nRF52833 SoC. The board name generated by the extension is
. The extension will also populate the “vendor” of the SoC. As we will see in Exercise 1.devacademyl3e1
When creating a custom board definition, remember that the hardware layers files from Architecture until SoC are provided by the SDK itself. We only need to populate the board layer. The board layer consists of these four mandatory files.
boards/<vendor>/devacademyl3e1
├── board.yml
├── Kconfig.devacademyl3e1
├── devacademyl3e1.dts
└── devacademyl3e1-pinctrl.dtsi
Below is a board layer consisting of all mandatory files, optional and special use cases files:
boards/<vendor>/devacademyl3e1
├── board.yml
├── Kconfig.devacademyl3e1
├── devacademyl3e1_<qualifiers>.dts
├── devacademyl3e1_<qualifiers>-pinctrl.dtsi
├── devacademyl3e1_<qualifiers>_defconfig
├── Kconfig.defconfig
├── board.cmake # Used for flash and debug
├── CMakeLists.txt # Needed in special cases
├── c_files.c # Needed in special cases
├── doc # Optional
│ ├── devacademyl3e1.png
│ └── index.rst
├── Kconfig # Optional to create a board Kconfig options menu
├── devacademyl3e1_<qualifiers>.yml # Optional for Test Runner (Twister)
├── devacademyl3e1_<qualifiers>_<revision>.conf # Needed to support hardware revisions
├── devacademyl3e1_<qualifiers>_<revision>.overlay #Needed to support hardware revisions
└── dts # Optional
└── bindings
The term devacademyl3e1
serves as a placeholder for the board name, and <vednor>
is a placeholder for the vendor name. If the board has qualifiers, such as multiple SoCs, CPU clusters, or variants (i.e., multi board target), these qualifiers must be appended to the board name to clearly indicate where you want these files to apply.
Now, we will cover these files one by one.
1. board.yaml
: This is a new file introduced in HWMv2 . It’s mandatory, so each board folder needs to have one board.yaml
file.
board.yaml
, but it’s not a common use case. The extension automatically generates this file when you provide the tool with your board name, SoC, SoC variant, and vendor, and you typically don’t need to change anything inside it.
You could also include full_name:
in board.yml
to specify the human-readable name of your board.
Here are some examples of board.yml
for some Nordic development kits:
So for a single board target like the nrf52840 dongle, which is based on the nrf52840 SoC, a single-core device with no CPU clusters.
For the nRF54L15, there are two cpuclusters defined by the SoC layer, cpuapp
and cpuflpr
, and you can see that the board.yml
defines a new variant called xip
which is associated with the cpuflpr
cpucluster. It also defined another variant called ns
(TF-M Enabled) with the cpuapp
cpucluster. So in total, you have 4 board targets.
For the nRF9161 DK, there are no cpuclusters defined for the nRF9161 SiP , there is a variant called ns
that is associated with the nrf9161 SoC. It also defines two revisions 0.9.0 (default) and 0.7.0.
2. Kconfig.devacademyl3e1:
This file has a fixed-defined task: selecting the specific SoC(s) used by a board. Hence, it pulls in lower layers of SW support (SoC, Family, Series, CPU, Arch). It also defines a Kconfig symbol for the board that is a normalized name of the board name ( with capital letters, and whitespace converted to underscore _
) prefixed with BOARD_
.
select
statement(s)
select
is needed for a single board targetselect … if
statements for multi-cores SoC or multi-SoC boardHere are some examples:
Below is an example of our
(single board target) that we will develop in Exercise 1, which is based on the nRF52833 QIAA.devacademyl3e1
config BOARD_DEVACADEMYL3E1
select SOC_NRF52833_QIAA
Here is another example for the nRF54L15 DK (quad board target). The file selects the appropriate SoC support layer based on the normalized board target triggered from the build system.
3.
: The hardware description in devicetree format that represents the schematics of your board. We call this file board-level devicetree file. It Includes connectors and any other hardware components such as LEDs, buttons, sensors, or communication peripherals (USB, BLE controller, etc). Memory partitioning is also done in this file. We will rely heavily on the automation provided by nRF Connect for VSCode extension, including the DeviceTree visual editor, to help us populate this file. Keep in mind that if your board has multiple board qualifiers, you need to create a board-level device tree file for each board target. Also, it’s worth mentioning that you can structure the board-level device tree file into multiple files to improve readability and maintainability.
.dtsdevacademyl3e1
4.
: This file defines the pin-mapping of your board’s peripherals. Keep in mind that if your board has multiple board qualifiers, you need to create a pin-mapping file for each. We will learn how to populate this file in Exercise 1.
-pinctrl.dtsi
devacademyl3e1
: This file is a Kconfig fragment merged as-is into the final build of any application built for the specified board.
_defconfigdevacademyl3e1
Default devacademyl3e1_defconfig
generated by the tool (Differs from one SoC to another).
# Copyright (c) 2024 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
CONFIG_ARM_MPU=y
CONFIG_HW_STACK_PROTECTION=y
In addition to the default Kconfig symbols, we need to include any Kconfig symbols that we want to be enabled for any application built on our board.
In the case of the
, since it’s a development kit, we want to add UART, RTT and GPIO support. Therefore, we will append the following :devacademyl3e1
# Enable RTT
CONFIG_USE_SEGGER_RTT=y
# enable GPIO
CONFIG_GPIO=y
# enable uart driver
CONFIG_SERIAL=y
# enable console
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
<boardname>_defconfig
is a Kconfig fragment merged as-is into the final build of any application built for the specified board, and must enable the bare minimum. It’s the application configuration’s (prj.conf
) responsibility to configure what is needed.
Keep in mind that if your board has multiple board qualifiers, you need to specify the qualifiers in the name of the file
to take effect when a certain qualifier is passed to the build system.
_<qualifiers>_defconfig devacademyl3e1
Kconfig.defconfig
: Board-specific default values for Kconfig options. The content of this file is placed inside if /endif
pair. This file is generated by the tool. Let’s see the example of our
, which has a single board target devacademyl3e1
devacademyl3e1
/nrf52833
.
if BOARD_DEVACADEMYL3E1
config BT_CTLR
default BT
endif # BOARD_DEVACADEMYL3E1
Kconfig We can see we have the BT_CTLR
which is to enable support for SoC native Bluetooth LE controller implementation, and it is enabled only if the CONFIG_BT
is selected by the application.
You could have multiple if/endif
pairs for the different normalized board targets (if the board has multiple board targets). Let’s take the example of Kconfig.defconfig
of the nRF54L15 DK.
Now, let’s look at the remanding of optional files.
board.cmake
: used for Flash and debug support, if the board has Flash or Debug support.CMakeLists.txt
: If you need to add source files to be executed Pre or Post kernel. This is in case your hardware uses some muxes or needs to be configured in a particular way. Customization can be added here, as done for the case of the nRF52840 Dongle where the board_nrf52840dongle_nrf52840_init() is executed at PRE_KERNEL_1
before the kernel. Note that the extension does not create the CMakeLists.txt
file; we can manually create it ourselves if needed.doc/index.rst
, doc/devacademyl3e1.png
: You only need documentation and a picture of your board if you’re Contributing your board to Zephyr.Kconfig
: Give you the flexibility of creating a board menu.devacademyl3e1.yml
: a YML file with miscellaneous metadata used by the Test Runner (Twister). If your board has multiple qualifiers, you need to have a .yml for each.In case you are creating new hardware revisions for your board, In other words, when you decide to modify your schematics and make a new PCB, you don’t have to create a new board definition, all you need to do is to add the modifications inside the board folder by adding the following files:
, devacademyl3e1
_<revision>.conf
and update
.overlaydevacademyl3e1
_<revision>board.yml
. Keep in mind that if your board has multiple board qualifiers, you need to specify the .conf
and .overlay
files to the affected qualifiers:
, devacademyl3e1
_<qualifiers>_
<revision>.conf
<qualifiers>_devacademyl3e1
_<revision>
.overlay.
devacademyl3e1
_
<revision>.conf
will be merged into the board’s default Kconfig configuration.devacademyl3e1
_<revision>.overlay
will be overlayed to the board-level devacademyl3e1
.dts
devicetree file.board.yml
file through the revision:
key controls how the Zephyr build system matches the <board_name>@<revision>
string specified by the user when building an application for the board for either the west build CLI or the nRF Connect for VS Code extension. An example development kit that uses the board revisions is the nRF9160 DK.When creating a new custom board, it is always a good idea to start looking into the SDK-defined boards with the same SoC/SIP as your custom board for inspiration. There is a long list of Development Kits, Prototyping Platforms, and Reference designs already shipped in the SDK that can serve as a good starting point.
They are available in two locations <install_path>/zephyr/boards/nordic/
and <install_path>/nrf/boards/nordic/
See the Zephyr Board Porting Guide.
This exercise tab is for nRF Connect SDK v2.6.2 -v2.5.2, where Hardware model v1 (HWMv1) is used. HWMv1 is deprecated and will be removed in nRF Connect SDK v3.0.0. Use HWMv2 for all new designs (Tab v2.8.x-v2-7.0)
In this topic, we will explore the different options to create custom board files and the guidelines for naming your custom board. You can watch the video below or go through the lesson’s text.
We will also cover the mandatory files required to define a custom board, optional files, and revision files used if you create revisions for your board. We will study these files one by one and understand the role of each.
In the exercises of Lesson 3, we will use the Create a new board GUI in nRF Connect for VS Code extension to help us populate most of the content of the mandatory files.
When naming your custom board, there are some conventions that you need to follow.
west boards
in the nRF Connect Terminal for a list of names that have already been taken; you can’t name your custom board with a name that is already in use.Note that the Create a new board GUI in nRF Connect for VS Code extension will ask you to provide a human-readable name for your board (Ex: DevAcademy nRF52833), and it will automatically generate your board ID (devacademy_nrf52833
) that can be used by west build
command or by the Add Build Configration GUI.
There are three options for where to store custom board files with varying advantages and disadvantages:
boards
folder in your application directory. Suitable for prototyping/debuggingAs we mentioned before, we will use the nRF Connect for VS Code to create the template files for a new development kit called “DevAcademy nRF52833” which is based on the nRF52833 SoC. The board ID generated by the extension is devacademy_nrf52833
. The extension will also automatically populate the architecture “ARCH” used by the SoC. As we will see in Exercise 1
When creating a custom board definition, remember that the hardware layers files from Architecture until SoC are provided by the SDK itself. We only need to populate the board layer. The board layer consists of these five mandatory files.
boards/<ARCH>/devacademy_nrf52833
├── Kconfig.board
├── Kconfig.defconfig
├── devacademy_nrf52833_defconfig
├── devacademy_nrf52833.dts
└── devacademy_nrf52833-pinctrl.dtsi
Below is a board layer consisting of all mandatory files, optional and special use cases files:
boards/<ARCH>/devacademy_nrf52833
├── Kconfig.board
├── Kconfig.defconfig
├── devacademy_nrf52833_defconfig
├── devacademy_nrf52833.dts
├── devacademy_nrf52833-pinctrl.dtsi
├── board.cmake # Used for flash and debug
├── CMakeLists.txt # Needed in special cases
├── c_files.c # Needed in special cases
├── doc # Optional
│ ├── devacademy_nrf52833.png
│ └── index.rst
├── Kconfig # Optional to create a board Kconfig options menu
├── devacademy_nrf52833.yaml # Optional for Test Runner (Twister)
├── devacademy_nrf52833_<revision>.conf # Needed to support multiple hardware revisions
├── devacademy_nrf52833_<revision>.overlay # Needed to support multiple hardware revisions
└── revision.cmake # Needed to support multiple hardware revisions
└── dts # Optional
└── bindings
The devacademy_nrf52833
will be your board’s name, of course. We are using this name just as a placeholder.
Now, we will cover these files one by one.
The mandatory files are:
Kconfig.board
: The extension automatically generates this file, and we typically don’t need to change anything inside it. What it does is that it makes a Kconfig Symbol for your board BOARD_DEVACADEMY_NRF52833
and it specifies a dependency to the SoC hardware support layer (through the depends on Keyword).# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
config BOARD_DEVACADEMY_NRF52833
bool "DevAcademy nRF52833"
depends on SOC_NRF52833_QIAA
2. Kconfig.defconfig
: Board-specific default values for Kconfig options. The extension automatically generates this file, and we typically don’t need to change anything inside it.
The file is placed inside an if BOARD_DEVACADEMY_NRF52833
/ endif
pair of lines, as shown below. When the developer passes the selected target board through either west (CLI) or using nRF Connect for VS Code Build Configration window (GUI), the BOARD_DEVACADEMY_NRF52833
will be set and the Kconfig BOARD symbol will be set through the project. The other option we find in that file is BT_CTLR
which is to enable support for SoC native Bluetooth LE controller implementation, and it is enabled only if the CONFIG_BT
is selected by the application. This is added here due to the fact that the nRF52833 is widely used for Bluetooth LE applications.
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
if BOARD_DEVACADEMY_NRF52833
config BOARD
default "devacademy_nrf52833"
config BT_CTLR
default BT
endif
devacademy_nrf52833_defconfig
: This file is the Kconfig fragment merged as-is into the final build of any application built for the specified board. The default Kconfig symbols that are generated by the extension are:
CONFIG_SOC_SERIES_NRF52X
, which will enable the CPU and architecture support.CONFIG_SOC_NRF52833_QIAA
Default devacademy_nrf52833_defconfig
generated by the tool.
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
CONFIG_SOC_SERIES_NRF52X=y
CONFIG_SOC_NRF52833_QIAA=y
CONFIG_BOARD_DEVACADEMY_NRF52833=y
# Enable MPU
CONFIG_ARM_MPU=y
# Enable hardware stack protection
CONFIG_HW_STACK_PROTECTION=y
What we need to add in this file in addition to the default Kconfig symbols are any Kconfig symbols that we want to be enabled for any application build for our board.
In the case of the DevAcademy nRF52833
we want to add UART, RTT and GPIO support. Therefore, we will append the following :
# Enable RTT
CONFIG_USE_SEGGER_RTT=y
# enable GPIO
CONFIG_GPIO=y
# enable uart driver
CONFIG_SERIAL=y
# enable console
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
# additional board options
CONFIG_GPIO_AS_PINRESET=y
CONFIG_PINCTRL=y
<BoardID>_defconfig
is a Kconfig fragment merged as-is into the final build of any application built for the specified board, and must enable the bare minimum. It’s the application configuration’s (prj.conf
) responsibility to configure what is needed.
devacademy_nrf52833.dts
: The hardware description in devicetree format that represents the schematics of your board. We call this file board-level devicetree file. It Includes connectors and any other hardware components such as LEDs, buttons, sensors, or communication peripherals (USB, BLE controller, etc). Flash partitioning is also done in this file. We will rely heavily on the automation provided by nRF Connect for VSCode extension, including the DeviceTree visual editor, to help us populate this file.devacademy_nrf52833-pinctrl.dtsi
: This file defines the pin-mapping of your board’s peripherals. Note that the extension does not create this file; we must create it ourselves. We will learn how to populate this file in Exercise 1The optional files are:
board.cmake
: used for Flash and debug support, if the board has Flash or Debug support.CMakeLists.txt
: If you need to add source files to be executed Pre or Post kernel. This is in case your hardware uses some muxes or needs to be configured in a particular way. Customization can be added here, as done for the case of the nRF52840 Dongle where the board_nrf52840dongle_nrf52840_init() is executed at PRE_KERNEL_1 before the kernel. Note that the extension does not create the CMakeLists.txt
file; we can manually create it ourselves if needed.doc/index.rst
, doc/devacademy_nrf52833.png
: documentation for and a picture of your board. You only need this if you’re Contributing your board to Zephyr.Kconfig
: Give us the flexibility of creating a board menudevacademy_nrf52833.yaml
: a YAML file with miscellaneous metadata used by the Test Runner (Twister).In case you will be creating new hardware revisions for your board. In other words, when you decide to modify your schematics and make a new PCB, you don’t have to create a new board definition, all you need to do is to add the modifications inside the board folder by adding the following files: devacademy_nrf52833_<revision>.conf
, devacademy_nrf52833_<revision>.overlay
and revision.cmake
devacademy_nrf52833_<revision>.conf
will be merged into the board’s default Kconfig configuration.devacademy_nrf52833_<revision>.overlay
will be added to the common devacademy_nrf52833.dts
devicetree filerevision.cmake
file controls how the Zephyr build system matches the <board>@<revision>
string specified by the user when building an application for the board for either the west build CLI or the nRF Connect for VS Code extension. An example development kit that uses the board revisions is the nRF9160 DK.When creating a new custom board, it is always a good idea to start looking into the SDK-defined boards with the same SoC/SIP as your custom board for inspiration. There is a long list of Development Kits, Prototyping Platforms, and Reference designs already shipped in the SDK that can serve as a good starting point.
They are available in two locations <install_path>/zephyr/boards/arm/
and <install_path>/nrf/boards/arm/
See the Zephyr Board Porting Guide.