Note
This lesson covers how to define boards in the nRF Connect SDK using both hardware models v1 and v2 (HWMv1 and HWMv2 respectively).
This exercise tab covers nRF Connect SDK where HWMv2 is used, which is recommended for all new designs.
In this topic, we will explore the different options for creating custom board files and the guidelines for naming your custom board.
We will cover the mandatory and optional files required to define a custom board in HWMv2, as well as how to create a revision of the board. We will study these files one by one and understand their role.
In Exercise 1 of this lesson, we will use the Create a new board GUI in the nRF Connect for VS Code extension to define a new board, and populate most of the mandatory files’ content.
Board terminology (in HWMv2)
In Hardware Model version 2, each board has a unique board name (sometimes referred to as the board ID).
The Create a new board GUI function in the nRF Connect for VS Code extension will ask you to provide both a board name and a human-readable name for your board. The human-readable name can include white spaces or capital letters (e.g., My nRF54L DK, DevAcademyL3E1), and is intended for display purposes and documentation. The board name is commonly a lower-case and underscore-separated version of the human-readable name (e.g., my_nrf54l_dk, devacademyl3e1).
Definition
Human-readable name (full_name) is the descriptive name for the board, which can include spaces and capital letters. The full name is intended for display purposes and documentation, making it easier for users to recognize the board.
Board name is typically a lowercase, underscore-separated version of the human-readable name, with all whitespaces replaced by underscores. The board name uniquely and descriptively identifies a particular system, but does not include additional information that may be required to actually build an image.
When naming your custom board, you need to give your board a unique name. Run 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.
Below is an example of the output:
esp32c3_042_oled
96b_aerocore2
nrf52840dongle
nrf5340dk
nrf54l15dk
thingy53
nrf52_sparkfunTerminalNote
In HWMv2, the name of the SoC is no longer needed at the end of the board name. Instead, this is specified explicitly in one of the files in the board definition (board.yml file).
In addition to the board name, a board will have one or more board qualifiers.
Let’s examine the board terminology used in HWMv2, using the BL5340 DVK from Ezurio as an example, 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. Boards with single-core SoCs typically have one board target, while more advanced boards with multiple SoCs or multi-core SoCs will have several board targets. - Board name: The name of the board without spaces.
- Board revision (optional): This is used to capture new changes in new hardware versions (new schematics, new PCB).
- Board qualifiers: The set of additional tokens, separated by a forward slash / that follows the board name (and optionally board revision).
- SoC: The specific SoC used on the board.
- CPU cluster: This is defined by the SoC layer. If the SoC does not have any clusters, this is omitted.
- 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 Trusted Firmware-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.
Consider a board with the human-readable name DevAcademy L3E1, based on the nRF52833 SoC. The board will have the board name devacademyl3e1, and the board target devacademyl3e1/nrf52833. The board can have an optional revision that can be specified as [email protected]/nrf52833 and it could have an optional variant [email protected]/nrf52833/sense.
Note
The CPU clusters are defined by the SoC layer, and the nRF52833 SoC does not have any clusters.
Location of custom board
Before diving into the board files that make up the custom board definition, we need to know where to put the files.
When working with custom boards, you have three main options for where to place the board definition files. Each option has its own advantages and limitations:
- Out-of-Tree (dedicated directory): In this approach, your board files are stored outside of the nRF Connect SDK/Zephyr tree in a separate directory. You’ll configure the build system to locate and use these external board files. This method is ideal for closed-source projects where you want to keep board definitions private. This is the method we’ll focus on in this lesson.
- Upstream in Zephyr: Choose this option if you’re developing a development kit, module, reference design, or prototyping platform that you intend to share with the Zephyr community. It’s also appropriate for open-source products. Board definitions submitted upstream must include documentation and go through a review and approval process by the Zephyr maintainers.
- Inside the application’s
boardsfolder: This option is suitable for quick prototyping or debugging. You can place the board files directly in aboardssubdirectory within your application folder. This is a convenient approach for temporary or experimental work.
Board files
Consider our new development kit DevAcademy L3E1 which is based on the nRF52833 SoC. The board name for this board will be .devacademyl3e1
When creating a custom board definition, remember that the SDK provides the hardware layer files from Architecture up to SoC. So, 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 The term <vendor> serves as a placeholder for the vendor name.
Mandatory files
Let’s take a close look at the four mandatory files in the board layer.
1. board.yml
The board.yml file is a required component introduced in Hardware Model v2 (HWMv2). Each board folder must contain one board.yml, and it serves as a central configuration file that defines key properties for your board.
- Board name: Defines the board name or names.
- SoC selection: At least one SoC must be specified.
- Revisions: Optional; used to define specific hardware versions.
- Variants: Used for special configurations, such as enabling TF-M or using a different CPU core.
While it’s technically possible to define multiple boards in one folder using a single board.yml, this is not a common use case.
When you use the extension tool and input the board name, SoC, SoC variant, and vendor, the board.yml file is generated automatically. In most cases, you won’t need to manually edit it.
Here is what a board.yml file typically looks like. You could also include full_name: in board.yml to specify the human-readable name of your board.

Let’s take a look at the board.yml files for some Nordic development kits.

