mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-23 17:24:44 +00:00
Merge branch 'feature/gcov_over_apptrace' into 'master'
esp32: Adds gcov over JTAG feature See merge request !1117
This commit is contained in:
@@ -254,6 +254,10 @@ static volatile uint8_t *s_trax_blocks[] = {
|
||||
#define ESP_APPTRACE_USR_DATA_LEN_MAX (ESP_APPTRACE_TRAX_BLOCK_SIZE - sizeof(esp_tracedata_hdr_t))
|
||||
#endif
|
||||
|
||||
#define ESP_APPTRACE_HW_TRAX 0
|
||||
#define ESP_APPTRACE_HW_MAX 1
|
||||
#define ESP_APPTRACE_HW(_i_) (&s_trace_hw[_i_])
|
||||
|
||||
/** Trace data header. Every user data chunk is prepended with this header.
|
||||
* User allocates block with esp_apptrace_buffer_get and then fills it with data,
|
||||
* in multithreading environment it can happen that tasks gets buffer and then gets interrupted,
|
||||
@@ -326,8 +330,33 @@ static esp_apptrace_buffer_t s_trace_buf;
|
||||
static esp_apptrace_lock_t s_log_lock = {.irq_stat = 0, .portmux = portMUX_INITIALIZER_UNLOCKED};
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t *(*get_up_buffer)(uint32_t, esp_apptrace_tmo_t *);
|
||||
esp_err_t (*put_up_buffer)(uint8_t *, esp_apptrace_tmo_t *);
|
||||
esp_err_t (*flush_up_buffer)(uint32_t, esp_apptrace_tmo_t *);
|
||||
uint8_t *(*get_down_buffer)(uint32_t *, esp_apptrace_tmo_t *);
|
||||
esp_err_t (*put_down_buffer)(uint8_t *, esp_apptrace_tmo_t *);
|
||||
bool (*host_is_connected)(void);
|
||||
} esp_apptrace_hw_t;
|
||||
|
||||
static uint32_t esp_apptrace_trax_down_buffer_write_nolock(uint8_t *data, uint32_t size);
|
||||
static esp_err_t esp_apptrace_trax_flush(uint32_t min_sz, esp_apptrace_tmo_t *tmo);
|
||||
static uint8_t *esp_apptrace_trax_get_buffer(uint32_t size, esp_apptrace_tmo_t *tmo);
|
||||
static esp_err_t esp_apptrace_trax_put_buffer(uint8_t *ptr, esp_apptrace_tmo_t *tmo);
|
||||
static bool esp_apptrace_trax_host_is_connected(void);
|
||||
static uint8_t *esp_apptrace_trax_down_buffer_get(uint32_t *size, esp_apptrace_tmo_t *tmo);
|
||||
static esp_err_t esp_apptrace_trax_down_buffer_put(uint8_t *ptr, esp_apptrace_tmo_t *tmo);
|
||||
|
||||
static esp_apptrace_hw_t s_trace_hw[ESP_APPTRACE_HW_MAX] = {
|
||||
{
|
||||
.get_up_buffer = esp_apptrace_trax_get_buffer,
|
||||
.put_up_buffer = esp_apptrace_trax_put_buffer,
|
||||
.flush_up_buffer = esp_apptrace_trax_flush,
|
||||
.get_down_buffer = esp_apptrace_trax_down_buffer_get,
|
||||
.put_down_buffer = esp_apptrace_trax_down_buffer_put,
|
||||
.host_is_connected = esp_apptrace_trax_host_is_connected
|
||||
}
|
||||
};
|
||||
|
||||
static inline int esp_apptrace_log_lock()
|
||||
{
|
||||
@@ -586,7 +615,7 @@ static uint8_t *esp_apptrace_trax_down_buffer_get(uint32_t *size, esp_apptrace_t
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static inline esp_err_t esp_apptrace_trax_down_buffer_put(uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_trax_down_buffer_put(uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
/* nothing todo */
|
||||
return ESP_OK;
|
||||
@@ -597,8 +626,8 @@ static uint32_t esp_apptrace_trax_down_buffer_write_nolock(uint8_t *data, uint32
|
||||
uint32_t total_sz = 0;
|
||||
|
||||
while (total_sz < size) {
|
||||
// ESP_APPTRACE_LOGE("esp_apptrace_trax_down_buffer_write_nolock WRS %d-%d-%d %d", s_trace_buf.rb_down.wr, s_trace_buf.rb_down.rd,
|
||||
// s_trace_buf.rb_down.cur_size, size);
|
||||
ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock WRS %d-%d-%d %d", s_trace_buf.rb_down.wr, s_trace_buf.rb_down.rd,
|
||||
s_trace_buf.rb_down.cur_size, size);
|
||||
uint32_t wr_sz = esp_apptrace_rb_write_size_get(&s_trace_buf.rb_down);
|
||||
if (wr_sz == 0) {
|
||||
break;
|
||||
@@ -607,15 +636,15 @@ static uint32_t esp_apptrace_trax_down_buffer_write_nolock(uint8_t *data, uint32
|
||||
if (wr_sz > size - total_sz) {
|
||||
wr_sz = size - total_sz;
|
||||
}
|
||||
// ESP_APPTRACE_LOGE("esp_apptrace_trax_down_buffer_write_nolock wr %d", wr_sz);
|
||||
ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d", wr_sz);
|
||||
uint8_t *ptr = esp_apptrace_rb_produce(&s_trace_buf.rb_down, wr_sz);
|
||||
if (!ptr) {
|
||||
assert(false && "Failed to produce bytes to down buffer!");
|
||||
}
|
||||
// ESP_APPTRACE_LOGE("esp_apptrace_trax_down_buffer_write_nolock wr %d to 0x%x from 0x%x", wr_sz, ptr, data + total_sz + wr_sz);
|
||||
ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d to 0x%x from 0x%x", wr_sz, ptr, data + total_sz + wr_sz);
|
||||
memcpy(ptr, data + total_sz, wr_sz);
|
||||
total_sz += wr_sz;
|
||||
// ESP_APPTRACE_LOGE("esp_apptrace_trax_down_buffer_write_nolock wr %d/%d", wr_sz, total_sz);
|
||||
ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d/%d", wr_sz, total_sz);
|
||||
}
|
||||
return total_sz;
|
||||
}
|
||||
@@ -795,6 +824,11 @@ static esp_err_t esp_apptrace_trax_flush(uint32_t min_sz, esp_apptrace_tmo_t *tm
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool esp_apptrace_trax_host_is_connected(void)
|
||||
{
|
||||
return eri_read(ESP_APPTRACE_TRAX_CTRL_REG) & ESP_APPTRACE_TRAX_HOST_CONNECT ? true : false;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_dest_init()
|
||||
{
|
||||
for (int i = 0; i < ESP_APPTRACE_TRAX_BLOCKS_NUM; i++) {
|
||||
@@ -867,14 +901,11 @@ esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *buf, uint32_t *size,
|
||||
{
|
||||
int res = ESP_OK;
|
||||
esp_apptrace_tmo_t tmo;
|
||||
//TODO: use ptr to HW transport iface struct
|
||||
uint8_t *(*apptrace_get_down_buffer)(uint32_t *, esp_apptrace_tmo_t *);
|
||||
esp_err_t (*apptrace_put_down_buffer)(uint8_t *, esp_apptrace_tmo_t *);
|
||||
esp_apptrace_hw_t *hw = NULL;
|
||||
|
||||
if (dest == ESP_APPTRACE_DEST_TRAX) {
|
||||
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
|
||||
apptrace_get_down_buffer = esp_apptrace_trax_down_buffer_get;
|
||||
apptrace_put_down_buffer = esp_apptrace_trax_down_buffer_put;
|
||||
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
|
||||
#else
|
||||
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
@@ -888,12 +919,14 @@ esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *buf, uint32_t *size,
|
||||
esp_apptrace_tmo_init(&tmo, user_tmo);
|
||||
uint32_t act_sz = *size;
|
||||
*size = 0;
|
||||
uint8_t * ptr = apptrace_get_down_buffer(&act_sz, &tmo);
|
||||
uint8_t * ptr = hw->get_down_buffer(&act_sz, &tmo);
|
||||
if (ptr && act_sz > 0) {
|
||||
ESP_APPTRACE_LOGD("Read %d bytes from host", act_sz);
|
||||
memcpy(buf, ptr, act_sz);
|
||||
res = apptrace_put_down_buffer(ptr, &tmo);
|
||||
res = hw->put_down_buffer(ptr, &tmo);
|
||||
*size = act_sz;
|
||||
} else {
|
||||
res = ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -902,12 +935,11 @@ esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *buf, uint32_t *size,
|
||||
uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size, uint32_t user_tmo)
|
||||
{
|
||||
esp_apptrace_tmo_t tmo;
|
||||
//TODO: use ptr to HW transport iface struct
|
||||
uint8_t *(*apptrace_get_down_buffer)(uint32_t *, esp_apptrace_tmo_t *);
|
||||
esp_apptrace_hw_t *hw = NULL;
|
||||
|
||||
if (dest == ESP_APPTRACE_DEST_TRAX) {
|
||||
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
|
||||
apptrace_get_down_buffer = esp_apptrace_trax_down_buffer_get;
|
||||
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
|
||||
#else
|
||||
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
|
||||
return NULL;
|
||||
@@ -919,18 +951,17 @@ uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size,
|
||||
|
||||
// ESP_APPTRACE_LOGE("esp_apptrace_down_buffer_get %d", *size);
|
||||
esp_apptrace_tmo_init(&tmo, user_tmo);
|
||||
return apptrace_get_down_buffer(size, &tmo);
|
||||
return hw->get_down_buffer(size, &tmo);
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_down_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t user_tmo)
|
||||
{
|
||||
esp_apptrace_tmo_t tmo;
|
||||
//TODO: use ptr to HW transport iface struct
|
||||
esp_err_t (*apptrace_put_down_buffer)(uint8_t *, esp_apptrace_tmo_t *);
|
||||
esp_apptrace_hw_t *hw = NULL;
|
||||
|
||||
if (dest == ESP_APPTRACE_DEST_TRAX) {
|
||||
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
|
||||
apptrace_put_down_buffer = esp_apptrace_trax_down_buffer_put;
|
||||
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
|
||||
#else
|
||||
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
@@ -941,21 +972,18 @@ esp_err_t esp_apptrace_down_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, u
|
||||
}
|
||||
|
||||
esp_apptrace_tmo_init(&tmo, user_tmo);
|
||||
return apptrace_put_down_buffer(ptr, &tmo);
|
||||
return hw->put_down_buffer(ptr, &tmo);
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_t size, uint32_t user_tmo)
|
||||
{
|
||||
uint8_t *ptr = NULL;
|
||||
esp_apptrace_tmo_t tmo;
|
||||
//TODO: use ptr to HW transport iface struct
|
||||
uint8_t *(*apptrace_get_buffer)(uint32_t, esp_apptrace_tmo_t *);
|
||||
esp_err_t (*apptrace_put_buffer)(uint8_t *, esp_apptrace_tmo_t *);
|
||||
esp_apptrace_hw_t *hw = NULL;
|
||||
|
||||
if (dest == ESP_APPTRACE_DEST_TRAX) {
|
||||
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
|
||||
apptrace_get_buffer = esp_apptrace_trax_get_buffer;
|
||||
apptrace_put_buffer = esp_apptrace_trax_put_buffer;
|
||||
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
|
||||
#else
|
||||
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
@@ -966,7 +994,7 @@ esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_
|
||||
}
|
||||
|
||||
esp_apptrace_tmo_init(&tmo, user_tmo);
|
||||
ptr = apptrace_get_buffer(size, &tmo);
|
||||
ptr = hw->get_up_buffer(size, &tmo);
|
||||
if (ptr == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
@@ -976,7 +1004,7 @@ esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_
|
||||
memcpy(ptr, data, size);
|
||||
|
||||
// now indicate that this buffer is ready to be sent off to host
|
||||
return apptrace_put_buffer(ptr, &tmo);
|
||||
return hw->put_up_buffer(ptr, &tmo);
|
||||
}
|
||||
|
||||
int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const char *fmt, va_list ap)
|
||||
@@ -984,14 +1012,11 @@ int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const c
|
||||
uint16_t nargs = 0;
|
||||
uint8_t *pout, *p = (uint8_t *)fmt;
|
||||
esp_apptrace_tmo_t tmo;
|
||||
//TODO: use ptr to HW transport iface struct
|
||||
uint8_t *(*apptrace_get_buffer)(uint32_t, esp_apptrace_tmo_t *);
|
||||
esp_err_t (*apptrace_put_buffer)(uint8_t *, esp_apptrace_tmo_t *);
|
||||
esp_apptrace_hw_t *hw = NULL;
|
||||
|
||||
if (dest == ESP_APPTRACE_DEST_TRAX) {
|
||||
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
|
||||
apptrace_get_buffer = esp_apptrace_trax_get_buffer;
|
||||
apptrace_put_buffer = esp_apptrace_trax_put_buffer;
|
||||
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
|
||||
#else
|
||||
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
@@ -1014,7 +1039,7 @@ int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const c
|
||||
ESP_APPTRACE_LOGE("Failed to store all printf args!");
|
||||
}
|
||||
|
||||
pout = apptrace_get_buffer(1 + sizeof(char *) + nargs * sizeof(uint32_t), &tmo);
|
||||
pout = hw->get_up_buffer(1 + sizeof(char *) + nargs * sizeof(uint32_t), &tmo);
|
||||
if (pout == NULL) {
|
||||
ESP_APPTRACE_LOGE("Failed to get buffer!");
|
||||
return -1;
|
||||
@@ -1031,7 +1056,7 @@ int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const c
|
||||
ESP_APPTRACE_LOGD("arg %x", arg);
|
||||
}
|
||||
|
||||
int ret = apptrace_put_buffer(p, &tmo);
|
||||
int ret = hw->put_up_buffer(p, &tmo);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_APPTRACE_LOGE("Failed to put printf buf (%d)!", ret);
|
||||
return -1;
|
||||
@@ -1048,12 +1073,11 @@ int esp_apptrace_vprintf(const char *fmt, va_list ap)
|
||||
uint8_t *esp_apptrace_buffer_get(esp_apptrace_dest_t dest, uint32_t size, uint32_t user_tmo)
|
||||
{
|
||||
esp_apptrace_tmo_t tmo;
|
||||
//TODO: use ptr to HW transport iface struct
|
||||
uint8_t *(*apptrace_get_buffer)(uint32_t, esp_apptrace_tmo_t *);
|
||||
esp_apptrace_hw_t *hw = NULL;
|
||||
|
||||
if (dest == ESP_APPTRACE_DEST_TRAX) {
|
||||
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
|
||||
apptrace_get_buffer = esp_apptrace_trax_get_buffer;
|
||||
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
|
||||
#else
|
||||
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
|
||||
return NULL;
|
||||
@@ -1064,18 +1088,17 @@ uint8_t *esp_apptrace_buffer_get(esp_apptrace_dest_t dest, uint32_t size, uint32
|
||||
}
|
||||
|
||||
esp_apptrace_tmo_init(&tmo, user_tmo);
|
||||
return apptrace_get_buffer(size, &tmo);
|
||||
return hw->get_up_buffer(size, &tmo);
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t user_tmo)
|
||||
{
|
||||
esp_apptrace_tmo_t tmo;
|
||||
//TODO: use ptr to HW transport iface struct
|
||||
esp_err_t (*apptrace_put_buffer)(uint8_t *, esp_apptrace_tmo_t *);
|
||||
esp_apptrace_hw_t *hw = NULL;
|
||||
|
||||
if (dest == ESP_APPTRACE_DEST_TRAX) {
|
||||
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
|
||||
apptrace_put_buffer = esp_apptrace_trax_put_buffer;
|
||||
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
|
||||
#else
|
||||
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
@@ -1086,18 +1109,17 @@ esp_err_t esp_apptrace_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32
|
||||
}
|
||||
|
||||
esp_apptrace_tmo_init(&tmo, user_tmo);
|
||||
return apptrace_put_buffer(ptr, &tmo);
|
||||
return hw->put_up_buffer(ptr, &tmo);
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_flush_nolock(esp_apptrace_dest_t dest, uint32_t min_sz, uint32_t usr_tmo)
|
||||
{
|
||||
esp_apptrace_tmo_t tmo;
|
||||
//TODO: use ptr to HW transport iface struct
|
||||
esp_err_t (*apptrace_flush)(uint32_t, esp_apptrace_tmo_t *);
|
||||
esp_apptrace_hw_t *hw = NULL;
|
||||
|
||||
if (dest == ESP_APPTRACE_DEST_TRAX) {
|
||||
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
|
||||
apptrace_flush = esp_apptrace_trax_flush;
|
||||
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
|
||||
#else
|
||||
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
@@ -1108,7 +1130,7 @@ esp_err_t esp_apptrace_flush_nolock(esp_apptrace_dest_t dest, uint32_t min_sz, u
|
||||
}
|
||||
|
||||
esp_apptrace_tmo_init(&tmo, usr_tmo);
|
||||
return apptrace_flush(min_sz, &tmo);
|
||||
return hw->flush_up_buffer(min_sz, &tmo);
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_flush(esp_apptrace_dest_t dest, uint32_t usr_tmo)
|
||||
@@ -1134,4 +1156,23 @@ esp_err_t esp_apptrace_flush(esp_apptrace_dest_t dest, uint32_t usr_tmo)
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool esp_apptrace_host_is_connected(esp_apptrace_dest_t dest)
|
||||
{
|
||||
esp_apptrace_hw_t *hw = NULL;
|
||||
|
||||
if (dest == ESP_APPTRACE_DEST_TRAX) {
|
||||
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
|
||||
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
|
||||
#else
|
||||
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
} else {
|
||||
ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
return hw->host_is_connected();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -4,12 +4,14 @@
|
||||
|
||||
COMPONENT_SRCDIRS := .
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := include
|
||||
COMPONENT_ADD_INCLUDEDIRS = include
|
||||
|
||||
COMPONENT_ADD_LDFLAGS := -lapp_trace
|
||||
COMPONENT_ADD_LDFLAGS = -lapp_trace
|
||||
|
||||
# do not produce gcov info for this module, it is used as transport for gcov
|
||||
CFLAGS := $(subst --coverage,,$(CFLAGS))
|
||||
|
||||
ifdef CONFIG_SYSVIEW_ENABLE
|
||||
#COMPONENT_EXTRA_INCLUDES := freertos
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS += \
|
||||
sys_view/Config \
|
||||
@@ -17,8 +19,11 @@ COMPONENT_ADD_INCLUDEDIRS += \
|
||||
sys_view/Sample/OS
|
||||
|
||||
COMPONENT_SRCDIRS += \
|
||||
gcov \
|
||||
sys_view/SEGGER \
|
||||
sys_view/Sample/OS \
|
||||
sys_view/Sample/Config \
|
||||
sys_view/esp32
|
||||
else
|
||||
COMPONENT_SRCDIRS += gcov
|
||||
endif
|
||||
|
93
components/app_trace/gcov/gcov_rtio.c
Normal file
93
components/app_trace/gcov/gcov_rtio.c
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This module implements runtime file I/O API for GCOV.
|
||||
|
||||
#include "esp_task_wdt.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "esp_app_trace.h"
|
||||
|
||||
#if CONFIG_ESP32_APPTRACE_ENABLE
|
||||
|
||||
#define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "esp_gcov_rtio";
|
||||
|
||||
static void (*s_gcov_exit)(void);
|
||||
static uint8_t s_gcov_down_buf[256];
|
||||
|
||||
void esp_gcov_dump()
|
||||
{
|
||||
#if CONFIG_FREERTOS_UNICORE == 0
|
||||
esp_cpu_stall(!xPortGetCoreID());
|
||||
#endif
|
||||
|
||||
while (!esp_apptrace_host_is_connected(ESP_APPTRACE_DEST_TRAX)) {
|
||||
// to avoid complains that task watchdog got triggered for other tasks
|
||||
TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
|
||||
TIMERG0.wdt_feed=1;
|
||||
TIMERG0.wdt_wprotect=0;
|
||||
// to avoid reboot on INT_WDT
|
||||
TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
|
||||
TIMERG1.wdt_feed=1;
|
||||
TIMERG1.wdt_wprotect=0;
|
||||
}
|
||||
|
||||
if (s_gcov_exit) {
|
||||
s_gcov_exit();
|
||||
}
|
||||
|
||||
int ret = esp_apptrace_fstop(ESP_APPTRACE_DEST_TRAX);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
int gcov_rtio_atexit(void (*function)(void))
|
||||
{
|
||||
s_gcov_exit = function;
|
||||
esp_apptrace_down_buffer_config(s_gcov_down_buf, sizeof(s_gcov_down_buf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *gcov_rtio_fopen(const char *path, const char *mode)
|
||||
{
|
||||
return esp_apptrace_fopen(ESP_APPTRACE_DEST_TRAX, path, mode);
|
||||
}
|
||||
|
||||
int gcov_rtio_fclose(void *stream)
|
||||
{
|
||||
return esp_apptrace_fclose(ESP_APPTRACE_DEST_TRAX, stream);
|
||||
}
|
||||
|
||||
size_t gcov_rtio_fwrite(const void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
return esp_apptrace_fwrite(ESP_APPTRACE_DEST_TRAX, ptr, size, nmemb, stream);
|
||||
}
|
||||
|
||||
int gcov_rtio_fseek(void *stream, long offset, int whence)
|
||||
{
|
||||
return esp_apptrace_fseek(ESP_APPTRACE_DEST_TRAX, stream, offset, whence);
|
||||
}
|
||||
|
||||
long gcov_rtio_ftell(void *stream)
|
||||
{
|
||||
return esp_apptrace_ftell(ESP_APPTRACE_DEST_TRAX, stream);
|
||||
}
|
||||
|
||||
#endif
|
340
components/app_trace/host_file_io.c
Normal file
340
components/app_trace/host_file_io.c
Normal file
@@ -0,0 +1,340 @@
|
||||
// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Hot It Works
|
||||
// ************
|
||||
//
|
||||
// This module implements host file I/O protocol on top of apptrace module.
|
||||
// The protocol is enough simple. It sends command with arguments to the host and receives response from it.
|
||||
// Responses contains return values of respective file I/O API. This value is returned to the caller.
|
||||
// Commands has the following format:
|
||||
// * Header. See esp_apptrace_fcmd_hdr_t.
|
||||
// * Operation arguments. See file operation helper structures below.
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_app_trace.h"
|
||||
|
||||
#if CONFIG_ESP32_APPTRACE_ENABLE
|
||||
|
||||
#define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "esp_host_file_io";
|
||||
|
||||
#define ESP_APPTRACE_FILE_CMD_FOPEN 0x0
|
||||
#define ESP_APPTRACE_FILE_CMD_FCLOSE 0x1
|
||||
#define ESP_APPTRACE_FILE_CMD_FWRITE 0x2
|
||||
#define ESP_APPTRACE_FILE_CMD_FREAD 0x3
|
||||
#define ESP_APPTRACE_FILE_CMD_FSEEK 0x4
|
||||
#define ESP_APPTRACE_FILE_CMD_FTELL 0x5
|
||||
#define ESP_APPTRACE_FILE_CMD_STOP 0x6 // indicates that there is no files to transfer
|
||||
|
||||
/** File operation header */
|
||||
typedef struct {
|
||||
uint8_t cmd; ///< Command ID
|
||||
} esp_apptrace_fcmd_hdr_t;
|
||||
|
||||
/** Helper structure for fopen */
|
||||
typedef struct {
|
||||
const char *path;
|
||||
uint16_t path_len;
|
||||
const char *mode;
|
||||
uint16_t mode_len;
|
||||
} esp_apptrace_fopen_args_t;
|
||||
|
||||
/** Helper structure for fclose */
|
||||
typedef struct {
|
||||
void *file;
|
||||
} esp_apptrace_fclose_args_t;
|
||||
|
||||
/** Helper structure for fwrite */
|
||||
typedef struct {
|
||||
void * buf;
|
||||
size_t size;
|
||||
void * file;
|
||||
} esp_apptrace_fwrite_args_t;
|
||||
|
||||
/** Helper structure for fread */
|
||||
typedef struct {
|
||||
size_t size;
|
||||
void * file;
|
||||
} esp_apptrace_fread_args_t;
|
||||
|
||||
/** Helper structure for fseek */
|
||||
typedef struct {
|
||||
long offset;
|
||||
int whence;
|
||||
void * file;
|
||||
} esp_apptrace_fseek_args_t;
|
||||
|
||||
/** Helper structure for ftell */
|
||||
typedef struct {
|
||||
void *file;
|
||||
} esp_apptrace_ftell_args_t;
|
||||
|
||||
static esp_err_t esp_apptrace_file_cmd_send(esp_apptrace_dest_t dest, uint8_t cmd, void (*prep_args)(uint8_t *, void *), void *args, uint32_t args_len)
|
||||
{
|
||||
esp_err_t ret;
|
||||
esp_apptrace_fcmd_hdr_t *hdr;
|
||||
|
||||
uint8_t *ptr = esp_apptrace_buffer_get(dest, sizeof(*hdr) + args_len, ESP_APPTRACE_TMO_INFINITE); //TODO: finite tmo
|
||||
if (ptr == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
hdr = (esp_apptrace_fcmd_hdr_t *)ptr;
|
||||
hdr->cmd = cmd;
|
||||
if (prep_args) {
|
||||
prep_args(ptr + sizeof(hdr->cmd), args);
|
||||
}
|
||||
|
||||
// now indicate that this buffer is ready to be sent off to host
|
||||
ret = esp_apptrace_buffer_put(dest, ptr, ESP_APPTRACE_TMO_INFINITE);//TODO: finite tmo
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to put apptrace buffer (%d)!", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = esp_apptrace_flush(dest, ESP_APPTRACE_TMO_INFINITE);//TODO: finite tmo
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to flush apptrace buffer (%d)!", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_file_rsp_recv(esp_apptrace_dest_t dest, uint8_t *buf, uint32_t buf_len)
|
||||
{
|
||||
uint32_t tot_rd = 0;
|
||||
while (tot_rd < buf_len) {
|
||||
uint32_t rd_size = buf_len - tot_rd;
|
||||
esp_err_t ret = esp_apptrace_read(dest, buf, &rd_size, ESP_APPTRACE_TMO_INFINITE); //TODO: finite tmo
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return ret;
|
||||
}
|
||||
tot_rd += rd_size;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void esp_apptrace_fopen_args_prepare(uint8_t *buf, void *priv)
|
||||
{
|
||||
esp_apptrace_fopen_args_t *args = priv;
|
||||
|
||||
memcpy(buf, args->path, args->path_len);
|
||||
memcpy(buf + args->path_len, args->mode, args->mode_len);
|
||||
}
|
||||
|
||||
void *esp_apptrace_fopen(esp_apptrace_dest_t dest, const char *path, const char *mode)
|
||||
{
|
||||
esp_apptrace_fopen_args_t cmd_args;
|
||||
|
||||
cmd_args.path = path;
|
||||
cmd_args.path_len = strlen(path) + 1;
|
||||
cmd_args.mode = mode;
|
||||
cmd_args.mode_len = strlen(mode) + 1;
|
||||
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FOPEN, esp_apptrace_fopen_args_prepare,
|
||||
&cmd_args, cmd_args.path_len+cmd_args.mode_len);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// now read the answer
|
||||
uint8_t resp[sizeof(void *)];
|
||||
ret = esp_apptrace_file_rsp_recv(dest, resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return *((void **)resp);
|
||||
}
|
||||
|
||||
static void esp_apptrace_fclose_args_prepare(uint8_t *buf, void *priv)
|
||||
{
|
||||
esp_apptrace_fclose_args_t *args = priv;
|
||||
|
||||
memcpy(buf, &args->file, sizeof(args->file));
|
||||
}
|
||||
|
||||
int esp_apptrace_fclose(esp_apptrace_dest_t dest, void *stream)
|
||||
{
|
||||
esp_apptrace_fclose_args_t cmd_args;
|
||||
|
||||
cmd_args.file = stream;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FCLOSE, esp_apptrace_fclose_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
// now read the answer
|
||||
uint8_t resp[sizeof(int)];
|
||||
ret = esp_apptrace_file_rsp_recv(dest, resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
return *((int *)resp);
|
||||
}
|
||||
|
||||
static void esp_apptrace_fwrite_args_prepare(uint8_t *buf, void *priv)
|
||||
{
|
||||
esp_apptrace_fwrite_args_t *args = priv;
|
||||
|
||||
memcpy(buf, &args->file, sizeof(args->file));
|
||||
memcpy(buf + sizeof(args->file), args->buf, args->size);
|
||||
}
|
||||
|
||||
size_t esp_apptrace_fwrite(esp_apptrace_dest_t dest, const void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
esp_apptrace_fwrite_args_t cmd_args;
|
||||
|
||||
cmd_args.buf = (void *)ptr;
|
||||
cmd_args.size = size * nmemb;
|
||||
cmd_args.file = stream;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FWRITE, esp_apptrace_fwrite_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args.file)+cmd_args.size);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// now read the answer
|
||||
uint8_t resp[sizeof(size_t)];
|
||||
ret = esp_apptrace_file_rsp_recv(dest, resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return *((size_t *)resp);
|
||||
}
|
||||
|
||||
static void esp_apptrace_fread_args_prepare(uint8_t *buf, void *priv)
|
||||
{
|
||||
esp_apptrace_fread_args_t *args = priv;
|
||||
|
||||
memcpy(buf, &args->file, sizeof(args->file));
|
||||
memcpy(buf + sizeof(args->file), &args->size, sizeof(args->size));
|
||||
}
|
||||
|
||||
size_t esp_apptrace_fread(esp_apptrace_dest_t dest, void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
esp_apptrace_fread_args_t cmd_args;
|
||||
|
||||
cmd_args.size = size * nmemb;
|
||||
cmd_args.file = stream;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FREAD, esp_apptrace_fread_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// now read the answer
|
||||
uint8_t resp[sizeof(size_t)];
|
||||
ret = esp_apptrace_file_rsp_recv(dest, resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return 0;
|
||||
}
|
||||
if (*((size_t *)resp) > 0) {
|
||||
ret = esp_apptrace_file_rsp_recv(dest, ptr, *((size_t *)resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read file data (%d)!", ret);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return *((size_t *)resp);
|
||||
}
|
||||
|
||||
static void esp_apptrace_fseek_args_prepare(uint8_t *buf, void *priv)
|
||||
{
|
||||
esp_apptrace_fseek_args_t *args = priv;
|
||||
|
||||
memcpy(buf, &args->file, sizeof(args->file));
|
||||
}
|
||||
|
||||
int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int whence)
|
||||
{
|
||||
esp_apptrace_fseek_args_t cmd_args;
|
||||
|
||||
cmd_args.file = stream;
|
||||
cmd_args.offset = offset;
|
||||
cmd_args.whence = whence;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FSEEK, esp_apptrace_fseek_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// now read the answer
|
||||
uint8_t resp[sizeof(int)];
|
||||
ret = esp_apptrace_file_rsp_recv(dest, resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return *((int *)resp);
|
||||
}
|
||||
|
||||
static void esp_apptrace_ftell_args_prepare(uint8_t *buf, void *priv)
|
||||
{
|
||||
esp_apptrace_ftell_args_t *args = priv;
|
||||
|
||||
memcpy(buf, &args->file, sizeof(args->file));
|
||||
}
|
||||
|
||||
int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream)
|
||||
{
|
||||
esp_apptrace_ftell_args_t cmd_args;
|
||||
|
||||
cmd_args.file = stream;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FTELL, esp_apptrace_ftell_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// now read the answer
|
||||
uint8_t resp[sizeof(int)];
|
||||
ret = esp_apptrace_file_rsp_recv(dest, resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return *((int *)resp);
|
||||
}
|
||||
|
||||
int esp_apptrace_fstop(esp_apptrace_dest_t dest)
|
||||
{
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_STOP, NULL, NULL, 0);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
@@ -161,4 +161,105 @@ uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size,
|
||||
*/
|
||||
esp_err_t esp_apptrace_down_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Checks whether host is connected.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
*
|
||||
* @return true if host is connected, otherwise false
|
||||
*/
|
||||
bool esp_apptrace_host_is_connected(esp_apptrace_dest_t dest);
|
||||
|
||||
/**
|
||||
* @brief Opens file on host.
|
||||
* This function has the same semantic as 'fopen' except for the first argument.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
* @param path Path to file.
|
||||
* @param mode Mode string. See fopen for details.
|
||||
*
|
||||
* @return non zero file handle on success, otherwise 0
|
||||
*/
|
||||
void *esp_apptrace_fopen(esp_apptrace_dest_t dest, const char *path, const char *mode);
|
||||
|
||||
/**
|
||||
* @brief Closes file on host.
|
||||
* This function has the same semantic as 'fclose' except for the first argument.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
* @param stream File handle returned by esp_apptrace_fopen.
|
||||
*
|
||||
* @return Zero on success, otherwise non-zero. See fclose for details.
|
||||
*/
|
||||
int esp_apptrace_fclose(esp_apptrace_dest_t dest, void *stream);
|
||||
|
||||
/**
|
||||
* @brief Writes to file on host.
|
||||
* This function has the same semantic as 'fwrite' except for the first argument.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
* @param ptr Address of data to write.
|
||||
* @param size Size of an item.
|
||||
* @param nmemb Number of items to write.
|
||||
* @param stream File handle returned by esp_apptrace_fopen.
|
||||
*
|
||||
* @return Number of written items. See fwrite for details.
|
||||
*/
|
||||
size_t esp_apptrace_fwrite(esp_apptrace_dest_t dest, const void *ptr, size_t size, size_t nmemb, void *stream);
|
||||
|
||||
/**
|
||||
* @brief Read file on host.
|
||||
* This function has the same semantic as 'fread' except for the first argument.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
* @param ptr Address to store read data.
|
||||
* @param size Size of an item.
|
||||
* @param nmemb Number of items to read.
|
||||
* @param stream File handle returned by esp_apptrace_fopen.
|
||||
*
|
||||
* @return Number of read items. See fread for details.
|
||||
*/
|
||||
size_t esp_apptrace_fread(esp_apptrace_dest_t dest, void *ptr, size_t size, size_t nmemb, void *stream);
|
||||
|
||||
/**
|
||||
* @brief Set position indicator in file on host.
|
||||
* This function has the same semantic as 'fseek' except for the first argument.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
* @param stream File handle returned by esp_apptrace_fopen.
|
||||
* @param offset Offset. See fseek for details.
|
||||
* @param whence Position in file. See fseek for details.
|
||||
*
|
||||
* @return Zero on success, otherwise non-zero. See fseek for details.
|
||||
*/
|
||||
int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int whence);
|
||||
|
||||
/**
|
||||
* @brief Get current position indicator for file on host.
|
||||
* This function has the same semantic as 'ftell' except for the first argument.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
* @param stream File handle returned by esp_apptrace_fopen.
|
||||
*
|
||||
* @return Current position in file. See ftell for details.
|
||||
*/
|
||||
int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream);
|
||||
|
||||
/**
|
||||
* @brief Indicates to the host that all file operations are completed.
|
||||
* This function should be called after all file operations are finished and
|
||||
* indicate to the host that it can perform cleanup operations (close open files etc.).
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
int esp_apptrace_fstop(esp_apptrace_dest_t dest);
|
||||
|
||||
/**
|
||||
* @brief Triggers gcov info dump.
|
||||
* This function waits for the host to connect to target before dumping data.
|
||||
*/
|
||||
void esp_gcov_dump(void);
|
||||
|
||||
#endif
|
||||
|
@@ -89,13 +89,13 @@ SECTIONS
|
||||
*libesp32.a:core_dump.o(.literal .text .literal.* .text.*)
|
||||
*libapp_trace.a:(.literal .text .literal.* .text.*)
|
||||
*libxtensa-debug-module.a:eri.o(.literal .text .literal.* .text.*)
|
||||
*libesp32.a:app_trace.o(.literal .text .literal.* .text.*)
|
||||
*libphy.a:(.literal .text .literal.* .text.*)
|
||||
*librtc.a:(.literal .text .literal.* .text.*)
|
||||
*libsoc.a:(.literal .text .literal.* .text.*)
|
||||
*libhal.a:(.literal .text .literal.* .text.*)
|
||||
*libgcc.a:lib2funcs.o(.literal .text .literal.* .text.*)
|
||||
*libspi_flash.a:spi_flash_rom_patch.o(.literal .text .literal.* .text.*)
|
||||
*libgcov.a:(.literal .text .literal.* .text.*)
|
||||
_iram_text_end = ABSOLUTE(.);
|
||||
} > iram0_0_seg
|
||||
|
||||
@@ -117,6 +117,7 @@ SECTIONS
|
||||
*libesp32.a:panic.o(.rodata .rodata.*)
|
||||
*libphy.a:(.rodata .rodata.*)
|
||||
*libapp_trace.a:(.rodata .rodata.*)
|
||||
*libgcov.a:(.rodata .rodata.*)
|
||||
*libheap.a:multi_heap.o(.rodata .rodata.*)
|
||||
*libheap.a:multi_heap_poisoning.o(.rodata .rodata.*)
|
||||
_data_end = ABSOLUTE(.);
|
||||
|
Reference in New Issue
Block a user