Component Configuration and KConfig System

Chapter 24: Component Configuration and KConfig System

Chapter Objectives

  • Understand the concept of ESP-IDF components and their role in modular development.
  • Learn about the Kconfig system used for configuration management in ESP-IDF.
  • Understand the purpose and usage of the menuconfig tool.
  • Learn the basic syntax of Kconfig files (config, menuconfig, choice, bool, int, hex, string, depends on, default).
  • Understand how configuration options are stored in sdkconfig and accessed via sdkconfig.h.
  • Learn how to add custom configuration options to your own components.
  • Understand the role of Kconfig.projbuild files.

Introduction

As our ESP32 projects grow in complexity, managing configuration settings becomes increasingly important. While simple #define directives in header files might suffice for small projects, they quickly become unwieldy. How do we manage settings for different hardware variants? How do we easily enable or disable features? How do libraries or reusable modules (components) expose their own configuration options without cluttering the main application?

ESP-IDF solves these challenges using a powerful and flexible configuration system called Kconfig, originally developed for the Linux kernel. Kconfig allows developers to define configuration options in dedicated files, provides a text-based menu interface (menuconfig) to easily view and modify these options, and automatically generates header files (sdkconfig.h) to make these settings accessible in C code.

This chapter explores the structure of ESP-IDF components, delves into the Kconfig language and its associated tools, and shows you how to create and manage configuration settings for your own custom components, leading to more modular, maintainable, and configurable firmware.

Theory

ESP-IDF Components

ESP-IDF promotes a modular design philosophy based on components. A component is essentially a self-contained module of code, typically residing in its own directory, that provides specific functionality. Examples include drivers (like GPIO, WiFi), libraries (like FreeRTOS, NVS, lwIP), and even parts of your own application logic.

Key characteristics of components:

  • Directory Structure: Usually located under the components/ directory in your project or within the ESP-IDF framework itself.
  • Build Integration: Each component typically has its own CMakeLists.txt file that tells the build system how to compile its source files and link them into the final application.
  • Configuration: Components can define their own configuration options using Kconfig files, allowing users to customize the component’s behavior via menuconfig.
  • Dependencies: Components can declare dependencies on other components.