board.yml examples- Single board target: The nRF52840 dongle is based on the nRF52840 SoC, a single-core device with no CPU clusters.
- Quad board target: The nRF54L15 has two CPU clusters defined by the SoC layer,
cpuappandcpuflpr. Theboard.ymldefines a new variant,xip,which is associated withcpuflpr.It also defines another variant calledns(TF-M enabled) associated with thecpuapp. So in total, there are 4 board targets. - Dual board target with revisions: The nRF9161 DK has no CPU clusters defined by the nRF9161 SiP. There is a variant,
ns.It also defines two revisions: 0.9.0 (default) and 0.7.0.
2. Kconfig.devacademyl3e1
This file serves a specific and essential purpose: it selects the SoC(s) used by the board. By doing so, it pulls in the appropriate hardware layer files from Architecture up to SoC. It also defines a Kconfig symbol for the board, which is the board name prefixed with BOARD_ .
- It contains
selectstatement(s)- Only
selectis needed for a single-board target select … ifstatements are needed for multi-core SoCs or multi-SoC boards
- Only
Here 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_QIAAHere 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. devacademyl3e1.dts
The board-level devicetree file is a hardware description written in the devicetree format. It represents the schematics of your board, detailing its physical components and connections.
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 the nRF Connect for VS Code extension, including the Devicetree Visual Editor, to help us populate this file.
If your board has multiple board qualifiers (i.e., different board targets or variants), you need to create a separate board-level devicetree file for each board target. You can structure the board-level devicetree file into multiple files to improve readability and maintainability.
4. devacademyl3e1-pinctrl.dtsi
This file defines the pin-mapping of your board’s peripherals.
If your board has multiple board qualifiers (i.e., different board targets or variants), you need to create a separate pin-mapping file for each board target.
Optional files
Now that we’ve covered the four mandatory files in the board layer, let’s take a look at the optional files.
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 <vendor> serves as a placeholder for the vendor name. If the board has qualifiers (<qualifiers>), such as multiple SoCs, CPU clusters, or variants (e.g., multi-board target), these qualifiers must be appended to the board name to clearly indicate where you want these files to apply.
devacademyl3e1_defconfig
The file is a Kconfig fragment that is merged as-is into the final build of any application built for the specified board._defconfigdevacademyl3e1
Here is the default devacademyl3e1_defconfig file 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 manually include any additional Kconfig symbols that we want to be enabled for all applications built for the board.
In the case of our board, DevAcademy L3E1, it’s a development kit, so 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=yNote
<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.
If your board has multiple board qualifiers (i.e., different board targets or variants), you need to specify the qualifiers in the name of the file (e.g., for it to take effect when a certain qualifier is passed to the build system._<qualifiers>_defconfig)devacademyl3e1
Kconfig.defconfig
The Kconfig.defconfig file defines board-specific default values for Kconfig options. The content of this file is wrapped in if /endif blocks that correspond to specific board targets. This file is automatically generated by the tool and complements the defconfig file by setting defaults that only apply when building for a particular board.
Let’s see the example for our board which has a single board target devacademyl3e1/nrf52833.
if BOARD_DEVACADEMYL3E1
config BT_CTLR
default BT
endif # BOARD_DEVACADEMYL3E1KconfigThe CONFIG_BT_CTLR Kconfig option, which enables support for the SoC native Bluetooth LE controller implementation, is only enabled if CONFIG_BT is selected by the application.
If the board has multiple board targets, you can have multiple if/endif blocks for the different board targets.
For example, in the Kconfig.defconfig file for the nRF54L15 DK.

The remaining optional files are:
board.cmake: Used to add Flash and debug support to the board.CMakeLists.txt: Used to include source files that should be executed pre- or post-kernel. For example, if your hardware requires custom mux configurations or needs to be configured in a particular way, it can be added to this file. This is done for the nRF52840 Dongle whereboard_nrf52840dongle_nrf52840_init()is executed atPRE_KERNEL_1before the kernel. Note that the extension does not create theCMakeLists.txtfile; you need to manually create it if needed.doc/index.rst,doc/devacademyl3e1.png: Documentation and image of the board, only needed if you are Contributing your board to Zephyr.Kconfig: Allows you to create a custom Kconfig menu specific to your board.devacademyl3e1.yml: A YAML file with miscellaneous metadata used by Zephyr’s Test Runner (Twister). If your board has multiple qualifiers, you need to have a .yml for each.
Board revisions
When you create new hardware revisions for your board, such as changes to the schematics or a new PCB layout, you do not need to create a completely new board definition. Instead, you can simply add the revision-specific files within the same board folder, and devacademyl3e1_<revision>.conf, and update .overlaydevacademyl3e1_<revision>board.yml to include the revision.
Keep in mind that if your board has multiple board qualifiers, you need to specify the .conf and .overlay files to the affected qualifiers, e.g., , devacademyl3e1_<qualifiers>_<revision>.conf<qualifiers>_devacademyl3e1_<revision>.overlay.
: The optional Kconfig settings specified here will be merged into the board’s default Kconfig configuration.<revision>.confdevacademyl3e1_: The optional devicetree overlay will be overlayed with the board-level_<revision>.overlaydevacademyl3e1devicetree file..dtsdevacademyl3e1board.yml: Therevision:property controls how the Zephyr build system matches the<board_name>@<revision>string specified by the user when building an application for the board.
Note
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.