Configuring your application

Much like the Linux kernel, Zephyr allows its users to configure the kernel/application at build time through the usage of the Kconfig-based configuration system. This can be used to, for example, enable optional features.

Interactive configuration

Users can choose to configure their application interactively, through the usage of the menuconfig interface.

Opening the menuconfig interface

To open up the menuconfig interface, you’ll first have to build your application. For example, assuming we want to configure the pixy2 sample, based on the How to build section, we’d first have to run:

west build -p -b frdm_imx93//a55 samples/pixy2 -D DTC_OVERLAY_FILE=frdm_imx93.overlay

If the compilation was successful, the project tree should now contain a new directory called build. With this, you can now open the menuconfig interface by running:

ninja -C build menuconfig

If all went well, you should now be greeted by an interface similar to the one shown in Figure 34.

../_images/menuconfig_itf.png

Figure 34 Menuconfig interface

Searching for configuration options

If you’re interested in looking for a particular configuration option, you can use the search interface, which can be accessed by pressing the / key. Once open (see Figure 37), you can now type in the name of your configuration option.

../_images/menuconfig_search.png

Figure 37 Menuconfig search interface

The name of the configuration option you type in must not contain the CONFIG_ prefix. For example, assuming we’re interested in looking for the CONFIG_CLOCK_CONTROL_INIT_PRIORITY option, we’d simply type in CLOCK_CONTROL_INIT_PRIORITY as shown in Figure 38.

../_images/menuconfig_search_example.png

Figure 38 Menuconfig search example

We can then use the up and down arrow keys to navigate through the search results.

Printing help information

Sometimes the menuconfig entries are not descriptive enough and you might require additional information (such as the name of the associated configuration option, its type, etc..). In such cases, you can use the ? key to print help information on the currently selected entry (highlighted in blue as shown in Figure 34). For example, Figure 39 shows the help infromation printed for the entry highlighted in Figure 34.

../_images/menuconfig_help.png

Figure 39 Menuconfig help

If you want to close the help menu, you can just press the ESC key.

Using configuration options in your C code

During the build process, Zephyr will generate an autoconf.h header file with the definitions of the configuration options and their values. If you inspect this file (which you should be able to find under build/zephyr/include/generated/zephyr/autoconf.h), you’ll notice that each configuration option is defined as a macro. For boolean types, if the config was assigned the value y, the associated macro will be defined and will expand to the value 1. For instance:

/* if NXPCUP_PIXY2_I2C_TRANSPORT is set to n, this config will not be defined at all! */
#define CONFIG_NXPCUP_PIXY2_I2C_TRANSPORT 1

On the other hand, if the config is assigned the value n, the associated macro will not be defined at all. The example below shows you how you can test if a config was assigned the value y and perform actions based on that:

int main(void) {
#ifdef CONFIG_NXPCUP_PIXY2_I2C_TRANSPORT
   LOG_INF("Hello, world!");
#else
   LOG_INF("Goodbye, world!");
#endif /* CONFIG_NXPCUP_PIXY2_I2C_TRANSPORT */
   return 0;
}

If CONFIG_NXPCUP_PIXY2_I2C_TRANSPORT is set to y, your application will print the Hello, world! message. Otherwise, it will print the Goodbye, world! message.

For integer types, the associated macro should always be defined and will expand to the configured value.

Non-interactive configuration

Note

While you’re still getting used to the development environment, we recommend using this method instead of the interactive configuration as it should be less prone to errors/mistakes.

As discussed in Menuconfig entries, the configuration performed through menuconfig is not persistent. To overcome this, you can opt for the non-interactive configuration option, which makes use of the prj.conf file.

Each Zephyr application must have a prj.conf file, even if it’s empty. In the context of this project, each sample application has the prj.conf file stored under samples/<sample_name>/prj.conf, while the starting point for your application has it stored under src/prj.conf.

The prj.conf file is made up of multiple entries, each of which with the following format:

<config_name>=<value>

where:

  • config_name: name of the configuration option to modify. The name must contain the CONFIG_ prefix. For example: CONFIG_NXPCUP_PIXY2_SPI_TRANSPORT.

  • value: value to assign to the config

Therefore, setting the value of a config option is as simple as adding a new line to the prj.conf file. For example, assuming we want to set CONFIG_NXPCUP_PIXY2_SPI_TRANSPORT to y for the pixy2 sample, we’d have to add the following line to samples/pixy2/prj.conf:

CONFIG_NXPCUP_PIXY2_SPI_TRANSPORT=y

After modifying the prj.conf file, you can re-compile the application as you normally would (using the -p flag). You also have the option of verifying if you configuration was saved by opening up menuconfig and looking at the value that was assigned to your config (needs to be done after the re-compilation).

Further reading

  1. https://docs.zephyrproject.org/latest/build/kconfig/index.html

  2. https://docs.zephyrproject.org/latest/build/kconfig/menuconfig.html