From fb3b5d93cc3e3fa198a1e13b6698038eec5b75db Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Wed, 17 Dec 2025 10:15:21 +0100 Subject: [PATCH] test(freertos): Added support for gcov code coverage for FreeRTOS source files This commit adds the following: - Added support to FreeRTOS component to report code coverage using gcov and app trace. - Added a new sdkconfig.ci.code_coverage for code coverage tests. - Added a new Kconfig option CONFIG_FREERTOS_ENABLE_COVERAGE_TESTS to control the code instrumentation. - Added an idf_component.yml file to the test_app to fetch the esp_gcov component from the component registry. - Updated the README to explain how to take code coverage data. --- .../test_apps/freertos/CMakeLists.txt | 33 ++++++ .../freertos/test_apps/freertos/README.md | 68 ++++++++++++ .../test_apps/freertos/main/Kconfig.projbuild | 14 +++ .../test_apps/freertos/main/idf_component.yml | 7 ++ .../freertos/sdkconfig.ci.code_coverage | 103 ++++++++++++++++++ 5 files changed, 225 insertions(+) create mode 100644 components/freertos/test_apps/freertos/main/Kconfig.projbuild create mode 100644 components/freertos/test_apps/freertos/main/idf_component.yml create mode 100644 components/freertos/test_apps/freertos/sdkconfig.ci.code_coverage diff --git a/components/freertos/test_apps/freertos/CMakeLists.txt b/components/freertos/test_apps/freertos/CMakeLists.txt index 26cd3663400..b9f35b5f9e5 100644 --- a/components/freertos/test_apps/freertos/CMakeLists.txt +++ b/components/freertos/test_apps/freertos/CMakeLists.txt @@ -19,3 +19,36 @@ set(EXTRA_COMPONENT_DIRS set(COMPONENTS main esp_psram) project(freertos_test) + +# ============================================================================ +# Code Coverage Instrumentation +# ============================================================================ +# When CONFIG_FREERTOS_ENABLE_COVERAGE_TESTS is enabled, instrument FreeRTOS +# kernel, port, and ESP additions source files for coverage analysis. + +if(CONFIG_FREERTOS_ENABLE_COVERAGE_TESTS) + # Get the FreeRTOS component library and directory + idf_component_get_property(freertos_lib freertos COMPONENT_LIB) + idf_component_get_property(freertos_dir freertos COMPONENT_DIR) + + # Add coverage flags to the entire FreeRTOS component + target_compile_options(${freertos_lib} PRIVATE "--coverage") + target_link_options(${freertos_lib} PRIVATE "--coverage") + + # Create coverage report generation targets + file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/coverage_report" _coverage_report_path) + + idf_create_coverage_report( + ${_coverage_report_path} + SOURCE_DIR ${freertos_dir} + GCOV_OPTIONS "--gcov-ignore-parse-errors=negative_hits.warn" + ) + idf_clean_coverage_report(${_coverage_report_path}) + + message(STATUS "================================================") + message(STATUS "FreeRTOS code coverage instrumentation enabled for test app") + message(STATUS "Coverage report will be generated in: ${_coverage_report_path}") + message(STATUS "Coverage root directory: ${freertos_dir}") + message(STATUS "Use 'idf.py gcovr-report' to generate coverage report after running tests") + message(STATUS "Use 'idf.py cov-data-clean' to clean coverage data") +endif() diff --git a/components/freertos/test_apps/freertos/README.md b/components/freertos/test_apps/freertos/README.md index 44f3780f1d6..31c1c55afea 100644 --- a/components/freertos/test_apps/freertos/README.md +++ b/components/freertos/test_apps/freertos/README.md @@ -1,2 +1,70 @@ | Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | + + + +## Manual Code Coverage Workflow + +This test_app can be set up to enable FreeRTOS code coverage using GCOV via JTAG and AppTrace. + +Follow these steps to manually build, flash, run, and collect code coverage from a FreeRTOS app: + +### 1. **Configure the project and build the application** +The sdkconfig.ci.code_coverage enables code coverage settings and other FreeRTOS options to maximize coverage. +```sh +idf.py set-target # e.g., esp32s3 +idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.ci.code_coverage" build flash monitor +``` + +### 2. **Flash the Device** +```sh +idf.py -p flash +``` + +### 3. **Launch OpenOCD** +Start OpenOCD in a new terminal (adjust for your board/target if needed): +```sh +openocd -f board/esp32-builtin.cfg +``` + +### 4. **Run Tests** +Interact with the device over serial (`idf.py monitor -p `) and run tests. + +### 5. **Collect Coverage Data** +Flush coverage data regularly, and collect `.gcda` files from the device using a telnet session +```sh +telnet localhost 4444 +``` +Then run +```sh +esp gcov +``` + +All `.gcda` files will be retrieved into your build directory. +Make sure to regularly collect `.gcda` files to avoid memory overflow problems. +Coverage data should be collected before tests that reset the target. +The coverage data is cumulative. + +### 6. **Generate Coverage Report** +Adjust the `gcov` tool to be used based on the target +```sh +xtensa-esp32s3-elf-gcov -b \ + ../esp-idf/freertos/CMakeFiles/__idf_freertos.dir/FreeRTOS-Kernel/*.gcda + +xtensa-esp32s3-elf-gcov -b \ + ../esp-idf/freertos/CMakeFiles/__idf_freertos.dir/esp_additions/*gcda +``` +Then run: +```sh +mkdir coverage_report +cd coverage_report +mkdir html +▶ gcovr \ + --gcov-use-existing-files \ + --gcov-keep \ + --root $IDF_PATH/components/freertos \ + --html-details \ + --output html/index.html \ + . +``` +This generates a detailed, navigable HTML coverage report in `html` folder. diff --git a/components/freertos/test_apps/freertos/main/Kconfig.projbuild b/components/freertos/test_apps/freertos/main/Kconfig.projbuild new file mode 100644 index 00000000000..26d6da5b3ab --- /dev/null +++ b/components/freertos/test_apps/freertos/main/Kconfig.projbuild @@ -0,0 +1,14 @@ +menu "FreeRTOS Test App Configuration" + + config FREERTOS_ENABLE_COVERAGE_TESTS + bool "Enable code coverage instrumentation for FreeRTOS" + depends on ESP_GCOV_ENABLE + default n + help + When enabled, FreeRTOS kernel, port, and ESP additions source files will be compiled with + code coverage instrumentation flags (--coverage) to enable GCOV code coverage testing. + + Note: This option will increase binary size and may impact performance. It should only be + enabled when running coverage tests. + +endmenu diff --git a/components/freertos/test_apps/freertos/main/idf_component.yml b/components/freertos/test_apps/freertos/main/idf_component.yml new file mode 100644 index 00000000000..783a7408131 --- /dev/null +++ b/components/freertos/test_apps/freertos/main/idf_component.yml @@ -0,0 +1,7 @@ +## IDF Component Manager Manifest File +dependencies: + ## Required IDF version + idf: + version: '>=6.0' + # # Put list of dependencies here + espressif/esp_gcov: ^1 diff --git a/components/freertos/test_apps/freertos/sdkconfig.ci.code_coverage b/components/freertos/test_apps/freertos/sdkconfig.ci.code_coverage new file mode 100644 index 00000000000..427f74c318d --- /dev/null +++ b/components/freertos/test_apps/freertos/sdkconfig.ci.code_coverage @@ -0,0 +1,103 @@ +# Code Coverage Configuration for FreeRTOS Tests +# This is a configuration file for maximum code coverage. +# It includes all necessary settings for GCOV coverage instrumentation and enables +# many optional FreeRTOS features, hooks, and debugging options to maximize coverage. + +# ============================================================================ +# GCOV Coverage Infrastructure +# ============================================================================ +CONFIG_ESP_TRACE_TRANSPORT_APPTRACE=y +CONFIG_APPTRACE_DEST_JTAG=y +CONFIG_APPTRACE_LOCK_ENABLE=y +CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO=-1 +CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH=0 +CONFIG_ESP_GCOV_ENABLE=y + +# GCOV needs __getreent() which currently newlib provides, and not picolibc +CONFIG_LIBC_NEWLIB=y + +# ============================================================================ +# FreeRTOS Coverage Instrumentation +# ============================================================================ +# Enable code coverage instrumentation for FreeRTOS kernel, port, and ESP additions +CONFIG_FREERTOS_ENABLE_COVERAGE_TESTS=y + +# ============================================================================ +# Compiler Optimizations (Debug mode for maximum coverage) +# ============================================================================ +# Use debug optimizations to prevent code elimination +CONFIG_COMPILER_OPTIMIZATION_DEBUG=y +# Keep assertions enabled to test error paths +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y + +# Bootloader should use size optimization to keep bootloader size small +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y + +# ============================================================================ +# FreeRTOS Kernel Options (from sdkconfig.ci.freertos_options) +# ============================================================================ +# Core timer selection +CONFIG_FREERTOS_CORETIMER_1=y +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=n + +# Stack overflow checking +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL=y +CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y + +# Interrupt backtrace +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y + +# Static allocation support +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y + +# Task pre-deletion hook +CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK=y + +# Queue registry +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=10 + +# Trace facility and stats +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U64=y + +# FreeRTOS in IRAM +CONFIG_FREERTOS_IN_IRAM=y + +# FPU in ISR +CONFIG_FREERTOS_FPU_IN_ISR=y + +# Task notifications +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2 + +# List data integrity checks +CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES=y + +# Timer task affinity +CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1=y + +# Tick hook - enables vApplicationTickHook() +CONFIG_FREERTOS_USE_TICK_HOOK=y + +# Idle hook - enables vApplicationIdleHook() +CONFIG_FREERTOS_USE_IDLE_HOOK=y + +# Application task tag +CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG=y + +# ============================================================================ +# FreeRTOS Port Options +# ============================================================================ +# Task function wrapper +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y + +# Thread local storage deletion callbacks +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y + +# Mutex owner check +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y + +# Port critical compliance check +CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE=y