Zephyr includes a concept called Snippets to assign a nickname to a set of configurations that may include both Kconfig and Devicetree changes. These are quite useful when you need to change more than one symbol and/or tweak your devicetree nodes for a particular build or test. Let’s take a tour of Zephyr Snippets today by focusing on a configuration change that enables the shell and logging.
Production Versus Testing
Snippets make a lot of sense in a bimodal atmosphere, such as the difference between production and testing. It’s unlikely that your production devices will have logging enabled, and you’ll likely disable the shell as well.
west build -p -b frdm_rw612 examples/zephyr/hello -S shell-logs
With snippets, you can configure your project to build with logging and shell disabled by default, then call your snippet to enable them for a debug session. The example above uses the -S flag to include a snippet called shell-logs in the build.
Let’s look at exactly what makes up this snippet.
Snippet: Common Configuration in a Nice Package
The example above calls a snippet that is made up of this file hierarchy.
snippets
└── shell_log
├── shell_log.conf
└── snippet.yml
The snippet.yml file assigns the name of the snippet and adds the shell_log.conf file to the build as an extra config file.
name: shell-log append: EXTRA_CONF_FILE: shell_log.conf
If we look in the config file, we see the symbols that are selected by this snippet:
CONFIG_LOG=y CONFIG_LOG_MAX_LEVEL=4 CONFIG_SHELL=y CONFIG_SHELL_BACKENDS=y CONFIG_SHELL_BACKEND_SERIAL=y
The final piece in the puzzle is telling Zephyr where to find your snippet files. Do this by using a Zephyr module yaml file to specify where to look for the snippets folder, relative to your project’s root directory.
build:
settings:
snippet_root: .
While there is nothing magical happening in snippets, enabling this set of symbols with one human-readable (and memorable) snippet name is pretty nice. The same could be done by adding -- -DEXTRA_CONF_FILE=snippets/shell_log/shell_log.conf or by adding the symbols to the prj.conf file. But you can see why including the snippet argument is more convenient and less error-prone
While it is not demonstrated in this example, the concept is quite extensible. A Devicetree overlay file may be added alongside, or instead of the Kconfig file by adding EXTRA_DTC_OVERLAY_FILE: your_devicetree.overlay in the snippet file append section. Build flags are another option, and all of the additions presented by the snippet may be gated/conditionally included based on board name and domain (eg: when using sysbuild). In fact, let’s jump into some of the quirks that sysbuild brings and how to deal with them.
Using Snippets with Sysbuild (multi-domain builds)
The same snippet example above can be applied to multi-domain builds like Golioth’s firmware update sample. The syntax looks very much the same but has some unintended consequences.
west build -p -b frdm_rw612 examples/zephyr/fw_update/ --sysbuild -S shell-log
If we look at the summary of the build for the mcuboot domain, we see our snippet grew the resource usage by quite a bit.
# mcuboot without shell-log snippet
Memory region Used Size Region Size %age Used
FLASH: 51996 B 128 KB 39.67%
RAM: 44096 B 960 KB 4.49%
SMU1: 510 KB 510 KB 100.00%
SMU2: 140 KB 140 KB 100.00%
IDT_LIST: 0 GB 32 KB 0.00%
# mcuboot with shell-log snippet
Memory region Used Size Region Size %age Used
FLASH: 77608 B 128 KB 59.21%
RAM: 49424 B 960 KB 5.03%
SMU1: 510 KB 510 KB 100.00%
SMU2: 140 KB 140 KB 100.00%
IDT_LIST: 0 GB 32 KB 0.00%
Flash usage for the bootloader is a whopping 50% more when including the snippet in the build command! Hey, that’s fine if you have the space available, which we do in this sample. However, the bootloader partition is commonly sized for the build without extra space and this snippet would cause the build to fail.
Most likely you are turning on shell and logging just to work with the application. But snippets are included in all domains during a sysbuild. The solution is to namespace your snippet inclusion.
west build -p -b frdm_rw612 examples/zephyr/fw_update/ --sysbuild -- -Dfw_update_SNIPPET="shell-log"
This is a slightly different approach which leverages cmake to add a list of snippets targeting one specific domain. In this case that’s fw_update, but could also have targeted only the bootloader by using -Dmcuboot_SNIPPET="name-of-your-snippet".
During the build, Zephyr will report the conf and overlay files included in the build so you can check for the expected files to confirm the snippet worked.
Parsing /home/mike/golioth-compile/golioth-firmware-sdk/modules/lib/golioth-firmware-sdk/examples/zephyr/fw_update/Kconfig Loaded configuration '/home/mike/golioth-compile/golioth-firmware-sdk/zephyr/boards/nxp/frdm_rw612/frdm_rw612_defconfig' Merged configuration '/home/mike/golioth-compile/golioth-firmware-sdk/modules/lib/golioth-firmware-sdk/examples/zephyr/fw_update/prj.conf' Merged configuration '/home/mike/golioth-compile/golioth-firmware-sdk/modules/lib/golioth-firmware-sdk/examples/zephyr/fw_update/boards/frdm_rw612.conf' Merged configuration '/home/mike/golioth-compile/golioth-firmware-sdk/modules/lib/golioth-firmware-sdk/snippets/shell_log/shell_log.conf' Merged configuration '/home/mike/golioth-compile/golioth-firmware-sdk/modules/lib/golioth-firmware-sdk/build/fw_update/zephyr/.config.sysbuild' Configuration saved to '/home/mike/golioth-compile/golioth-firmware-sdk/modules/lib/golioth-firmware-sdk/build/fw_update/zephyr/.config' Kconfig header saved to '/home/mike/golioth-compile/golioth-firmware-sdk/modules/lib/golioth-firmware-sdk/build/fw_update/zephyr/include/generated/zephyr/autoconf.h'
Using Multiple Snippets
You may add as many snippets to your snippet directory as you like.
snippets
├── dev_sectag
│ ├── dev_sectag.conf
│ └── snippet.yml
└── shell_log
├── shell_log.conf
└── snippet.yml
And then use more than one in your build.
west build -p -b frdm_rw612 examples/zephyr/hello -S shell-logs -S dev-sectag
Zephyr even has some snippets built-in. Many of them are tightly coupled to vendor-specific configurations. But some are quite useful, like using -S rtt-console to turn on console output when using Segger RTT.
What do you have planned for your own snippets? We’d love to hear about it, post your details in the Golioth forum!


No comments yet! Start the discussion at forum.golioth.io