Custom Kconfig Preprocessor Macros

Zephyr Software Configuration

March 12, 2024 (1mo ago)


While developing firmware in Zephyr different is needed for different targets and applications.

Rather than managing multiple codebases for each version of firmware, one codebase can be configured through custom Kconfig preprocessor macros.

With Kconfig preprocessor macros, code can be compiled in/out allowing different versions of a single codebase.

An example use case is a point-to-point LoRa radio. The application needs to support both receiving and transmitting functionalities.

While both behaviors can be implemented independently. There is a lot of overlap in the codebases.

They can be implemented together and the specific functionality can be wrapped in preprocessor statements.

Zephyr Kconfig Overview

Kconfig is the configuration system used in Zephyr.

It shares similarities with the configuration tool utilized by the Linux kernel.

Within the Zephyr ecosystem this configuration tool is used to enable and customize various subsystems and parameters.

It can also be used by developers to easily add configuration to their applications.

Adding Custom Configuration

Application configuration is handled in prj.conf. Prior to this step, the new Kconfig configuration needs to be defined. Configuration options (often called symbols) are defined in Kconfig files. They also specify dependencies between symbols that determine what configurations are valid.

In a new Kconfig file add a new configuration option.

config LORA_MODE
	bool "Set LoRa Radio to TX/RX"
	help
	  This option compiles in the correct code.
	  TRUE - Tx and FALSE - Rx

source "Kconfig.zephyr"

Kconfig.zephyr is a reference to the main Zephyr Kconfig.

Idon’t prepend CONFIG_ as it is prepended to the symbol name. The format is shown below

CONFIG_<symbol name>=<value>

The example configuration is simple. There are lots more functionality such as dependencies and options that can be implemented.

See an example configuration below.

config BOARD_ENABLE_DCDC
	bool "Enable DCDC mode"
	select SOC_DCDC_NRF52X
	default y
	depends on BOARD_CUSTOM_PLANK

Applying New Configuration

In prj.conf set the new Kconfig to the desired value.

CONFIG_LORA_MODE=y

Add it into the code. This snippet initializes the device as a receiving radio or transmitting radio depending on the Kconfig.

#if (CONFIG_LORA_MODE)
lora_init_tx(dev);
#else
lora_init_rx(dev);
#endif

After building a code there are some files to look at to verify everything is set up correctly.

In build/zephyr/.config all the configuration values for the application are shown. Search for the new configuration.

CONFIG_LORA_MODE=y

You can verify that your preprocessor configuration has been created by checking the autoconf.h file. Located within build/zephyr/include/generated/autoconf.h.

The header files show all the auto-generated configurations.

#define CONFIG_LORA_MODE 1

It is fairly easy to include a new configuration into a project, and it's also a clean method to manage a codebase. It is common for large codebases to utilize some style of preprocessor configurations.

A good practice to implement in personal projects.