esp-idf/examples/system/gcov
..
components/sample
main
CMakeLists.txt
README.md
pytest_gcov.py
sdkconfig.ci
sdkconfig.defaults

README.md

Supported Targets ESP32 ESP32-C2 ESP32-C3 ESP32-C6 ESP32-H2 ESP32-P4 ESP32-S2 ESP32-S3

Blink Example With Coverage Info (Gcov)

(See the README.md file in the upper level 'examples' directory for more information about examples.)

The following example demonstrates how to compile an ESP-IDF project to generate code coverage data, and how generate a code coverage report using Gcov or Lcov. Refer to the Gcov Guide for more details on the code coverage features supported in ESP-IDF.

This example implements a simple blink application but with code coverage enabled. The example will demonstrate the following features:

  • How to compile a project with coverage info enabled.
  • Various methods of dumping code coverage data (e.g. Instant Run-Time Dump and Hard-coded Dump).
  • How to generate a code coverage report.

How to use example

Hardware Required

To run this example, you need a supported dev board connected to a JTAG adapter, which can come in the following forms:

This example will assume that that an ESP-WROVER-KIT is used.

  1. Connect the JTAG interface to ESP32 board, and power up both the JTAG and ESP32. For details about how to set up JTAG interface, please see JTAG Debugging.

  2. After connecting JTAG interface, you need to Run OpenOCD.

  3. Open a separate terminal window and run telnet by entering the command below. The telnet terminal window is used to feed commands to OpenOCD:

telnet localhost 4444

Configure the project

idf.py menuconfig

The example will enable the following options by default:

  • Enable the Application Tracing Module under Component config -> Application Level Tracing -> Data Destination by choosing JTAG.
  • Enable GCOV to host interface under Component config -> Application Level Tracing -> GCOV to Host Enable.
  • Enable OpenOCD Debug Stubs under Component config -> ESP System Settings -> OpenOCD debug stubs

Build, Flash, and Run

Build the project and flash it to the board, then run monitor tool to view serial output:

idf.py -p PORT flash monitor

(Replace PORT with the name of the serial port to use.)

(To exit the serial monitor, type Ctrl-].)

See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.

Example Output

1. Hard-coded Dump

The example will initially execute two hard-coded dumps. Therefore, when the application outputs Ready to dump GCOV data..., users should execute the esp gcov dump OpenOCD command. The example should output the following:

blink_dummy_func: Counter = 0
some_dummy_func: Counter = 0
Ready to dump GCOV data...
GCOV data have been dumped.
blink_dummy_func: Counter = 1
some_dummy_func: Counter = 2
Ready to dump GCOV data...
GCOV data have been dumped.

2. Instant Run-Time Dump

After the two hard-coded dumps, the example will continue looping through it's main blink function. Users can call esp gcov OpenOCD command to trigger an instant run-time dump. The output should resemble the following:

blink_dummy_func: Counter = 2
some_dummy_func: Counter = 4
blink_dummy_func: Counter = 3
some_dummy_func: Counter = 6
blink_dummy_func: Counter = 4
some_dummy_func: Counter = 8
blink_dummy_func: Counter = 5
some_dummy_func: Counter = 10
blink_dummy_func: Counter = 6
some_dummy_func: Counter = 12
blink_dummy_func: Counter = 7
some_dummy_func: Counter = 14
blink_dummy_func: Counter = 8
some_dummy_func: Counter = 16
blink_dummy_func: Counter = 9
some_dummy_func: Counter = 18
blink_dummy_func: Counter = 10
some_dummy_func: Counter = 20
...

Generating Gcovr Report

After dumping one or more times, a coverage report can be generated by calling cmake --build build/ --target gcovr-report. This should result in an HTML code coverage report being generated in the build directory.

To clean Gcov and report related data from the build directory, call cmake --build build/ --target cov-data-clean

The following log should be output when generating the coverage report:

[1/2] Generating coverage report in: /home/user/esp/esp-idf/examples/system/gcov/build/coverage_report
Using gcov: xtensa-esp32-elf-gcov
[2/2] cd /home/user/esp/esp-idf/examples/system/gcov/build && gcovr -r /home/user/esp/esp-idf/examples/system/gcov...a-esp32-elf-gcov -s --html-details /home/user/esp/esp-idf/examples/system/gcov/build/coverage_report/html/index.htm
lines: 100.0% (27 out of 27)
branches: 100.0% (2 out of 2)

Troubleshooting

OpenOCD Out of Sync

If the following log is output when issuing an OpenOCD command via telnet, it could indicate that OpenOCD and the ESP32 are out of sync. This occurs when the ESP32 is externally reset whilst connected to OpenOCD (e.g., by pressing the EN button).

Open On-Chip Debugger
> esp gcov dump
Target halted. PRO_CPU: PC=0x4008AFF4 (active)    APP_CPU: PC=0x400E396E
Total trace memory: 16384 bytes
Connect targets...
Target halted. PRO_CPU: PC=0x400D5D74 (active)    APP_CPU: PC=0x400E396E
timed out while waiting for target halted / 1 - 2
Failed to wait halt on bp target (-4)!
Failed to halt targets (-4)!
Failed to connect to targets (-4)!

This issue can be resolved in the following ways:

  • Reset the board by issuing the reset command via telnet
  • Restart OpenOCD

gcovr not found

gcovr can be installed from the package database of your operating system or directly as a Python package, e.g:

    python -m pip install gcovr