mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-17 07:28:02 +00:00
Merge branch 'move_gcov_to_component_registry' into 'master'
Move gcov to component registry Closes IDF-13404 and DOC-11978 See merge request espressif/esp-idf!40752
This commit is contained in:
@@ -14,15 +14,6 @@ if(CONFIG_ESP_DEBUG_STUBS_ENABLE)
|
||||
"debug_stubs.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_APPTRACE_GCOV_ENABLE)
|
||||
if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
|
||||
list(APPEND srcs
|
||||
"gcov/gcov_rtio.c")
|
||||
else()
|
||||
fail_at_build_time(app_trace "Only GNU compiler can link with Gcov library")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(include_dirs "include")
|
||||
|
||||
set(priv_include_dirs "private_include" "port/include")
|
||||
@@ -71,53 +62,3 @@ idf_component_register(SRCS "${srcs}"
|
||||
PRIV_REQUIRES esp_driver_gptimer esp_driver_gpio esp_driver_uart
|
||||
REQUIRES esp_timer
|
||||
LDFRAGMENTS linker.lf)
|
||||
|
||||
# Force app_trace to also appear later than gcov in link line
|
||||
idf_component_get_property(app_trace app_trace COMPONENT_LIB)
|
||||
|
||||
if(CONFIG_APPTRACE_GCOV_ENABLE)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
# Coverage info is not supported when clang is used
|
||||
# TODO: LLVM-214
|
||||
message(FATAL_ERROR "Coverage info is not supported when building with Clang!")
|
||||
endif()
|
||||
|
||||
# The original Gcov library from toolchain will be objcopy with symbols redefinitions (see file gcov/io_sym.map).
|
||||
# This needs because ESP has no file-system onboard, and redefined functions solves this problem and transmits
|
||||
# output file to host PC.
|
||||
|
||||
# Set a name for Gcov library
|
||||
set(GCOV_LIB libgcov_rtio)
|
||||
|
||||
# Set include direcrory of Gcov internal headers
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=plugin
|
||||
OUTPUT_VARIABLE gcc_plugin_dir
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_QUIET)
|
||||
set_source_files_properties(gcov/gcov_rtio.c
|
||||
PROPERTIES COMPILE_FLAGS "-I${gcc_plugin_dir}/include")
|
||||
|
||||
# Copy libgcov.a with symbols redefinition
|
||||
find_library(GCOV_LIBRARY_PATH gcov ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES})
|
||||
add_custom_command(OUTPUT ${GCOV_LIB}.a
|
||||
COMMAND ${_CMAKE_TOOLCHAIN_PREFIX}objcopy
|
||||
--redefine-syms ${CMAKE_CURRENT_LIST_DIR}/gcov/io_sym.map
|
||||
${GCOV_LIBRARY_PATH} ${GCOV_LIB}.a
|
||||
MAIN_DEPENDENCY ${GCOV_LIBRARY_PATH}
|
||||
VERBATIM)
|
||||
add_custom_target(${GCOV_LIB}_target DEPENDS ${GCOV_LIB}.a)
|
||||
add_library(${GCOV_LIB} STATIC IMPORTED)
|
||||
set_target_properties(${GCOV_LIB}
|
||||
PROPERTIES
|
||||
IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${GCOV_LIB}.a)
|
||||
add_dependencies(${GCOV_LIB} ${GCOV_LIB}_target)
|
||||
add_dependencies(${COMPONENT_LIB} ${GCOV_LIB})
|
||||
|
||||
# disable --coverage for this component, as it is used as transport for gcov
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-profile-arcs" "-fno-test-coverage")
|
||||
target_link_options(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=__gcov_init")
|
||||
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE ${GCOV_LIB} $<TARGET_FILE:${app_trace}> c)
|
||||
else()
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE $<TARGET_FILE:${app_trace}> c)
|
||||
endif()
|
||||
|
@@ -373,19 +373,4 @@ menu "Application Level Tracing"
|
||||
|
||||
endmenu
|
||||
|
||||
config APPTRACE_GCOV_ENABLE
|
||||
bool "GCOV to Host Enable"
|
||||
depends on APPTRACE_ENABLE && !APPTRACE_SV_ENABLE
|
||||
select ESP_DEBUG_STUBS_ENABLE
|
||||
default n
|
||||
help
|
||||
Enables support for GCOV data transfer to host.
|
||||
|
||||
config APPTRACE_GCOV_DUMP_TASK_STACK_SIZE
|
||||
int "Gcov dump task stack size"
|
||||
depends on APPTRACE_GCOV_ENABLE
|
||||
default 2048
|
||||
help
|
||||
Configures stack size of Gcov dump task
|
||||
|
||||
endmenu
|
||||
|
@@ -9,11 +9,11 @@
|
||||
//
|
||||
|
||||
#include "esp_private/startup_internal.h"
|
||||
#include "dbg_stubs.h"
|
||||
#include "esp_dbg_stubs.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
/*
|
||||
Debug stubs is actually a table of 4-byte entries. Every entry is equal to zero or must contain meaningfull data.
|
||||
Debug stubs is actually a table of 4-byte entries. Every entry is equal to zero or must contain meaningful data.
|
||||
The first entry is a service one and has the followinf format:
|
||||
- tramp_addr, 4 bytes; Address of buffer for trampoline/code. Max size is ESP_DBG_STUBS_CODE_BUF_SIZE.
|
||||
- min_stack_addr, 4 bytes; Start of the buffer for minimal onboard stack or data. Max size is ESP_DBG_STUBS_STACK_MIN_SIZE.
|
||||
|
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// This module implements runtime file I/O API for GCOV.
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_task_wdt.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "soc/timer_periph.h"
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_freertos_hooks.h"
|
||||
#include "dbg_stubs.h"
|
||||
#include "esp_private/esp_ipc.h"
|
||||
#include "esp_attr.h"
|
||||
#include "hal/wdt_hal.h"
|
||||
|
||||
#if CONFIG_APPTRACE_GCOV_ENABLE
|
||||
|
||||
#define ESP_GCOV_DOWN_BUF_SIZE 4200
|
||||
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "esp_gcov_rtio";
|
||||
static volatile bool s_create_gcov_task = false;
|
||||
static volatile bool s_gcov_task_running = false;
|
||||
|
||||
extern void __gcov_dump(void);
|
||||
extern void __gcov_reset(void);
|
||||
|
||||
void gcov_dump_task(void *pvParameter)
|
||||
{
|
||||
int dump_result = 0;
|
||||
bool *running = (bool *)pvParameter;
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "%s stack use in %d", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "Alloc apptrace down buf %d bytes", ESP_GCOV_DOWN_BUF_SIZE);
|
||||
void *down_buf = malloc(ESP_GCOV_DOWN_BUF_SIZE);
|
||||
if (down_buf == NULL) {
|
||||
ESP_EARLY_LOGE(TAG, "Could not allocate memory for the buffer");
|
||||
dump_result = ESP_ERR_NO_MEM;
|
||||
goto gcov_exit;
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "Config apptrace down buf");
|
||||
esp_err_t res = esp_apptrace_down_buffer_config(ESP_APPTRACE_DEST_JTAG, down_buf, ESP_GCOV_DOWN_BUF_SIZE);
|
||||
if (res != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to config apptrace down buf (%d)!", res);
|
||||
dump_result = res;
|
||||
goto gcov_exit;
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "Dump data...");
|
||||
__gcov_dump();
|
||||
// reset dump status to allow incremental data accumulation
|
||||
__gcov_reset();
|
||||
free(down_buf);
|
||||
ESP_EARLY_LOGV(TAG, "Finish file transfer session");
|
||||
dump_result = esp_apptrace_fstop(ESP_APPTRACE_DEST_JTAG);
|
||||
if (dump_result != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", dump_result);
|
||||
}
|
||||
|
||||
gcov_exit:
|
||||
ESP_EARLY_LOGV(TAG, "dump_result %d", dump_result);
|
||||
if (running) {
|
||||
*running = false;
|
||||
}
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "%s stack use out %d", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void gcov_create_task(void *arg)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
xTaskCreatePinnedToCore(&gcov_dump_task, "gcov_dump_task", CONFIG_APPTRACE_GCOV_DUMP_TASK_STACK_SIZE,
|
||||
(void *)&s_gcov_task_running, configMAX_PRIORITIES - 1, NULL, 0);
|
||||
}
|
||||
|
||||
static IRAM_ATTR
|
||||
void gcov_create_task_tick_hook(void)
|
||||
{
|
||||
if (s_create_gcov_task) {
|
||||
if (esp_ipc_call_nonblocking(xPortGetCoreID(), &gcov_create_task, NULL) == ESP_OK) {
|
||||
s_create_gcov_task = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Triggers gcov info dump task
|
||||
* This function is to be called by OpenOCD, not by normal user code.
|
||||
* TODO: what about interrupted flash access (when cache disabled)
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
static int esp_dbg_stub_gcov_entry(void)
|
||||
{
|
||||
/* we are in isr context here */
|
||||
s_create_gcov_task = true;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void gcov_rtio_init(void)
|
||||
{
|
||||
uint32_t stub_entry = 0;
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
assert(esp_dbg_stub_entry_get(ESP_DBG_STUB_ENTRY_GCOV, &stub_entry) == ESP_OK);
|
||||
if (stub_entry != 0) {
|
||||
/* "__gcov_init()" can be called several times. We must avoid multiple tick hook registration */
|
||||
return;
|
||||
}
|
||||
esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_GCOV, (uint32_t)&esp_dbg_stub_gcov_entry);
|
||||
assert(esp_dbg_stub_entry_get(ESP_DBG_STUB_ENTRY_CAPABILITIES, &stub_entry) == ESP_OK);
|
||||
esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_CAPABILITIES, stub_entry | ESP_DBG_STUB_CAP_GCOV_TASK);
|
||||
esp_register_freertos_tick_hook(gcov_create_task_tick_hook);
|
||||
}
|
||||
|
||||
void esp_gcov_dump(void)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
|
||||
while (!esp_apptrace_host_is_connected(ESP_APPTRACE_DEST_JTAG)) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
|
||||
/* We are not in isr context here. Waiting for the completion is safe */
|
||||
s_gcov_task_running = true;
|
||||
s_create_gcov_task = true;
|
||||
while (s_gcov_task_running) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
}
|
||||
|
||||
void *gcov_rtio_fopen(const char *path, const char *mode)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s '%s' '%s'", __FUNCTION__, path, mode);
|
||||
void *f = esp_apptrace_fopen(ESP_APPTRACE_DEST_JTAG, path, mode);
|
||||
ESP_EARLY_LOGV(TAG, "%s ret %p", __FUNCTION__, f);
|
||||
return f;
|
||||
}
|
||||
|
||||
int gcov_rtio_fclose(void *stream)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
return esp_apptrace_fclose(ESP_APPTRACE_DEST_JTAG, stream);
|
||||
}
|
||||
|
||||
size_t gcov_rtio_fread(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s read %u", __FUNCTION__, size * nmemb);
|
||||
size_t sz = esp_apptrace_fread(ESP_APPTRACE_DEST_JTAG, ptr, size, nmemb, stream);
|
||||
ESP_EARLY_LOGV(TAG, "%s actually read %u", __FUNCTION__, sz);
|
||||
return sz;
|
||||
}
|
||||
|
||||
size_t gcov_rtio_fwrite(const void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
return esp_apptrace_fwrite(ESP_APPTRACE_DEST_JTAG, ptr, size, nmemb, stream);
|
||||
}
|
||||
|
||||
int gcov_rtio_fseek(void *stream, long offset, int whence)
|
||||
{
|
||||
int ret = esp_apptrace_fseek(ESP_APPTRACE_DEST_JTAG, stream, offset, whence);
|
||||
ESP_EARLY_LOGV(TAG, "%s(%p %ld %d) = %d", __FUNCTION__, stream, offset, whence, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
long gcov_rtio_ftell(void *stream)
|
||||
{
|
||||
long ret = esp_apptrace_ftell(ESP_APPTRACE_DEST_JTAG, stream);
|
||||
ESP_EARLY_LOGV(TAG, "%s(%p) = %ld", __FUNCTION__, stream, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int gcov_rtio_feof(void *stream)
|
||||
{
|
||||
int ret = esp_apptrace_feof(ESP_APPTRACE_DEST_JTAG, stream);
|
||||
ESP_EARLY_LOGV(TAG, "%s(%p) = %d", __FUNCTION__, stream, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void gcov_rtio_setbuf(void *arg1 __attribute__((unused)), void *arg2 __attribute__((unused)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Wrappers for Gcov functions */
|
||||
|
||||
extern void __real___gcov_init(void *info);
|
||||
void __wrap___gcov_init(void *info)
|
||||
{
|
||||
__real___gcov_init(info);
|
||||
gcov_rtio_init();
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,8 +0,0 @@
|
||||
fopen gcov_rtio_fopen
|
||||
fclose gcov_rtio_fclose
|
||||
fwrite gcov_rtio_fwrite
|
||||
fread gcov_rtio_fread
|
||||
fseek gcov_rtio_fseek
|
||||
ftell gcov_rtio_ftell
|
||||
setbuf gcov_rtio_setbuf
|
||||
feof gcov_rtio_feof
|
@@ -267,12 +267,6 @@ int esp_apptrace_fstop(esp_apptrace_dest_t dest);
|
||||
*/
|
||||
int esp_apptrace_feof(esp_apptrace_dest_t dest, void *stream);
|
||||
|
||||
/**
|
||||
* @brief Triggers gcov info dump.
|
||||
* This function waits for the host to connect to target before dumping data.
|
||||
*/
|
||||
void esp_gcov_dump(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -44,18 +44,18 @@ void esp_dbg_stubs_init(void);
|
||||
*
|
||||
* @param id Stub ID.
|
||||
* @param entry Stub entry. Usually it is stub entry function address,
|
||||
* but can be any value meaningfull for OpenOCD command/code
|
||||
* but can be any value meaningful for OpenOCD command/code
|
||||
* such as capabilities
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_dbg_stub_entry_set(esp_dbg_stub_id_t id, uint32_t entry);
|
||||
|
||||
/**
|
||||
* @brief Retrives the corresponding stub entry
|
||||
* @brief Retrieves the corresponding stub entry
|
||||
*
|
||||
* @param id Stub ID.
|
||||
* @param entry Stub entry. Usually it is stub entry function address,
|
||||
* but can be any value meaningfull for OpenOCD command/code
|
||||
* but can be any value meaningful for OpenOCD command/code
|
||||
* such as capabilities
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
@@ -1,41 +0,0 @@
|
||||
# idf_create_lcov_report
|
||||
#
|
||||
# Create coverage report.
|
||||
function(idf_create_coverage_report report_dir)
|
||||
set(gcov_tool ${_CMAKE_TOOLCHAIN_PREFIX}gcov)
|
||||
idf_build_get_property(project_name PROJECT_NAME)
|
||||
|
||||
file(TO_NATIVE_PATH "${report_dir}" _report_dir)
|
||||
file(TO_NATIVE_PATH "${project_dir}" _project_dir)
|
||||
file(TO_NATIVE_PATH "${report_dir}/html/index.html" _index_path)
|
||||
|
||||
add_custom_target(pre-cov-report
|
||||
COMMENT "Generating coverage report in: ${_report_dir}"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Using gcov: ${gcov_tool}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${_report_dir}/html
|
||||
)
|
||||
|
||||
add_custom_target(lcov-report
|
||||
COMMENT "WARNING: lcov-report is deprecated. Please use gcovr-report instead."
|
||||
COMMAND lcov --gcov-tool ${gcov_tool} -c -d ${CMAKE_CURRENT_BINARY_DIR} -o ${_report_dir}/${project_name}.info
|
||||
COMMAND genhtml -o ${_report_dir}/html ${_report_dir}/${project_name}.info
|
||||
DEPENDS pre-cov-report
|
||||
)
|
||||
|
||||
add_custom_target(gcovr-report
|
||||
COMMAND gcovr -r ${_project_dir} --gcov-executable ${gcov_tool} -s --html-details ${_index_path}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS pre-cov-report
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# idf_clean_coverage_report
|
||||
#
|
||||
# Clean coverage report.
|
||||
function(idf_clean_coverage_report report_dir)
|
||||
file(TO_CMAKE_PATH "${report_dir}" _report_dir)
|
||||
|
||||
add_custom_target(cov-data-clean
|
||||
COMMENT "Clean coverage report in: ${_report_dir}"
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${_report_dir})
|
||||
endfunction()
|
@@ -8,7 +8,6 @@ CONFIG_ESP32_APPTRACE_ENABLE CONFIG_APPTRACE_ENABLE
|
||||
CONFIG_ESP32_APPTRACE_LOCK_ENABLE CONFIG_APPTRACE_LOCK_ENABLE
|
||||
CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO
|
||||
CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH
|
||||
CONFIG_ESP32_GCOV_ENABLE CONFIG_APPTRACE_GCOV_ENABLE
|
||||
|
||||
CONFIG_SYSVIEW_ENABLE CONFIG_APPTRACE_SV_ENABLE
|
||||
CONFIG_SYSVIEW_TS_SOURCE CONFIG_APPTRACE_SV_TS_SOURCE
|
||||
|
@@ -662,8 +662,7 @@ menu "IPC (Inter-Processor Call)"
|
||||
|
||||
config ESP_IPC_ENABLE
|
||||
bool
|
||||
default y
|
||||
depends on !ESP_SYSTEM_SINGLE_CORE_MODE || APPTRACE_GCOV_ENABLE
|
||||
default y if !ESP_SYSTEM_SINGLE_CORE_MODE
|
||||
|
||||
config ESP_IPC_TASK_STACK_SIZE
|
||||
int "Inter-Processor Call (IPC) task stack size"
|
||||
|
@@ -12,7 +12,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_FREERTOS_UNICORE) || defined(CONFIG_APPTRACE_GCOV_ENABLE)
|
||||
#if defined(CONFIG_ESP_IPC_ENABLE)
|
||||
|
||||
/*
|
||||
* Inter-processor call APIs
|
||||
@@ -71,7 +71,7 @@ esp_err_t esp_ipc_call(uint32_t cpu_id, esp_ipc_func_t func, void* arg);
|
||||
*/
|
||||
esp_err_t esp_ipc_call_blocking(uint32_t cpu_id, esp_ipc_func_t func, void* arg);
|
||||
|
||||
#endif // !defined(CONFIG_FREERTOS_UNICORE) || defined(CONFIG_APPTRACE_GCOV_ENABLE)
|
||||
#endif // defined(CONFIG_ESP_IPC_ENABLE)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_FREERTOS_UNICORE) || defined(CONFIG_APPTRACE_GCOV_ENABLE)
|
||||
#if defined(CONFIG_ESP_IPC_ENABLE)
|
||||
|
||||
/**
|
||||
* @brief Execute a callback on a given CPU without any blocking operations for the caller
|
||||
@@ -40,7 +40,7 @@ extern "C" {
|
||||
*/
|
||||
esp_err_t esp_ipc_call_nonblocking(uint32_t cpu_id, esp_ipc_func_t func, void* arg);
|
||||
|
||||
#endif // !defined(CONFIG_FREERTOS_UNICORE) || defined(CONFIG_APPTRACE_GCOV_ENABLE)
|
||||
#endif // defined(CONFIG_ESP_IPC_ENABLE)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -461,133 +461,9 @@ Good instructions on how to install, configure, and visualize data in Impulse fr
|
||||
|
||||
If you have problems with visualization (no data is shown or strange behaviors of zoom action are observed), you can try to delete current signal hierarchy and double-click on the necessary file or port. Eclipse will ask you to create a new signal hierarchy.
|
||||
|
||||
|
||||
.. _app_trace-gcov-source-code-coverage:
|
||||
|
||||
Gcov (Source Code Coverage)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Basics of Gcov and Gcovr
|
||||
""""""""""""""""""""""""
|
||||
|
||||
Source code coverage is data indicating the count and frequency of every program execution path that has been taken within a program's runtime. `Gcov <https://en.wikipedia.org/wiki/Gcov>`_ is a GCC tool that, when used in concert with the compiler, can generate log files indicating the execution count of each line of a source file. The `Gcovr <https://gcovr.com/>`_ tool is a utility for managing Gcov and generating summarized code coverage results.
|
||||
|
||||
Generally, using Gcov to compile and run programs on the host will undergo these steps:
|
||||
|
||||
1. Compile the source code using GCC with the ``--coverage`` option enabled. This will cause the compiler to generate a ``.gcno`` notes files during compilation. The notes files contain information to reconstruct execution path block graphs and map each block to source code line numbers. Each source file compiled with the ``--coverage`` option should have their own ``.gcno`` file of the same name (e.g., a ``main.c`` will generate a ``main.gcno`` when compiled).
|
||||
|
||||
2. Execute the program. During execution, the program should generate ``.gcda`` data files. These data files contain the counts of the number of times an execution path was taken. The program will generate a ``.gcda`` file for each source file compiled with the ``--coverage`` option (e.g., ``main.c`` will generate a ``main.gcda``).
|
||||
|
||||
3. Gcov or Gcovr can be used to generate a code coverage based on the ``.gcno``, ``.gcda``, and source files. Gcov will generate a text-based coverage report for each source file in the form of a ``.gcov`` file, whilst Gcovr will generate a coverage report in HTML format.
|
||||
|
||||
|
||||
Gcov and Gcovr in ESP-IDF
|
||||
"""""""""""""""""""""""""""
|
||||
|
||||
Using Gcov in ESP-IDF is complicated due to the fact that the program is running remotely from the host (i.e., on the target). The code coverage data (i.e., the ``.gcda`` files) is initially stored on the target itself. OpenOCD is then used to dump the code coverage data from the target to the host via JTAG during runtime. Using Gcov in ESP-IDF can be split into the following steps.
|
||||
|
||||
1. :ref:`app_trace-gcov-setup-project`
|
||||
2. :ref:`app_trace-gcov-dumping-data`
|
||||
3. :ref:`app_trace-gcov-generate-report`
|
||||
|
||||
|
||||
.. _app_trace-gcov-setup-project:
|
||||
|
||||
Setting Up a Project for Gcov
|
||||
"""""""""""""""""""""""""""""
|
||||
|
||||
Compiler Option
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
In order to obtain code coverage data in a project, one or more source files within the project must be compiled with the ``--coverage`` option. In ESP-IDF, this can be achieved at the component level or the individual source file level:
|
||||
|
||||
- To cause all source files in a component to be compiled with the ``--coverage`` option, you can add ``target_compile_options(${COMPONENT_LIB} PRIVATE --coverage)`` to the ``CMakeLists.txt`` file of the component.
|
||||
- To cause a select number of source files (e.g., ``source1.c`` and ``source2.c``) in the same component to be compiled with the ``--coverage`` option, you can add ``set_source_files_properties(source1.c source2.c PROPERTIES COMPILE_FLAGS --coverage)`` to the ``CMakeLists.txt`` file of the component.
|
||||
|
||||
When a source file is compiled with the ``--coverage`` option (e.g., ``gcov_example.c``), the compiler will generate the ``gcov_example.gcno`` file in the project's build directory.
|
||||
|
||||
|
||||
Project Configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Before building a project with source code coverage, make sure that the following project configuration options are enabled by running ``idf.py menuconfig``.
|
||||
|
||||
- Enable the application tracing module by selecting ``Trace Memory`` for the :ref:`CONFIG_APPTRACE_DESTINATION1` option.
|
||||
- Enable Gcov to the host via the :ref:`CONFIG_APPTRACE_GCOV_ENABLE`.
|
||||
|
||||
|
||||
.. _app_trace-gcov-dumping-data:
|
||||
|
||||
Dumping Code Coverage Data
|
||||
""""""""""""""""""""""""""
|
||||
|
||||
Once a project has been complied with the ``--coverage`` option and flashed onto the target, code coverage data will be stored internally on the target (i.e., in trace memory) whilst the application runs. The process of transferring code coverage data from the target to the host is known as dumping.
|
||||
|
||||
The dumping of coverage data is done via OpenOCD (see :doc:`JTAG Debugging <../api-guides/jtag-debugging/index>` on how to setup and run OpenOCD). A dump is triggered by issuing commands to OpenOCD, therefore a telnet session to OpenOCD must be opened to issue such commands (run ``telnet localhost 4444``). Note that GDB could be used instead of telnet to issue commands to OpenOCD, however all commands issued from GDB will need to be prefixed as ``mon <oocd_command>``.
|
||||
|
||||
When the target dumps code coverage data, the ``.gcda`` files are stored in the project's build directory. For example, if ``gcov_example_main.c`` of the ``main`` component is compiled with the ``--coverage`` option, then dumping the code coverage data would generate a ``gcov_example_main.gcda`` in ``build/esp-idf/main/CMakeFiles/__idf_main.dir/gcov_example_main.c.gcda``. Note that the ``.gcno`` files produced during compilation are also placed in the same directory.
|
||||
|
||||
The dumping of code coverage data can be done multiple times throughout an application's lifetime. Each dump will simply update the ``.gcda`` file with the newest code coverage information. Code coverage data is accumulative, thus the newest data will contain the total execution count of each code path over the application's entire lifetime.
|
||||
|
||||
ESP-IDF supports two methods of dumping code coverage data form the target to the host:
|
||||
|
||||
* Instant Run-Time Dumpgit
|
||||
* Hard-coded Dump
|
||||
|
||||
|
||||
Instant Run-Time Dump
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
An Instant Run-Time Dump is triggered by calling the ``{IDF_TARGET_NAME} gcov`` OpenOCD command (via a telnet session). Once called, OpenOCD will immediately preempt the {IDF_TARGET_NAME}'s current state and execute a built-in ESP-IDF Gcov debug stub function. The debug stub function will handle the dumping of data to the host. Upon completion, the {IDF_TARGET_NAME} will resume its current state.
|
||||
|
||||
|
||||
Hard-coded Dump
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
A Hard-coded Dump is triggered by the application itself by calling :cpp:func:`esp_gcov_dump` from somewhere within the application. When called, the application will halt and wait for OpenOCD to connect and retrieve the code coverage data. Once :cpp:func:`esp_gcov_dump` is called, the host must execute the ``esp gcov dump`` OpenOCD command (via a telnet session). The ``esp gcov dump`` command will cause OpenOCD to connect to the {IDF_TARGET_NAME}, retrieve the code coverage data, then disconnect from the {IDF_TARGET_NAME}, thus allowing the application to resume. Hard-coded Dumps can also be triggered multiple times throughout an application's lifetime.
|
||||
|
||||
Hard-coded dumps are useful if code coverage data is required at certain points of an application's lifetime by placing :cpp:func:`esp_gcov_dump` where necessary (e.g., after application initialization, during each iteration of an application's main loop).
|
||||
|
||||
GDB can be used to set a breakpoint on :cpp:func:`esp_gcov_dump`, then call ``mon esp gcov dump`` automatically via the use a ``gdbinit`` script (see Using GDB from :ref:`jtag-debugging-using-debugger-command-line`).
|
||||
|
||||
The following GDB script will add a breakpoint at :cpp:func:`esp_gcov_dump`, then call the ``mon esp gcov dump`` OpenOCD command.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
b esp_gcov_dump
|
||||
commands
|
||||
mon esp gcov dump
|
||||
end
|
||||
|
||||
|
||||
.. note::
|
||||
Note that all OpenOCD commands should be invoked in GDB as: ``mon <oocd_command>``.
|
||||
|
||||
|
||||
.. _app_trace-gcov-generate-report:
|
||||
|
||||
Generating Coverage Report
|
||||
""""""""""""""""""""""""""
|
||||
|
||||
Once the code coverage data has been dumped, the ``.gcno``, ``.gcda`` and the source files can be used to generate a code coverage report. A code coverage report is simply a report indicating the number of times each line in a source file has been executed.
|
||||
|
||||
Both Gcov and Gcovr can be used to generate code coverage reports. Gcov is provided along with the Xtensa toolchain, whilst Gcovr may need to be installed separately. For details on how to use Gcov or Gcovr, refer to `Gcov documentation <https://gcc.gnu.org/onlinedocs/gcc/Gcov.html>`_ and `Gcovr documentation <https://gcovr.com/>`_.
|
||||
|
||||
|
||||
Adding Gcovr Build Target to Project
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To make report generation more convenient, users can define additional build targets in their projects such that the report generation can be done with a single build command.
|
||||
|
||||
Add the following lines to the ``CMakeLists.txt`` file of your project.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/gcov.cmake)
|
||||
idf_create_coverage_report(${CMAKE_CURRENT_BINARY_DIR}/coverage_report)
|
||||
idf_clean_coverage_report(${CMAKE_CURRENT_BINARY_DIR}/coverage_report)
|
||||
|
||||
The following commands can now be used:
|
||||
|
||||
* ``cmake --build build/ --target gcovr-report`` will generate an HTML coverage report in ``$(BUILD_DIR_BASE)/coverage_report/html`` directory.
|
||||
* ``cmake --build build/ --target cov-data-clean`` will remove all coverage data files.
|
||||
In ESP-IDF projects, code coverage analysis using gcov can be done with the help of `espressif/esp_gcov <https://components.espressif.com/components/espressif/esp_gcov>`_ managed component.
|
||||
|
@@ -118,3 +118,27 @@ OTA Updates
|
||||
The partial download functionality in ESP HTTPS OTA has been moved under a configuration option in order to reduce the memory footprint if partial download is not used.
|
||||
|
||||
To use partial download features in your OTA applications, you need to enable the component-level configuration :ref:`CONFIG_ESP_HTTPS_OTA_ENABLE_PARTIAL_DOWNLOAD` in menuconfig (``Component config`` → ``ESP HTTPS OTA`` → ``Enable partial HTTP download for OTA``).
|
||||
|
||||
Gcov
|
||||
----
|
||||
|
||||
The gcov component has been moved to a separate repository. `esp_gcov <https://components.espressif.com/components/espressif/esp_gcov>`_ is now a managed component.
|
||||
|
||||
**Component Dependency**
|
||||
|
||||
Projects using gcov functionality must now add the esp_gcov component as a dependency in their ``idf_component.yml`` manifest file:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
dependencies:
|
||||
espressif/esp_gcov: ^1
|
||||
|
||||
**Configuration Changes**
|
||||
|
||||
The gcov configuration options have moved from the Application Level Tracing menu to a dedicated ``GNU Code Coverage`` menu section.
|
||||
|
||||
The ``CONFIG_APPTRACE_GCOV_ENABLE`` option has been renamed to ``CONFIG_ESP_GCOV_ENABLE``.
|
||||
|
||||
**Header File Changes**
|
||||
|
||||
For the gcov functionality, include the ``esp_gcov.h`` header file instead of ``esp_app_trace.h``.
|
||||
|
@@ -464,130 +464,7 @@ Start 子命令语法:
|
||||
|
||||
.. _app_trace-gcov-source-code-coverage:
|
||||
|
||||
Gcov(源代码覆盖)
|
||||
Gcov(源代码覆盖率)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Gcov 和 Gcovr 简介
|
||||
""""""""""""""""""""""""
|
||||
|
||||
源代码覆盖率显示程序运行时间内执行的每一条程序执行路径的数量和频率。`Gcov <https://en.wikipedia.org/wiki/Gcov>`_ 是一款 GCC 工具,与编译器协同使用时,可生成日志文件,显示源文件每行的执行次数。`Gcovr <https://gcovr.com/>`_ 是管理 Gcov 和生成代码覆盖率总结的工具。
|
||||
|
||||
一般来说,使用 Gcov 在主机上编译和运行程序会经过以下步骤:
|
||||
|
||||
1. 使用 GCC 以及 ``--coverage`` 选项编译源代码。编译器会在编译过程中生成一个 ``.gcno`` 注释文件,该文件包含重建执行路径块图以及将每个块映射到源代码行号等信息。每个用 ``--coverage`` 选项编译的源文件都会生成自己的同名 ``.gcno`` 文件(如 ``main.c`` 在编译时会生成 ``main.gcno``)。
|
||||
|
||||
2. 执行程序。在执行过程中,程序会生成 ``.gcda`` 数据文件。这些数据文件包含了执行路径的次数统计。程序将为每个用 ``--coverage`` 选项编译的源文件生成一个 ``.gcda`` 文件(如 ``main.c`` 将生成 ``main.gcda``)。
|
||||
|
||||
3. Gcov 或 Gcovr 可用于生成基于 ``.gcno``、``.gcda`` 和源文件的代码覆盖。Gcov 将以 ``.gcov`` 文件的形式为每个源文件生成基于文本的覆盖报告,而 Gcovr 将以 HTML 格式生成覆盖报告。
|
||||
|
||||
|
||||
ESP-IDF 中的 Gcov 和 Gcovr 应用
|
||||
"""""""""""""""""""""""""""""""""
|
||||
|
||||
在 ESP-IDF 中使用 Gcov 的过程比较复杂,因为程序不在主机上运行,而在目标机上运行。代码覆盖率数据(即 ``.gcda`` 文件)最初存储在目标机上,OpenOCD 在运行时通过 JTAG 将代码覆盖数据从目标机转储到主机上。在 ESP-IDF 中使用 Gcov 可以分为以下几个步骤:
|
||||
|
||||
1. :ref:`app_trace-gcov-setup-project`
|
||||
2. :ref:`app_trace-gcov-dumping-data`
|
||||
3. :ref:`app_trace-gcov-generate-report`
|
||||
|
||||
|
||||
.. _app_trace-gcov-setup-project:
|
||||
|
||||
为 Gcov 设置项目
|
||||
"""""""""""""""""""""""""""""""
|
||||
|
||||
编译器选项
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
为了获取项目中的代码覆盖率数据,必须用 ``--coverage`` 选项编译项目中的一个或多个源文件。在 ESP-IDF 中,这可以在组件级或单个源文件级实现:
|
||||
|
||||
- 在组件的 ``CMakeLists.txt`` 文件中添加 ``target_compile_options(${COMPONENT_LIB} PRIVATE --coverage)`` 可确保使用 ``--coverage`` 选项编译组件中的所有源文件。
|
||||
- 在组件的 ``CMakeLists.txt`` 文件中添加 ``set_source_files_properties(source1.c source2.c PROPERTIES COMPILE_FLAGS --coverage)`` 可确保使用 ``--coverage`` 选项编译同一组件中选定的一些源文件(如 ``source1.c`` 和 ``source2.c``)。
|
||||
|
||||
当一个源文件用 ``--coverage`` 选项编译时(例如 ``gcov_example.c``),编译器会在项目的构建目录下生成 ``gcov_example.gcno`` 文件。
|
||||
|
||||
|
||||
项目配置
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
在构建有源代码覆盖的项目之前,请运行 ``idf.py menuconfig`` 以启用以下项目配置选项。
|
||||
|
||||
- 通过 :ref:`CONFIG_APPTRACE_DESTINATION1` 选项选择 ``Trace Memory`` 来启用应用程序跟踪模块。
|
||||
- 通过 :ref:`CONFIG_APPTRACE_GCOV_ENABLE` 选项启用 Gcov 主机。
|
||||
|
||||
|
||||
.. _app_trace-gcov-dumping-data:
|
||||
|
||||
转储代码覆盖数据
|
||||
""""""""""""""""""""""""""
|
||||
|
||||
一旦项目使用 ``--coverage`` 选项编译并烧录到目标机上,在应用程序运行时,代码覆盖数据将存储在目标机内部(即在跟踪存储器中)。将代码覆盖率数据从目标机转移到主机上的过程称为转储。
|
||||
|
||||
覆盖率数据的转储通过 OpenOCD 进行(关于如何设置和运行 OpenOCD,请参考 :doc:`JTAG 调试 <../api-guides/jtag-debugging/index>`)。由于该过程需要通过向 OpenOCD 发出命令来触发转储,因此必须打开 telnet 会话,以向 OpenOCD 发出这些命令(运行 ``telnet localhost 4444``)。GDB 也可以代替 telnet 来向 OpenOCD 发出命令,但是所有从 GDB 发出的命令都需要以 ``mon <oocd_command>`` 为前缀。
|
||||
|
||||
当目标机转储代码覆盖数据时,``.gcda`` 文件存储在项目的构建目录中。例如,如果 ``main`` 组件的 ``gcov_example_main.c`` 在编译时使用了 ``--coverage`` 选项,那么转储代码覆盖数据将在 ``build/esp-idf/main/CMakeFiles/__idf_main.dir/gcov_example_main.c.gcda`` 中生成 ``gcov_example_main.gcda`` 文件。注意,编译过程中产生的 ``.gcno`` 文件也放在同一目录下。
|
||||
|
||||
代码覆盖数据的转储可以在应用程序的整个生命周期内多次进行。每次转储都会用最新的代码覆盖信息更新 ``.gcda`` 文件。代码覆盖数据是累积的,因此最新的数据将包含应用程序整个生命周期中每个代码路径的总执行次数。
|
||||
|
||||
ESP-IDF 支持两种将代码覆盖数据从目标机转储到主机的方法:
|
||||
|
||||
* 运行中实时转储
|
||||
* 硬编码转储
|
||||
|
||||
|
||||
运行中实时转储
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
通过 telnet 会话调用 OpenOCD 命令 ``{IDF_TARGET_NAME} gcov`` 来触发运行时的实时转储。一旦被调用,OpenOCD 将立即抢占 {IDF_TARGET_NAME} 的当前状态,并执行内置的 ESP-IDF Gcov 调试存根函数。调试存根函数将数据转储到主机。完成后,{IDF_TARGET_NAME} 将恢复当前状态。
|
||||
|
||||
|
||||
硬编码转储
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
硬编码转储是由应用程序本身从程序内部调用 :cpp:func:`esp_gcov_dump` 函数触发的。在调用时,应用程序将停止并等待 OpenOCD 连接,同时检索代码覆盖数据。一旦 :cpp:func:`esp_gcov_dump` 函数被调用,主机将通过 telnet 会话执行 ``esp gcov dump`` OpenOCD 命令,该命令会将 OpenOCD 连接到 {IDF_TARGET_NAME},检索代码覆盖数据,然后断开与 {IDF_TARGET_NAME} 的连接,从而恢复应用程序。在应用程序的生命周期中可多次触发硬编码转储。
|
||||
|
||||
在必要时(如应用程序初始化后或是应用程序主循环的每次迭代期间)放置 :cpp:func:`esp_gcov_dump`,当应用程序在生命周期的某刻需要代码覆盖率数据时,硬编码转储会非常有用。
|
||||
|
||||
GDB 可以用来在 :cpp:func:`esp_gcov_dump` 上设置断点,然后使用 ``gdbinit`` 脚本自动调用 ``mon esp gcov dump`` (关于 GDB 的使用可参考 :ref:`jtag-debugging-using-debugger-command-line`)。
|
||||
|
||||
以下 GDB 脚本将在 :cpp:func:`esp_gcov_dump` 处添加一个断点,然后调用 ``mon esp gcov dump`` OpenOCD 命令。
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
b esp_gcov_dump
|
||||
commands
|
||||
mon esp gcov dump
|
||||
end
|
||||
|
||||
|
||||
.. note::
|
||||
注意,所有的 OpenOCD 命令都应该在 GDB 中以 ``mon <oocd_command>`` 方式调用。
|
||||
|
||||
|
||||
.. _app_trace-gcov-generate-report:
|
||||
|
||||
生成代码覆盖报告
|
||||
""""""""""""""""""""""""""
|
||||
|
||||
一旦代码覆盖数据被转储,``.gcno``、``.gcda`` 和源文件可以用来生成代码覆盖报告。该报告会显示源文件中每行被执行的次数。
|
||||
|
||||
Gcov 和 Gcovr 都可以用来生成代码覆盖报告。安装 Xtensa 工具链时会一起安装 Gcov,但 Gcovr 可能需要单独安装。关于如何使用 Gcov 或 Gcovr,请参考 `Gcov 文档 <https://gcc.gnu.org/onlinedocs/gcc/Gcov.html>`_ 和 `Gcovr 文档 <https://gcovr.com/>`_。
|
||||
|
||||
|
||||
在工程中添加 Gcovr 构建目标
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
用户可以在自己的工程中定义额外的构建目标,从而通过一个简单的构建命令即可更方便地生成报告。
|
||||
|
||||
请在工程的 ``CMakeLists.txt`` 文件中添加以下内容:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/gcov.cmake)
|
||||
idf_create_coverage_report(${CMAKE_CURRENT_BINARY_DIR}/coverage_report)
|
||||
idf_clean_coverage_report(${CMAKE_CURRENT_BINARY_DIR}/coverage_report)
|
||||
|
||||
可使用以下命令:
|
||||
|
||||
* ``cmake --build build/ --target gcovr-report``:在 ``$(BUILD_DIR_BASE)/coverage_report/html`` 目录下生成 HTML 格式代码覆盖报告。
|
||||
* ``cmake --build build/ --target cov-data-clean``:删除所有代码覆盖数据文件。
|
||||
在 ESP-IDF 项目中,可以借助 `espressif/esp_gcov <https://components.espressif.com/components/espressif/esp_gcov>`_ 托管组件使用 gcov 进行代码覆盖率分析。
|
||||
|
@@ -111,3 +111,27 @@ FreeRTOS
|
||||
CRC 数据完整性检查已被弃用。`ESP_COREDUMP_CHECKSUM_CRC32` 表示该功能已完全删除,不再可用。现在默认的校验和算法为 SHA256。
|
||||
|
||||
函数 :cpp:func:`esp_core_dump_partition_and_size_get()` 现在对空白(已擦除)分区返回 `ESP_ERR_NOT_FOUND`,而不是 `ESP_ERR_INVALID_SIZE`。
|
||||
|
||||
Gcov
|
||||
----
|
||||
|
||||
gcov 组件已移至独立仓库。`esp_gcov <https://components.espressif.com/components/espressif/esp_gcov>`_ 现为托管组件。
|
||||
|
||||
**组件依赖**
|
||||
|
||||
使用 gcov 功能的项目现在必须在 ``idf_component.yml`` 清单文件中添加 esp_gcov 组件作为依赖项:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
dependencies:
|
||||
espressif/esp_gcov: ^1
|
||||
|
||||
**配置更改**
|
||||
|
||||
gcov 配置选项现在归类在 ``GNU Code Coverage`` 菜单下。
|
||||
|
||||
``CONFIG_APPTRACE_GCOV_ENABLE`` 选项已重命名为 ``CONFIG_ESP_GCOV_ENABLE``。
|
||||
|
||||
**头文件更改**
|
||||
|
||||
对于 gcov 功能,请改用 ``esp_gcov.h`` 头文件替代原有的 ``esp_app_trace.h``。
|
||||
|
@@ -5,15 +5,25 @@
|
||||
|
||||
(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](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/app_trace.html#gcov-source-code-coverage) for more details on the code coverage features supported in ESP-IDF.
|
||||
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. Refer to the [esp_gcov component](https://components.espressif.com/components/espressif/esp_gcov/) 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 add the esp_gcov component dependency
|
||||
* 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
|
||||
|
||||
### Component Dependency
|
||||
|
||||
This example uses the esp_gcov component for code coverage functionality. The component is already added as a dependency in the `main/idf_component.yml` file:
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
espressif/esp_gcov: ^1
|
||||
```
|
||||
|
||||
### Hardware Required
|
||||
|
||||
To run this example, you need a supported dev board connected to a JTAG adapter, which can come in the following forms:
|
||||
@@ -42,9 +52,11 @@ 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 GCOV to host interface under `Component config -> GNU Code Coverage -> GCOV to Host Enable`.
|
||||
* Enable OpenOCD Debug Stubs under `Component config -> ESP System Settings -> OpenOCD debug stubs`
|
||||
|
||||
**Note:** With the esp_gcov component, the GCOV configuration options appear under the component's own menu section.
|
||||
|
||||
### Build, Flash, and Run
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output:
|
||||
@@ -104,13 +116,16 @@ 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.
|
||||
After dumping one or more times, a coverage report can be generated by calling `idf.py 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`
|
||||
To clean Gcov and report related data from the build directory, call `idf.py cov-data-clean`
|
||||
|
||||
The following log should be output when generating the coverage report:
|
||||
|
||||
```
|
||||
Executing action: gcovr-report
|
||||
Running ninja in directory /home/user/esp/esp-idf/examples/system/gcov/build
|
||||
Executing "ninja gcovr-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
|
||||
@@ -148,3 +163,20 @@ gcovr can be installed from the package database of your operating system or dir
|
||||
```
|
||||
python -m pip install gcovr
|
||||
```
|
||||
|
||||
## Using Code Coverage in Your Own Project
|
||||
|
||||
To use code coverage functionality in your own ESP-IDF project, add the esp_gcov component as a dependency in your `idf_component.yml` manifest file:
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
espressif/esp_gcov: ^1
|
||||
```
|
||||
|
||||
After adding the dependency:
|
||||
|
||||
1. Configure the project using `idf.py menuconfig` to enable the necessary tracing and GCOV options
|
||||
2. Include the esp_gcov header in your code: `#include "esp_gcov.h"`
|
||||
3. Use the coverage dumping functions as demonstrated in this example
|
||||
|
||||
For detailed documentation, refer to the [esp_gcov component repository](https://components.espressif.com/components/espressif/esp_gcov/).
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_gcov.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
|
7
examples/system/gcov/main/idf_component.yml
Normal file
7
examples/system/gcov/main/idf_component.yml
Normal file
@@ -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
|
@@ -4,4 +4,3 @@ CONFIG_APPTRACE_ENABLE=y
|
||||
CONFIG_APPTRACE_LOCK_ENABLE=y
|
||||
CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO=-1
|
||||
CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH=0
|
||||
CONFIG_APPTRACE_GCOV_ENABLE=y
|
||||
|
Reference in New Issue
Block a user