Zephyr quick tip: Show what menuconfig changed and make changes persistent

The Zephyr project uses the KConfig system to select what subsystems and libraries are included in the build of your project. Sometime this is really simple, like adding CONFIG_GPIO=y when you need to use input/output pins. That’s easy enough to add manually. But things get more complex when you don’t know which configuration you need, or you want to fine tune a value like stack size.

In this post, we’re going to look at how to make changes in menuconfig, but also how to check those changes and make them permanent.

Turning on a watchdog timer

If you want to use the watchdog timer subsystem in Zephyr you need to add CONFIG_WATCHDOG=y to your build. That’s not entirely easy to figure out as the Watchdog entry in the Zephyr docs doesn’t mention it. There is some sample code called Task Watchdog and you can see the symbol is enable in the project configuration file, but there are other symbols related to watchdog timers in there as well. Which ones do we need?

I like to use menuconfig to work out these issue. It’s something we’ve talked about a few times before, and Marcin and Chris even filmed walkthrough of menuconfig system. The first step is to build your project before trying to enable the new configuration. This is necessary to generate the initial configuration for the project; if your project has a build error, you can’t load up menuconfig. Here I’m building for an nRF52840 feather board:

west build -b adafruit_feather_nrf52840 my_app_directory -p

Notice I’m using the -p directive for a “pristine” build. This makes sure that anything in the build directory is generated fresh so we are certain that we begin with a clean build.

Next, use west build -t menuconfig to launch the interactive configuration menu:

Zephyr menuconfig
Zephyr menuconfig

My most-used feature is the forward-slash ( / ) which brings up a text search. I searched for “watchdog” and two similar options came up.

I find that the options with helper text (“Watchdog Support” in this example) next to them are the best items to choose. Pressing enter on that entry takes me to the configuration item where I use the space bar to select it, indicated by an asterisk. That’s it, I’m not going any deeper right now. Pressing q brings up the exit menu, don’t forget to save your changes.

Zephyr kind of takes care of the rest, automatically pulling in a bunch of other options based on the top-level option I enabled. But those are actually why I’m writing this article. How can I see what changes other were made by “under the hood” by menuconfig?

Seeing changes made by menuconfig

Running a build command on a Zephyr project pulls in configurations from all over the place (eg: the board’s default configuration from the Zephyr tree, the project’s prj.conf file, and any .conf files in the boards directory). These coalesce into the build/zephyr/.config file, which is what menuconfig loads and saves to. Luckily, before this happens it makes a copy called .config.old which we can compare using the diff command:

[sourcecode]

(.venv) mike@krusty ~/golioth-compile/AgTech-Soil/fw $ diff build/zephyr/.config.old build/zephyr/.config
30c30
< # CONFIG_WATCHDOG is not set

> CONFIG_WATCHDOG=y
179c179,180
< # CONFIG_NRFX_WDT0 is not set

> CONFIG_NRFX_WDT=y
> CONFIG_NRFX_WDT0=y
813a815
> CONFIG_HAS_DTS_WDT=y
1046a1049,1057
> # CONFIG_WDT_DISABLE_AT_BOOT is not set
> # CONFIG_WDT_LOG_LEVEL_OFF is not set
> # CONFIG_WDT_LOG_LEVEL_ERR is not set
> # CONFIG_WDT_LOG_LEVEL_WRN is not set
> CONFIG_WDT_LOG_LEVEL_INF=y
> # CONFIG_WDT_LOG_LEVEL_DBG is not set
> CONFIG_WDT_LOG_LEVEL=3
> # CONFIG_WDT_COUNTER is not set
> CONFIG_WDT_NRFX=y
[/sourcecode]

Check that out! Enabling CONFIG_WATCHDOG automatically pulls in the CONFIG_NRFX_WDT because of the chip used in my project. Be we also learn some interesting things here. It looks like some Nordic chips have multiple watchdog timers as CONFIG_NRFX_WDT0 is selected. If we search in menuconfig for that symbol and type ? on the entry we can get more information on what that’s all about:

Nordic watchdog timer instance info
The help screen in menuconfig for CONFIG_NRFX_WDT0

You can see here that this symbol was enabled (y-selecting) by the WDT_NRFX symbol. So if you’re cruising through menuconfig and want to know why something is turned on, this is a handy way to track down those answers. Try bringing up the help screen for the CONFIG_WDT_COUNTER which is shown above but not enabled. I certainly learned something about this chip for doing so!

Making menuconfig changes persistent

Remember way back at the top of the article when I mentioned I was using a “pristine” build with the -p flag? If you do that now, you’ll lose your menuconfig changes. So make sure you do an incremental build (just don’t use the pristine flag) to test those changes out. But eventually you will want to make them persistent.

The solution for that is easy. Use the diff trick I showed above to confirm what symbols were changed by your menuconfig selections, and add those changes to the prj.conf or board-specific .conf files. Once you commit these to your revision control, you’ll be certain to compile in the options you need for future projects.

Stop by our Discord or our Forum for more quick tips about Zephyr and your next IoT project!

Mike Szczys
Mike Szczys
Mike is a Firmware Engineer at Golioth. His deep love of microcontrollers began in the early 2000s, growing from the desire to make more of the BEAM robotics he was building. During his 12 years at Hackaday (eight of them as Editor in Chief), he had a front-row seat for the growth of the industry, and was active in developing a number of custom electronic conference badges. When he's not reading data sheets he's busy as an orchestra musician in Madison, Wisconsin.

Post Comments

More from this author

Related posts

spot_img

Latest posts

Golioth Firmware SDK v0.17.0

Yesterday, we released v0.17.0 of the Golioth Firmware SDK. This release introduces support for the Golioth Location service in the SDK. We've also improved...

Using Zephyr SMP with Multiple MCUs

It's easy to see that Golioth makes firmware updates for internet-connected devices a snap. But combine Golioth Cohorts, our improved OTA event log, and interconnectivity tools like SMP, and you end up with a powerful OTA scheme for all of the controllers in a complex system.

Golioth Design Partners: IoT Solutions for Constrained Devices | 2025 Partner Network

We regularly refer Golioth users to our trusted Design Partners to help design, test, and deploy hardware out into the world. The Golioth Design Partner program has been going for more than 2 years and continues growing. In 2025, we reached 20 listed partners, with others in the wings.

Want to stay up to date with the latest news?

We would love to hear from you! Please fill in your details and we will stay in touch. It's that simple!