Plaintext
my_project/
├── main/
│   ├── CMakeLists.txt
│   ├── Kconfig.projbuild  (We'll create this)
│   └── main.c
├── components/
│   └── custom_module/
│       ├── CMakeLists.txt     (We'll create this)
│       ├── Kconfig            (We'll create this)
│       ├── Kconfig.projbuild  (We'll create this)
│       └── custom_module.c    (We'll create this)
│       └── include/
│           └── custom_module.h (We'll create this)
├── CMakeLists.txt
├── partitions.csv
└── sdkconfig

Using components makes projects more organized, facilitates code reuse, and allows for independent configuration of different modules.

The Kconfig System

Kconfig is the backbone of ESP-IDF’s configuration mechanism. It involves several parts:

  1. Kconfig Files: Plain text files containing definitions of configuration options. These files use a specific syntax to define symbols (options), their types, default values, dependencies, help text, and how they are organized into menus.
  2. menuconfig Tool: An interactive, text-based menu (ncurses) interface that reads the Kconfig files and presents the options to the user in a structured way (menus and submenus). Users navigate this interface to enable/disable features, set values, and choose options. You run it using idf.py menuconfig.
  3. sdkconfig File: A plain text file located in the project’s root directory. When you save your configuration in menuconfig, the chosen settings (only those differing from defaults or explicitly set) are saved to this file in the format CONFIG_OPTION_NAME=value. This file should generally not be edited manually; let menuconfig manage it. It should be added to version control (like Git) to ensure reproducible builds.
  4. sdkconfig.h File: An automatically generated C header file located in the build/config/ directory. It translates the settings from the sdkconfig file into C preprocessor macros (e.g., #define CONFIG_OPTION_NAME value). You include this header in your C/C++ code to access the configuration values. This file is generated during the build process and should not be edited manually or added to version control.
  5. Build System Integration: The ESP-IDF build system (CMake) processes the Kconfig files, generates the sdkconfig.h header, and uses the configuration settings to conditionally compile code or pass definitions to the compiler.
%%{ init: { 'theme': 'base', 'themeVariables': {
      'primaryColor': '#DBEAFE',      'primaryTextColor': '#1E40AF', 'primaryBorderColor': '#2563EB', /* Blue */
      'secondaryColor': '#FEF3C7',    'secondaryTextColor': '#92400E', 'secondaryBorderColor': '#D97706', /* Amber */
      'tertiaryColor': '#D1FAE5',     'tertiaryTextColor': '#065F46', 'tertiaryBorderColor': '#059669', /* Green */
      'lineColor': '#A78BFA',         'textColor': '#1F2937',
      'mainBkg': '#FFFFFF',           'nodeBorder': '#A78BFA',
      'fontFamily': '"Open Sans", sans-serif'
} } }%%
graph TD
    subgraph "Definition Phase"
        KFiles["Kconfig Files<br>(In Components / IDF)"]:::kconfigDef;
        KProjBuild["Kconfig.projbuild Files"]:::kconfigDef;
    end

    subgraph "Configuration Phase (User)"
       Menuconfig["idf.py menuconfig<br>(Interactive Tool)"]:::menuTool;
    end

     subgraph "Storage & Generation Phase (Build System)"
        Sdkconfig["sdkconfig File<br>(Project Root, User Settings)"]:::configFile;
        BuildProcess["Build Process<br>(CMake/Ninja)"]:::buildSystem;
        SdkconfigH["sdkconfig.h<br>(build/config/, Generated Header)"]:::generatedFile;
     end

     subgraph "Usage Phase (Code)"
        CCode["C/C++ Source Code<br>(#include <i>sdkconfig.h</i>)"]:::sourceCode;
        AppBinary[("Application Binary<br>(.elf / .bin)")]:::appBinary;
     end

    KFiles -- Defines Options --> Menuconfig;
    KProjBuild -- Locates Kconfig --> Menuconfig;
    Menuconfig -- Saves Choices --> Sdkconfig;
    Sdkconfig -- Input --> BuildProcess;
    BuildProcess -- Generates --> SdkconfigH;
    SdkconfigH -- Included By --> CCode;
    CCode -- Compiled With Config --> AppBinary;


    %% Styling Definitions
    classDef kconfigDef fill:#FEF3C7,stroke:#D97706,stroke-width:1.5px,color:#92400E;
    classDef menuTool fill:#EDE9FE,stroke:#5B21B6,stroke-width:2px,color:#5B21B6,font-weight:bold;
    classDef configFile fill:#FEF9C3,stroke:#F59E0B,stroke-width:1px,color:#B45309;
    classDef buildSystem fill:#BFDBFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF;
    classDef generatedFile fill:#D1FAE5,stroke:#059669,stroke-width:1.5px,color:#065F46;
    classDef sourceCode fill:#FFFFFF,stroke:#6B7280,stroke-width:1px,color:#1F2937;
    classDef appBinary fill:#E5E7EB,stroke:#6B7280,stroke-width:2px,color:#374151,font-weight:bold;

Kconfig File Syntax Basics

Kconfig files define configuration symbols and their properties. Here are some common elements:

  • config SYMBOL_NAME: Defines a configuration symbol (variable). The convention is to use uppercase names.
  • bool "Prompt": Defines a boolean symbol (can be enabled y or disabled n). The string is the prompt displayed in menuconfig.
  • int "Prompt": Defines an integer symbol.
  • hex "Prompt": Defines a hexadecimal symbol.
  • string "Prompt": Defines a string symbol.
  • default <value>: Sets the default value for the symbol. Defaults can depend on other symbols (e.g., default y if OTHER_SYMBOL).
  • depends on <OTHER_SYMBOL> or depends on <SYMBOL1> && <SYMBOL2>: Makes the current symbol visible/configurable only if the dependency symbol(s) are enabled (y).
  • help: Starts a block of help text explaining the symbol, displayed in menuconfig. The indentation matters.
  • menu "Menu Title"endmenu: Groups related options under a submenu in menuconfig.
  • choice <CHOICE_NAME>endchoice: Defines a group where only one option can be selected (like radio buttons). Individual options within the choice are defined using config.
  • source "path/to/other/Kconfig": Includes another Kconfig file, typically used to bring in component configurations.

Component Kconfig Files

Each component that needs to be configurable should contain a Kconfig file in its root directory. This file defines the configuration options specific to that component.

Project Kconfig Files

  • main/Kconfig (Optional): If your main application logic needs project-specific configuration options not tied to a reusable component, you can create a Kconfig file in the main directory.
  • Kconfig.projbuild: This file, located in the component’s directory (or main/), plays a crucial role. It tells the main build configuration process where to find the component’s Kconfig file. Its typical content is:# Kconfig.projbuild for component 'my_component' include $(COMPONENT_KCONFIG)
    or for the main component:# Kconfig.projbuild for main component include Kconfig
    The build system automatically finds these Kconfig.projbuild files and uses them to aggregate all Kconfig definitions before running menuconfig.

Accessing Configuration in Code

Once you have configured your project using menuconfig and built it, the settings are available in your C code by including the generated header:

C
#include "sdkconfig.h" // Include the generated config header

// ... later in your code ...

#ifdef CONFIG_MY_FEATURE_ENABLE // Check if a boolean option is enabled
    // Code related to the feature
    ESP_LOGI(TAG, "My Feature is enabled.");
#endif

int buffer_size = CONFIG_MY_BUFFER_SIZE; // Access an integer value
ESP_LOGI(TAG, "Using buffer size: %d", buffer_size);

const char* device_name = CONFIG_MY_DEVICE_NAME; // Access a string value
ESP_LOGI(TAG, "Device name: %s", device_name);

#if CONFIG_MY_MODE_OPTION_A // Check a choice option
    ESP_LOGI(TAG, "Mode A selected");
#elif CONFIG_MY_MODE_OPTION_B
    ESP_LOGI(TAG, "Mode B selected");
#endif

Important: The CONFIG_ prefix is automatically added to the symbol names defined in Kconfig when generating sdkconfig.h.

Accessing Kconfig Settings in C Code (via sdkconfig.h)

Remember to #include "sdkconfig.h"

Kconfig Type C Code Access Example
Boolean (bool) Use preprocessor directives #ifdef, #if, or #ifndef. The macro is defined (usually to 1) if the option is enabled (y).
#ifdef CONFIG_MY_FEATURE_ENABLED
    // Code to include if feature is enabled
    printf("Feature is ON\n");
#else
    // Optional code if feature is disabled
    printf("Feature is OFF\n");
#endif

// Or check the value directly (if defined)
#if CONFIG_MY_FEATURE_ENABLED
    // ...
#endif
Integer (int) / Hex (hex) The macro expands directly to the configured integer or hex value.
int size = CONFIG_BUFFER_SIZE;
uint32_t addr = CONFIG_DEVICE_ADDRESS;

printf("Buffer size: %d\n", size);
printf("Device address: 0x%08" PRIX32 "\n", addr);
String (string) The macro expands to a C string literal (including quotes).
const char* name = CONFIG_DEVICE_NAME;
printf("Device name: %s\n", name);

// Be careful with buffer sizes if copying
char local_name[64];
strncpy(local_name, CONFIG_DEVICE_NAME, sizeof(local_name) - 1);
local_name[sizeof(local_name) - 1] = '\0'; // Ensure null termination
Choice (choice) Only the macro corresponding to the selected option within the choice group will be defined (usually to 1). Use #if / #elif / #else / #endif.
#if CONFIG_OPERATION_MODE_A
    printf("Mode A selected.\n");
    // Mode A specific code...
#elif CONFIG_OPERATION_MODE_B
    printf("Mode B selected.\n");
    // Mode B specific code...
#else
    // This case might occur if no default was set and nothing selected
    printf("No valid mode selected!\n");
#endif

Practical Examples

Project Setup:

  • Start with a standard ESP-IDF project template (e.g., hello_world).
  • We will create a custom component.

Example 1: Creating a Configurable Custom Component

Let’s create a simple component called custom_module with some configuration options.

Create Component Directory Structure:

Inside your project’s root directory, create the following structure:

Plaintext
my_project/
├── main/
│   ├── CMakeLists.txt
│   ├── Kconfig.projbuild  (We'll create this)
│   └── main.c
├── components/
│   └── custom_module/
│       ├── CMakeLists.txt     (We'll create this)
│       ├── Kconfig            (We'll create this)
│       ├── Kconfig.projbuild  (We'll create this)
│       └── custom_module.c    (We'll create this)
│       └── include/
│           └── custom_module.h (We'll create this)
├── CMakeLists.txt
├── partitions.csv
└── sdkconfig

Create components/custom_module/Kconfig:

This file defines the configuration options for our component.

Plaintext
# Kconfig file for Custom Module component

menu "Custom Module Configuration"

    config CUSTOM_MODULE_ENABLE
        bool "Enable Custom Module Feature"
        default y
        help
            Enable this option to activate the core functionality
            of the custom module.

    config CUSTOM_MODULE_BUFFER_SIZE
        int "Data Buffer Size (bytes)"
        depends on CUSTOM_MODULE_ENABLE
        default 1024
        range 128 4096
        help
            Specifies the size of the internal data buffer used by the module.
            Must be between 128 and 4096 bytes.

    config CUSTOM_MODULE_DEVICE_NAME
        string "Device Nickname"
        depends on CUSTOM_MODULE_ENABLE
        default "My ESP32 Device"
        help
            A user-friendly name for this device, used in logs or UI.

    choice CUSTOM_MODULE_MODE
        prompt "Operating Mode"
        depends on CUSTOM_MODULE_ENABLE
        default CUSTOM_MODULE_MODE_A
        help
            Select the primary operating mode for the module.

        config CUSTOM_MODULE_MODE_A
            bool "Mode A (Standard)"

        config CUSTOM_MODULE_MODE_B
            bool "Mode B (Low Power)"

    endchoice # CUSTOM_MODULE_MODE

endmenu # Custom Module Configuration

Create components/custom_module/Kconfig.projbuild:

This tells the build system about the component’s Kconfig file.

Plaintext
# Kconfig.projbuild for component 'custom_module'
include $(COMPONENT_KCONFIG)

Create components/custom_module/include/custom_module.h:

Header file for our component’s functions.

C
#ifndef CUSTOM_MODULE_H
#define CUSTOM_MODULE_H

#include "esp_err.h"

/**
 * @brief Initializes the custom module based on Kconfig settings.
 *
 * @return esp_err_t ESP_OK on success, or an error code.
 */
esp_err_t custom_module_init(void);

/**
 * @brief Performs the main action of the custom module.
 */
void custom_module_do_work(void);

#endif // CUSTOM_MODULE_H

Create components/custom_module/custom_module.c:

Implementation file, accessing Kconfig values.

C
#include "custom_module.h"
#include "sdkconfig.h" // Include generated configuration
#include "esp_log.h"
#include <stdio.h> // For snprintf

static const char *TAG = "CUSTOM_MODULE";

// Static buffer, size determined by Kconfig
#ifdef CONFIG_CUSTOM_MODULE_ENABLE
static char internal_buffer[CONFIG_CUSTOM_MODULE_BUFFER_SIZE];
#endif

esp_err_t custom_module_init(void)
{
#ifndef CONFIG_CUSTOM_MODULE_ENABLE
    ESP_LOGW(TAG, "Custom module is disabled in configuration.");
    return ESP_OK; // Not an error, just disabled
#else
    ESP_LOGI(TAG, "Initializing Custom Module...");
    ESP_LOGI(TAG, "Feature Enabled: Yes");
    ESP_LOGI(TAG, "Buffer Size: %d bytes", CONFIG_CUSTOM_MODULE_BUFFER_SIZE);
    ESP_LOGI(TAG, "Device Nickname: '%s'", CONFIG_CUSTOM_MODULE_DEVICE_NAME);

    #if CONFIG_CUSTOM_MODULE_MODE_A
        ESP_LOGI(TAG, "Operating Mode: A (Standard)");
    #elif CONFIG_CUSTOM_MODULE_MODE_B
        ESP_LOGI(TAG, "Operating Mode: B (Low Power)");
    #else
        ESP_LOGW(TAG, "Operating Mode: Unknown/Not Set!");
    #endif

    // Initialize the buffer (example)
    snprintf(internal_buffer, sizeof(internal_buffer), "Initialized for %s", CONFIG_CUSTOM_MODULE_DEVICE_NAME);
    ESP_LOGD(TAG, "Internal buffer initialized.");

    ESP_LOGI(TAG, "Custom Module Initialized Successfully.");
    return ESP_OK;
#endif // CONFIG_CUSTOM_MODULE_ENABLE
}

void custom_module_do_work(void)
{
#ifndef CONFIG_CUSTOM_MODULE_ENABLE
    // Do nothing if disabled
    return;
#else
    ESP_LOGI(TAG, "Custom module doing work...");
    // Access the buffer or use other config values here
    ESP_LOGD(TAG, "Current buffer content: '%s'", internal_buffer);

    // Simulate work based on mode
    #if CONFIG_CUSTOM_MODULE_MODE_A
        ESP_LOGI(TAG, "Performing standard work...");
    #elif CONFIG_CUSTOM_MODULE_MODE_B
        ESP_LOGI(TAG, "Performing low power work...");
    #endif
#endif // CONFIG_CUSTOM_MODULE_ENABLE
}

Create components/custom_module/CMakeLists.txt:

Build instructions for the component.

Plaintext
# CMakeLists.txt for component custom_module

idf_component_register(SRCS "custom_module.c"
                       INCLUDE_DIRS "include"
                       REQUIRES main) # Example dependency

Modify main/main.c:

Include the component header and call its functions.

C
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "custom_module.h" // Include our custom component header

static const char *TAG = "MAIN";

void app_main(void)
{
    ESP_LOGI(TAG, "Main application started.");

    // Initialize the custom module
    esp_err_t init_result = custom_module_init();
    if (init_result != ESP_OK) {
        ESP_LOGE(TAG, "Failed to initialize custom module!");
        // Handle error, maybe restart or halt
        return;
    }

    // Main loop periodically calls the module's work function
    while (1) {
        custom_module_do_work();
        vTaskDelay(pdMS_TO_TICKS(5000)); // Do work every 5 seconds
    }
}

Create main/Kconfig.projbuild:

This ensures the build system finds the main component’s dependencies (even though main doesn’t have its own Kconfig in this example, this file structure is standard).

Plaintext
# Kconfig.projbuild for main component
# No custom Kconfig for main in this example, but file is needed
# if main has dependencies that need configuration processing.

(Note: Often, main doesn’t need a Kconfig.projbuild if it has no Kconfig itself and its dependencies are handled correctly by the build system finding their respective Kconfig.projbuild files. However, including it is safe.)

Modify CMakeLists.txt (Project Root):

Ensure the components directory is known to CMake (this is usually default if using idf.py create-project or examples). If not, you might need to add set(EXTRA_COMPONENT_DIRS components) near the top.

Build, Configure, Flash, Monitor:

  1. Configure: Run idf.py menuconfig. Navigate to the new Component config -> Custom Module Configuration menu. You should see the options you defined:
    • Enable/disable the feature.
    • Set the buffer size.
    • Change the device nickname.
    • Select Mode A or Mode B.
    • Try changing some values. Save and exit.
  2. Build: idf.py build. Observe the build output – it should compile your custom_module.c.
  3. Flash: idf.py -p <YOUR_PORT> flash
  4. Monitor: idf.py -p <YOUR_PORT> monitor

Expected Output:

The monitor output should show the logs from custom_module_init, reflecting the configuration values you set in menuconfig. The custom_module_do_work logs will then appear periodically. If you disabled the module in menuconfig, the initialization log will indicate it’s disabled, and custom_module_do_work will do nothing.

Plaintext
# Example output if enabled with defaults
I (xxx) MAIN: Main application started.
I (xxx) CUSTOM_MODULE: Initializing Custom Module...
I (xxx) CUSTOM_MODULE: Feature Enabled: Yes
I (xxx) CUSTOM_MODULE: Buffer Size: 1024 bytes
I (xxx) CUSTOM_MODULE: Device Nickname: 'My ESP32 Device'
I (xxx) CUSTOM_MODULE: Operating Mode: A (Standard)
I (xxx) CUSTOM_MODULE: Custom Module Initialized Successfully.
I (xxx) MAIN: Main loop started.
I (xxx) CUSTOM_MODULE: Custom module doing work...
I (xxx) CUSTOM_MODULE: Performing standard work...
... (repeats every 5 seconds) ...

If you change settings in menuconfig (e.g., set buffer size to 512, name to “Test Device”, mode to B) and rebuild/reflash, the output will change accordingly:

Plaintext
# Example output after changing config
I (xxx) MAIN: Main application started.
I (xxx) CUSTOM_MODULE: Initializing Custom Module...
I (xxx) CUSTOM_MODULE: Feature Enabled: Yes
I (xxx) CUSTOM_MODULE: Buffer Size: 512 bytes
I (xxx) CUSTOM_MODULE: Device Nickname: 'Test Device'
I (xxx) CUSTOM_MODULE: Operating Mode: B (Low Power)
I (xxx) CUSTOM_MODULE: Custom Module Initialized Successfully.
I (xxx) MAIN: Main loop started.
I (xxx) CUSTOM_MODULE: Custom module doing work...
I (xxx) CUSTOM_MODULE: Performing low power work...
... (repeats every 5 seconds) ...

Variant Notes

The Kconfig system, menuconfig tool, sdkconfig file generation, and the method for accessing configuration values via sdkconfig.h are consistent across all ESP32 variants supported by ESP-IDF (ESP32, S2, S3, C3, C6, H2). The underlying mechanism does not change based on the specific chip.

While the available configuration options will differ significantly between variants (e.g., options related to PSRAM, specific peripherals, number of cores), the way you define, configure, and access these options remains the same.

Common Mistakes & Troubleshooting Tips

Mistake / Issue Symptom(s) Troubleshooting / Solution
Forgetting Kconfig.projbuild
Component Kconfig exists, but link file is missing.
Component options don’t appear in menuconfig. Build might succeed, but CONFIG_ macros are undefined or have wrong defaults. Ensure every component with a Kconfig file has a corresponding Kconfig.projbuild file containing include $(COMPONENT_KCONFIG).
Manual Edits to sdkconfig / sdkconfig.h
Editing configuration outside menuconfig.
Changes overwritten on next menuconfig save or build. Inconsistent configuration. Always use idf.py menuconfig to change settings. Commit sdkconfig to version control; add sdkconfig.h and build/ to .gitignore.
Incorrect Kconfig Syntax
Typos, bad indentation, wrong keywords.
menuconfig fails, shows errors, or displays menus incorrectly. Build may fail at configuration stage. Check syntax carefully against examples/docs. Pay attention to help indentation. Run menuconfig to validate after edits.
Case Mismatch / Typos in CONFIG_ Macros
Using wrong name in C code.
Compilation errors (undefined macro). Code might be silently excluded if using #ifdef without #else. Verify exact symbol name from Kconfig. Remember CONFIG_ prefix is added, rest usually uppercase. Check generated build/config/sdkconfig.h if unsure.
Missing #include "sdkconfig.h"
Forgetting the header in C files.
Compilation errors (undefined macro CONFIG_...). Add #include "sdkconfig.h" to the top of any C/C++ file needing access to configuration values.
Incorrect depends on Logic
Dependency expression is wrong or uses CONFIG_ prefix.
Options appear/disappear unexpectedly in menuconfig based on other selections. Use correct Kconfig symbol names (without CONFIG_ prefix) in depends on statements. Use && (AND), || (OR), and parentheses () for complex logic.

Exercises

  1. Add String Length Limit: Modify the custom_module/Kconfig file. Add a new integer configuration option CUSTOM_MODULE_NAME_MAX_LEN that depends on CUSTOM_MODULE_ENABLE. Give it a default value (e.g., 32) and a reasonable range (e.g., 8-64). Modify custom_module.c to use this value when initializing the internal_buffer with snprintf to prevent potential buffer overflows if the CONFIG_CUSTOM_MODULE_DEVICE_NAME string is longer than expected (or longer than the new max length). Re-run menuconfig, build, and test.
  2. Add Component Dependency Config: Imagine custom_module needs a specific feature from the standard ESP-IDF “ESP Timer” component to be enabled. Find the Kconfig option for enabling the ESP Timer high-resolution timer (CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD or similar, check under Component config -> ESP System Settings -> High resolution timer in menuconfig). In custom_module/Kconfig, make CUSTOM_MODULE_ENABLE also depends on this ESP Timer option. Run menuconfig, disable the high-resolution timer, and observe that the “Custom Module Configuration” menu becomes greyed out or hidden. Re-enable it to make your component configurable again. (Note: You don’t need to change the C code for this exercise, just the Kconfig dependency).

Summary

  • ESP-IDF uses components for modular code organization.
  • The Kconfig system provides a robust way to manage configuration options for the project and its components.
  • idf.py menuconfig is the tool used to interactively view and modify Kconfig settings.
  • Configuration choices are saved in the sdkconfig file (add to version control).
  • The build system generates sdkconfig.h containing C preprocessor macros (CONFIG_...) corresponding to the settings (do not add to version control).
  • Components define their own options in a Kconfig file and make it known to the build system via Kconfig.projbuild.
  • Kconfig supports various types (bool, int, hex, string, choice), dependencies (depends on), defaults, ranges, help text, and menus.
  • Access configuration in C code by including sdkconfig.h and using the CONFIG_... macros.

Further Reading

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top