mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
app_trace: support gptimer as timestamp source
This commit is contained in:
parent
e36f47a153
commit
02f6b83f47
@ -94,7 +94,7 @@ menu "Application Level Tracing"
|
||||
prompt "Timer to use as timestamp source"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default APPTRACE_SV_TS_SOURCE_CCOUNT if FREERTOS_UNICORE && !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
default APPTRACE_SV_TS_SOURCE_TIMER_00 if !FREERTOS_UNICORE && !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
default APPTRACE_SV_TS_SOURCE_GPTIMER if !FREERTOS_UNICORE && !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
default APPTRACE_SV_TS_SOURCE_ESP_TIMER if PM_ENABLE || IDF_TARGET_ESP32C3
|
||||
help
|
||||
SystemView needs to use a hardware timer as the source of timestamps
|
||||
@ -104,20 +104,8 @@ menu "Application Level Tracing"
|
||||
bool "CPU cycle counter (CCOUNT)"
|
||||
depends on FREERTOS_UNICORE && !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
|
||||
config APPTRACE_SV_TS_SOURCE_TIMER_00
|
||||
bool "Timer 0, Group 0"
|
||||
depends on !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
|
||||
config APPTRACE_SV_TS_SOURCE_TIMER_01
|
||||
bool "Timer 1, Group 0"
|
||||
depends on !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
|
||||
config APPTRACE_SV_TS_SOURCE_TIMER_10
|
||||
bool "Timer 0, Group 1"
|
||||
depends on !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
|
||||
config APPTRACE_SV_TS_SOURCE_TIMER_11
|
||||
bool "Timer 1, Group 1"
|
||||
config APPTRACE_SV_TS_SOURCE_GPTIMER
|
||||
bool "General Purpose Timer (Timer Group)"
|
||||
depends on !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
|
||||
config APPTRACE_SV_TS_SOURCE_ESP_TIMER
|
||||
|
@ -12,8 +12,7 @@ entries:
|
||||
[mapping:app_trace_driver]
|
||||
archive: libdriver.a
|
||||
entries:
|
||||
if APPTRACE_SV_TS_SOURCE_TIMER_00 = y || APPTRACE_SV_TS_SOURCE_TIMER_01 = y
|
||||
|| APPTRACE_SV_TS_SOURCE_TIMER_10 = y || APPTRACE_SV_TS_SOURCE_TIMER_11 = y:
|
||||
timer (noflash)
|
||||
if APPTRACE_SV_TS_SOURCE_GPTIMER = y:
|
||||
gptimer (noflash)
|
||||
else:
|
||||
* (default)
|
||||
|
@ -14,10 +14,6 @@ CONFIG_ESP32_GCOV_ENABLE CONFIG_APPTRACE_GCOV_ENABLE
|
||||
CONFIG_SYSVIEW_ENABLE CONFIG_APPTRACE_SV_ENABLE
|
||||
CONFIG_SYSVIEW_TS_SOURCE CONFIG_APPTRACE_SV_TS_SOURCE
|
||||
CONFIG_SYSVIEW_TS_SOURCE_CCOUNT CONFIG_APPTRACE_SV_TS_SOURCE_CCOUNT
|
||||
CONFIG_SYSVIEW_TS_SOURCE_TIMER_00 CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00
|
||||
CONFIG_SYSVIEW_TS_SOURCE_TIMER_01 CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_01
|
||||
CONFIG_SYSVIEW_TS_SOURCE_TIMER_10 CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_10
|
||||
CONFIG_SYSVIEW_TS_SOURCE_TIMER_11 CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_11
|
||||
CONFIG_SYSVIEW_TS_SOURCE_ESP_TIMER CONFIG_APPTRACE_SV_TS_SOURCE_ESP_TIMER
|
||||
CONFIG_SYSVIEW_MAX_TASKS CONFIG_APPTRACE_SV_MAX_TASKS
|
||||
CONFIG_SYSVIEW_BUF_WAIT_TMO CONFIG_APPTRACE_SV_BUF_WAIT_TMO
|
||||
|
@ -101,26 +101,16 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
|
||||
#endif
|
||||
|
||||
#if TS_USE_TIMERGROUP
|
||||
#include "driver/timer.h"
|
||||
#include "driver/gptimer.h"
|
||||
|
||||
// Timer group timer divisor
|
||||
#define SYSVIEW_TIMER_DIV 2
|
||||
|
||||
// Frequency of the timestamp.
|
||||
// Frequency of the timestamp, using APB as GPTimer source clock
|
||||
#define SYSVIEW_TIMESTAMP_FREQ (esp_clk_apb_freq() / SYSVIEW_TIMER_DIV)
|
||||
|
||||
// Timer ID and group ID
|
||||
#if defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00) || defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_10)
|
||||
#define TS_TIMER_ID 0
|
||||
#else
|
||||
#define TS_TIMER_ID 1
|
||||
#endif // TIMER_00 || TIMER_01
|
||||
|
||||
#if defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00) || defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_01)
|
||||
#define TS_TIMER_GROUP 0
|
||||
#else
|
||||
#define TS_TIMER_GROUP 1
|
||||
#endif // TIMER_00 || TIMER_10
|
||||
// GPTimer handle
|
||||
gptimer_handle_t s_sv_gptimer;
|
||||
|
||||
#endif // TS_USE_TIMERGROUP
|
||||
|
||||
@ -199,19 +189,15 @@ static void SEGGER_SYSVIEW_TS_Init(void)
|
||||
* esp_timer and ccount can be used as is.
|
||||
*/
|
||||
#if TS_USE_TIMERGROUP
|
||||
timer_config_t config = {
|
||||
.alarm_en = 0,
|
||||
.auto_reload = 0,
|
||||
.counter_dir = TIMER_COUNT_UP,
|
||||
.divider = SYSVIEW_TIMER_DIV,
|
||||
.counter_en = 0
|
||||
gptimer_config_t config = {
|
||||
.clk_src = GPTIMER_CLK_SRC_APB,
|
||||
.direction = GPTIMER_COUNT_UP,
|
||||
.resolution_hz = SYSVIEW_TIMESTAMP_FREQ,
|
||||
};
|
||||
/* Configure timer */
|
||||
timer_init(TS_TIMER_GROUP, TS_TIMER_ID, &config);
|
||||
/* Load counter value */
|
||||
timer_set_counter_value(TS_TIMER_GROUP, TS_TIMER_ID, 0x00000000ULL);
|
||||
// pick any free GPTimer instance
|
||||
ESP_ERROR_CHECK(gptimer_new_timer(&config, &s_sv_gptimer));
|
||||
/* Start counting */
|
||||
timer_start(TS_TIMER_GROUP, TS_TIMER_ID);
|
||||
gptimer_start(s_sv_gptimer);
|
||||
#endif // TS_USE_TIMERGROUP
|
||||
}
|
||||
|
||||
@ -269,7 +255,7 @@ U32 SEGGER_SYSVIEW_X_GetTimestamp(void)
|
||||
{
|
||||
#if TS_USE_TIMERGROUP
|
||||
uint64_t ts = 0;
|
||||
timer_get_counter_value(TS_TIMER_GROUP, TS_TIMER_ID, &ts);
|
||||
gptimer_get_raw_count(s_sv_gptimer, &ts);
|
||||
return (U32) ts; // return lower part of counter value
|
||||
#elif TS_USE_CCOUNT
|
||||
return portGET_RUN_TIME_COUNTER_VALUE();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -9,7 +9,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "unity.h"
|
||||
#include "driver/timer.h"
|
||||
#include "driver/gptimer.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
@ -64,29 +65,6 @@ const static char *TAG = "esp_apptrace_test";
|
||||
#define ESP_APPTRACE_TEST_LOGV( format, ... ) ESP_APPTRACE_TEST_LOG_LEVEL(V, ESP_LOG_VERBOSE, format, ##__VA_ARGS__)
|
||||
#define ESP_APPTRACE_TEST_LOGO( format, ... ) ESP_APPTRACE_TEST_LOG_LEVEL(E, ESP_LOG_NONE, format, ##__VA_ARGS__)
|
||||
|
||||
static void esp_apptrace_test_timer_init(int timer_group, int timer_idx, uint32_t period)
|
||||
{
|
||||
uint64_t alarm_val = (period * (TIMER_BASE_CLK / 1000000UL)) / 2;
|
||||
timer_config_t config = {
|
||||
.alarm_en = 1,
|
||||
.auto_reload = 1,
|
||||
.counter_dir = TIMER_COUNT_UP,
|
||||
.divider = 2, //Range is 2 to 65536
|
||||
.intr_type = TIMER_INTR_LEVEL,
|
||||
.counter_en = TIMER_PAUSE,
|
||||
};
|
||||
/*Configure timer*/
|
||||
timer_init(timer_group, timer_idx, &config);
|
||||
/*Stop timer counter*/
|
||||
timer_pause(timer_group, timer_idx);
|
||||
/*Load counter value */
|
||||
timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL);
|
||||
/*Set alarm value*/
|
||||
timer_set_alarm_value(timer_group, timer_idx, alarm_val);
|
||||
/*Enable timer interrupt*/
|
||||
timer_enable_intr(timer_group, timer_idx);
|
||||
}
|
||||
|
||||
#if CONFIG_APPTRACE_SV_ENABLE == 0
|
||||
#define ESP_APPTRACE_TEST_WRITE(_b_, _s_) esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, _b_, _s_, ESP_APPTRACE_TMO_INFINITE)
|
||||
#define ESP_APPTRACE_TEST_WRITE_FROM_ISR(_b_, _s_) esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, _b_, _s_, 0UL)
|
||||
@ -102,9 +80,8 @@ typedef struct {
|
||||
} esp_apptrace_test_gen_data_t;
|
||||
|
||||
typedef struct {
|
||||
int group;
|
||||
int id;
|
||||
void (*isr_func)(void *);
|
||||
gptimer_handle_t gptimer;
|
||||
bool (*isr_func)(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx);
|
||||
esp_apptrace_test_gen_data_t data;
|
||||
} esp_apptrace_test_timer_arg_t;
|
||||
|
||||
@ -116,7 +93,6 @@ typedef struct {
|
||||
esp_apptrace_test_gen_data_t data;
|
||||
volatile int stop;
|
||||
SemaphoreHandle_t done;
|
||||
|
||||
uint32_t timers_num;
|
||||
esp_apptrace_test_timer_arg_t *timers;
|
||||
} esp_apptrace_test_task_arg_t;
|
||||
@ -132,86 +108,75 @@ static SemaphoreHandle_t s_print_lock;
|
||||
|
||||
static uint64_t esp_apptrace_test_ts_get(void);
|
||||
|
||||
static void esp_apptrace_test_timer_isr(void *arg)
|
||||
static bool esp_apptrace_test_timer_isr(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
|
||||
{
|
||||
esp_apptrace_test_timer_arg_t *tim_arg = (esp_apptrace_test_timer_arg_t *)arg;
|
||||
esp_apptrace_test_timer_arg_t *tim_arg = (esp_apptrace_test_timer_arg_t *)user_ctx;
|
||||
|
||||
uint32_t *ts = (uint32_t *)(tim_arg->data.buf + sizeof(uint32_t));
|
||||
*ts = (uint32_t)esp_apptrace_test_ts_get();
|
||||
memset(tim_arg->data.buf + 2 * sizeof(uint32_t), tim_arg->data.wr_cnt & tim_arg->data.mask, tim_arg->data.buf_sz - 2 * sizeof(uint32_t));
|
||||
int res = ESP_APPTRACE_TEST_WRITE_FROM_ISR(tim_arg->data.buf, tim_arg->data.buf_sz);
|
||||
if (res != ESP_OK) {
|
||||
} else {
|
||||
if (0) {
|
||||
esp_rom_printf("tim-%d-%d: Written chunk%d %d bytes, %x\n",
|
||||
tim_arg->group, tim_arg->id, tim_arg->data.wr_cnt, tim_arg->data.buf_sz, tim_arg->data.wr_cnt & tim_arg->data.mask);
|
||||
}
|
||||
if (res == ESP_OK) {
|
||||
tim_arg->data.wr_err = 0;
|
||||
}
|
||||
|
||||
tim_arg->data.wr_cnt++;
|
||||
timer_group_clr_intr_status_in_isr(tim_arg->group, tim_arg->id);
|
||||
timer_group_enable_alarm_in_isr(tim_arg->group, tim_arg->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void esp_apptrace_test_timer_isr_crash(void *arg)
|
||||
static bool esp_apptrace_test_timer_isr_crash(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
|
||||
{
|
||||
esp_apptrace_test_timer_arg_t *tim_arg = (esp_apptrace_test_timer_arg_t *)arg;
|
||||
esp_apptrace_test_timer_arg_t *tim_arg = (esp_apptrace_test_timer_arg_t *)user_ctx;
|
||||
|
||||
timer_group_clr_intr_status_in_isr(tim_arg->group, tim_arg->id);
|
||||
timer_group_enable_alarm_in_isr(tim_arg->group, tim_arg->id);
|
||||
if (tim_arg->data.wr_cnt < ESP_APPTRACE_TEST_BLOCKS_BEFORE_CRASH) {
|
||||
uint32_t *ts = (uint32_t *)(tim_arg->data.buf + sizeof(uint32_t));
|
||||
*ts = (uint32_t)esp_apptrace_test_ts_get();//xthal_get_ccount();//xTaskGetTickCount();
|
||||
memset(tim_arg->data.buf + 2 * sizeof(uint32_t), tim_arg->data.wr_cnt & tim_arg->data.mask, tim_arg->data.buf_sz - 2 * sizeof(uint32_t));
|
||||
int res = ESP_APPTRACE_TEST_WRITE_FROM_ISR(tim_arg->data.buf, tim_arg->data.buf_sz);
|
||||
if (res != ESP_OK) {
|
||||
esp_rom_printf("tim-%d-%d: Failed to write trace %d %x!\n", tim_arg->group, tim_arg->id, res, tim_arg->data.wr_cnt & tim_arg->data.mask);
|
||||
esp_rom_printf("tim-%x: Failed to write trace %d %x!\n", tim_arg->gptimer, res, tim_arg->data.wr_cnt & tim_arg->data.mask);
|
||||
} else {
|
||||
esp_rom_printf("tim-%d-%d: Written chunk%d %d bytes, %x\n",
|
||||
tim_arg->group, tim_arg->id, tim_arg->data.wr_cnt, tim_arg->data.buf_sz, tim_arg->data.wr_cnt & tim_arg->data.mask);
|
||||
esp_rom_printf("tim-%x: Written chunk%d %d bytes, %x\n",
|
||||
timer, tim_arg->data.wr_cnt, tim_arg->data.buf_sz, tim_arg->data.wr_cnt & tim_arg->data.mask);
|
||||
tim_arg->data.wr_cnt++;
|
||||
}
|
||||
} else {
|
||||
uint32_t *ptr = 0;
|
||||
*ptr = 1000;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void esp_apptrace_dummy_task(void *p)
|
||||
{
|
||||
esp_apptrace_test_task_arg_t *arg = (esp_apptrace_test_task_arg_t *) p;
|
||||
int res, flags = 0, i;
|
||||
timer_isr_handle_t *inth = NULL;
|
||||
TickType_t tmo_ticks = arg->data.period / (1000 * portTICK_PERIOD_MS);
|
||||
|
||||
ESP_APPTRACE_TEST_LOGI("%x: run dummy task (period %u us, %u timers)", xTaskGetCurrentTaskHandle(), arg->data.period, arg->timers_num);
|
||||
|
||||
if (arg->timers_num > 0) {
|
||||
inth = pvPortMalloc(arg->timers_num * sizeof(timer_isr_handle_t));
|
||||
if (!inth) {
|
||||
ESP_APPTRACE_TEST_LOGE("Failed to alloc timer ISR handles!");
|
||||
goto on_fail;
|
||||
}
|
||||
memset(inth, 0, arg->timers_num * sizeof(timer_isr_handle_t));
|
||||
for (int i = 0; i < arg->timers_num; i++) {
|
||||
esp_apptrace_test_timer_init(arg->timers[i].group, arg->timers[i].id, arg->timers[i].data.period);
|
||||
res = timer_isr_register(arg->timers[i].group, arg->timers[i].id, arg->timers[i].isr_func, &arg->timers[i], flags, &inth[i]);
|
||||
if (res != ESP_OK) {
|
||||
ESP_APPTRACE_TEST_LOGE("Failed to timer_isr_register (%d)!", res);
|
||||
goto on_fail;
|
||||
}
|
||||
*(uint32_t *)arg->timers[i].data.buf = (uint32_t)inth[i] | (1 << 31);
|
||||
ESP_APPTRACE_TEST_LOGI("%x: start timer %x period %u us", xTaskGetCurrentTaskHandle(), inth[i], arg->timers[i].data.period);
|
||||
res = timer_start(arg->timers[i].group, arg->timers[i].id);
|
||||
if (res != ESP_OK) {
|
||||
ESP_APPTRACE_TEST_LOGE("Failed to timer_start (%d)!", res);
|
||||
goto on_fail;
|
||||
}
|
||||
}
|
||||
gptimer_config_t timer_config = {
|
||||
.clk_src = GPTIMER_CLK_SRC_APB,
|
||||
.direction = GPTIMER_COUNT_UP,
|
||||
.resolution_hz = 1000000,
|
||||
};
|
||||
TEST_ESP_OK(gptimer_new_timer(&timer_config, &arg->timers[i].gptimer));
|
||||
*(uint32_t *)arg->timers[i].data.buf = (uint32_t)arg->timers[i].gptimer | (1 << 31);
|
||||
ESP_APPTRACE_TEST_LOGI("%x: start timer %x period %u us", xTaskGetCurrentTaskHandle(), arg->timers[i].gptimer, arg->timers[i].data.period);
|
||||
gptimer_alarm_config_t alarm_config = {
|
||||
.reload_count = 0,
|
||||
.alarm_count = arg->timers[i].data.period,
|
||||
.flags.auto_reload_on_alarm = true,
|
||||
};
|
||||
gptimer_event_callbacks_t cbs = {
|
||||
.on_alarm = arg->timers[i].isr_func,
|
||||
};
|
||||
TEST_ESP_OK(gptimer_register_event_callbacks(arg->timers[i].gptimer, &cbs, &arg->timers[i]));
|
||||
TEST_ESP_OK(gptimer_set_alarm_action(arg->timers[i].gptimer, &alarm_config));
|
||||
TEST_ESP_OK(gptimer_start(arg->timers[i].gptimer));
|
||||
}
|
||||
|
||||
i = 0;
|
||||
int i = 0;
|
||||
while (!arg->stop) {
|
||||
ESP_APPTRACE_TEST_LOGD("%x: dummy task work %d.%d", xTaskGetCurrentTaskHandle(), cpu_hal_get_core_id(), i++);
|
||||
if (tmo_ticks) {
|
||||
@ -219,16 +184,9 @@ static void esp_apptrace_dummy_task(void *p)
|
||||
}
|
||||
}
|
||||
|
||||
on_fail:
|
||||
if (inth) {
|
||||
for (int i = 0; i < arg->timers_num; i++) {
|
||||
timer_pause(arg->timers[i].group, arg->timers[i].id);
|
||||
timer_disable_intr(arg->timers[i].group, arg->timers[i].id);
|
||||
if (inth[i]) {
|
||||
esp_intr_free(inth[i]);
|
||||
}
|
||||
}
|
||||
vPortFree(inth);
|
||||
TEST_ESP_OK(gptimer_stop(arg->timers[i].gptimer));
|
||||
TEST_ESP_OK(gptimer_del_timer(arg->timers[i].gptimer));
|
||||
}
|
||||
xSemaphoreGive(arg->done);
|
||||
vTaskDelay(1);
|
||||
@ -238,34 +196,31 @@ on_fail:
|
||||
static void esp_apptrace_test_task(void *p)
|
||||
{
|
||||
esp_apptrace_test_task_arg_t *arg = (esp_apptrace_test_task_arg_t *) p;
|
||||
int res, flags = 0;
|
||||
timer_isr_handle_t *inth = NULL;
|
||||
int res;
|
||||
TickType_t tmo_ticks = arg->data.period / (1000 * portTICK_PERIOD_MS);
|
||||
|
||||
ESP_APPTRACE_TEST_LOGI("%x: run (period %u us, stamp mask %x, %u timers)", xTaskGetCurrentTaskHandle(), arg->data.period, arg->data.mask, arg->timers_num);
|
||||
|
||||
if (arg->timers_num > 0) {
|
||||
inth = pvPortMalloc(arg->timers_num * sizeof(timer_isr_handle_t));
|
||||
if (!inth) {
|
||||
ESP_APPTRACE_TEST_LOGE("Failed to alloc timer ISR handles!");
|
||||
goto on_fail;
|
||||
}
|
||||
memset(inth, 0, arg->timers_num * sizeof(timer_isr_handle_t));
|
||||
for (int i = 0; i < arg->timers_num; i++) {
|
||||
esp_apptrace_test_timer_init(arg->timers[i].group, arg->timers[i].id, arg->timers[i].data.period);
|
||||
res = timer_isr_register(arg->timers[i].group, arg->timers[i].id, arg->timers[i].isr_func, &arg->timers[i], flags, &inth[i]);
|
||||
if (res != ESP_OK) {
|
||||
ESP_APPTRACE_TEST_LOGE("Failed to timer_isr_register (%d)!", res);
|
||||
goto on_fail;
|
||||
}
|
||||
*(uint32_t *)arg->timers[i].data.buf = ((uint32_t)inth[i]) | (1 << 31) | (cpu_hal_get_core_id() ? 0x1 : 0);
|
||||
ESP_APPTRACE_TEST_LOGI("%x: start timer %x period %u us", xTaskGetCurrentTaskHandle(), inth[i], arg->timers[i].data.period);
|
||||
res = timer_start(arg->timers[i].group, arg->timers[i].id);
|
||||
if (res != ESP_OK) {
|
||||
ESP_APPTRACE_TEST_LOGE("Failed to timer_start (%d)!", res);
|
||||
goto on_fail;
|
||||
}
|
||||
}
|
||||
gptimer_config_t timer_config = {
|
||||
.clk_src = GPTIMER_CLK_SRC_APB,
|
||||
.direction = GPTIMER_COUNT_UP,
|
||||
.resolution_hz = 1000000,
|
||||
};
|
||||
TEST_ESP_OK(gptimer_new_timer(&timer_config, &arg->timers[i].gptimer));
|
||||
*(uint32_t *)arg->timers[i].data.buf = ((uint32_t)arg->timers[i].gptimer) | (1 << 31) | (cpu_hal_get_core_id() ? 0x1 : 0);
|
||||
ESP_APPTRACE_TEST_LOGI("%x: start timer %x period %u us", xTaskGetCurrentTaskHandle(), arg->timers[i].gptimer, arg->timers[i].data.period);
|
||||
gptimer_alarm_config_t alarm_config = {
|
||||
.reload_count = 0,
|
||||
.alarm_count = arg->timers[i].data.period,
|
||||
.flags.auto_reload_on_alarm = true,
|
||||
};
|
||||
gptimer_event_callbacks_t cbs = {
|
||||
.on_alarm = arg->timers[i].isr_func,
|
||||
};
|
||||
TEST_ESP_OK(gptimer_register_event_callbacks(arg->timers[i].gptimer, &cbs, &arg->timers[i]));
|
||||
TEST_ESP_OK(gptimer_set_alarm_action(arg->timers[i].gptimer, &alarm_config));
|
||||
TEST_ESP_OK(gptimer_start(arg->timers[i].gptimer));
|
||||
}
|
||||
|
||||
*(uint32_t *)arg->data.buf = (uint32_t)xTaskGetCurrentTaskHandle() | (cpu_hal_get_core_id() ? 0x1 : 0);
|
||||
@ -282,7 +237,7 @@ static void esp_apptrace_test_task(void *p)
|
||||
res = ESP_APPTRACE_TEST_WRITE(arg->data.buf, arg->data.buf_sz);
|
||||
}
|
||||
if (res) {
|
||||
if (1){//arg->data.wr_err++ < ESP_APPTRACE_TEST_PRN_WRERR_MAX) {
|
||||
if (1) { //arg->data.wr_err++ < ESP_APPTRACE_TEST_PRN_WRERR_MAX) {
|
||||
ESP_APPTRACE_TEST_LOGE("%x: Failed to write trace %d %x!", xTaskGetCurrentTaskHandle(), res, arg->data.wr_cnt & arg->data.mask);
|
||||
if (arg->data.wr_err == ESP_APPTRACE_TEST_PRN_WRERR_MAX) {
|
||||
ESP_APPTRACE_TEST_LOGE("\n");
|
||||
@ -300,16 +255,9 @@ static void esp_apptrace_test_task(void *p)
|
||||
}
|
||||
}
|
||||
|
||||
on_fail:
|
||||
if (inth) {
|
||||
for (int i = 0; i < arg->timers_num; i++) {
|
||||
timer_pause(arg->timers[i].group, arg->timers[i].id);
|
||||
timer_disable_intr(arg->timers[i].group, arg->timers[i].id);
|
||||
if (inth[i]) {
|
||||
esp_intr_free(inth[i]);
|
||||
}
|
||||
}
|
||||
vPortFree(inth);
|
||||
TEST_ESP_OK(gptimer_stop(arg->timers[i].gptimer));
|
||||
TEST_ESP_OK(gptimer_del_timer(arg->timers[i].gptimer));
|
||||
}
|
||||
xSemaphoreGive(arg->done);
|
||||
vTaskDelay(1);
|
||||
@ -319,17 +267,16 @@ on_fail:
|
||||
static void esp_apptrace_test_task_crash(void *p)
|
||||
{
|
||||
esp_apptrace_test_task_arg_t *arg = (esp_apptrace_test_task_arg_t *) p;
|
||||
int res, i;
|
||||
|
||||
ESP_APPTRACE_TEST_LOGE("%x: run (period %u us, stamp mask %x, %u timers)", xTaskGetCurrentTaskHandle(), arg->data.period, arg->data.mask, arg->timers_num);
|
||||
|
||||
arg->data.wr_cnt = 0;
|
||||
*(uint32_t *)arg->data.buf = (uint32_t)xTaskGetCurrentTaskHandle();
|
||||
for (i = 0; i < ESP_APPTRACE_TEST_BLOCKS_BEFORE_CRASH; i++) {
|
||||
for (int i = 0; i < ESP_APPTRACE_TEST_BLOCKS_BEFORE_CRASH; i++) {
|
||||
uint32_t *ts = (uint32_t *)(arg->data.buf + sizeof(uint32_t));
|
||||
*ts = (uint32_t)esp_apptrace_test_ts_get();
|
||||
memset(arg->data.buf + sizeof(uint32_t), arg->data.wr_cnt & arg->data.mask, arg->data.buf_sz - sizeof(uint32_t));
|
||||
res = ESP_APPTRACE_TEST_WRITE(arg->data.buf, arg->data.buf_sz);
|
||||
int res = ESP_APPTRACE_TEST_WRITE(arg->data.buf, arg->data.buf_sz);
|
||||
if (res) {
|
||||
ESP_APPTRACE_TEST_LOGE("%x: Failed to write trace %d %x!", xTaskGetCurrentTaskHandle(), res, arg->data.wr_cnt & arg->data.mask);
|
||||
} else {
|
||||
@ -346,67 +293,47 @@ static void esp_apptrace_test_task_crash(void *p)
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static int s_ts_timer_group, s_ts_timer_idx;
|
||||
static gptimer_handle_t ts_gptimer;
|
||||
|
||||
static uint64_t esp_apptrace_test_ts_get(void)
|
||||
{
|
||||
uint64_t ts = 0;
|
||||
timer_get_counter_value(s_ts_timer_group, s_ts_timer_idx, &ts);
|
||||
gptimer_get_raw_count(ts_gptimer, &ts);
|
||||
return ts;
|
||||
}
|
||||
|
||||
static void esp_apptrace_test_ts_init(int timer_group, int timer_idx)
|
||||
static void esp_apptrace_test_ts_init(void)
|
||||
{
|
||||
//uint64_t alarm_val = period * (TIMER_BASE_CLK / 1000000UL);
|
||||
|
||||
ESP_APPTRACE_TEST_LOGI("Use timer%d.%d for TS", timer_group, timer_idx);
|
||||
|
||||
s_ts_timer_group = timer_group;
|
||||
s_ts_timer_idx = timer_idx;
|
||||
|
||||
timer_config_t config = {
|
||||
.alarm_en = 0,
|
||||
.auto_reload = 0,
|
||||
.counter_dir = TIMER_COUNT_UP,
|
||||
.divider = 2, //Range is 2 to 65536
|
||||
.counter_en = 0,
|
||||
gptimer_config_t timer_config = {
|
||||
.clk_src = GPTIMER_CLK_SRC_APB,
|
||||
.direction = GPTIMER_COUNT_UP,
|
||||
.resolution_hz = 10000000,
|
||||
};
|
||||
/*Configure timer*/
|
||||
timer_init(timer_group, timer_idx, &config);
|
||||
/*Load counter value */
|
||||
timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL);
|
||||
/*Enable timer interrupt*/
|
||||
timer_start(timer_group, timer_idx);
|
||||
TEST_ESP_OK(gptimer_new_timer(&timer_config, &ts_gptimer));
|
||||
ESP_APPTRACE_TEST_LOGI("Use timer %x for TS", ts_gptimer);
|
||||
TEST_ESP_OK(gptimer_start(ts_gptimer));
|
||||
}
|
||||
|
||||
static void esp_apptrace_test_ts_cleanup(void)
|
||||
{
|
||||
timer_config_t config = {
|
||||
.alarm_en = 0,
|
||||
.auto_reload = 0,
|
||||
.counter_dir = TIMER_COUNT_UP,
|
||||
.divider = 2, //Range is 2 to 65536
|
||||
.counter_en = 0,
|
||||
};
|
||||
/*Configure timer*/
|
||||
timer_init(s_ts_timer_group, s_ts_timer_idx, &config);
|
||||
TEST_ESP_OK(gptimer_stop(ts_gptimer));
|
||||
TEST_ESP_OK(gptimer_del_timer(ts_gptimer));
|
||||
ts_gptimer = NULL;
|
||||
}
|
||||
|
||||
static void esp_apptrace_test(esp_apptrace_test_cfg_t *test_cfg)
|
||||
{
|
||||
int i, k;
|
||||
int tims_in_use[TIMER_GROUP_MAX][TIMER_MAX] = {{0, 0}, {0, 0}};
|
||||
esp_apptrace_test_task_arg_t dummy_task_arg[1];
|
||||
esp_apptrace_test_task_arg_t dummy_task_arg = {
|
||||
.core = 0,
|
||||
.prio = 3,
|
||||
.task_func = esp_apptrace_test_task_crash,
|
||||
.data.buf = NULL,
|
||||
.data.buf_sz = 0,
|
||||
.data.period = 500000,
|
||||
.timers_num = 0,
|
||||
.timers = NULL,
|
||||
};
|
||||
|
||||
memset(dummy_task_arg, 0, sizeof(dummy_task_arg));
|
||||
dummy_task_arg[0].core = 0;
|
||||
dummy_task_arg[0].prio = 3;
|
||||
dummy_task_arg[0].task_func = esp_apptrace_test_task_crash;
|
||||
dummy_task_arg[0].data.buf = NULL;
|
||||
dummy_task_arg[0].data.buf_sz = 0;
|
||||
dummy_task_arg[0].data.period = 500000;
|
||||
dummy_task_arg[0].timers_num = 0;
|
||||
dummy_task_arg[0].timers = NULL;
|
||||
#if ESP_APPTRACE_TEST_USE_PRINT_LOCK == 1
|
||||
s_print_lock = xSemaphoreCreateBinary();
|
||||
if (!s_print_lock) {
|
||||
@ -417,38 +344,17 @@ static void esp_apptrace_test(esp_apptrace_test_cfg_t *test_cfg)
|
||||
#else
|
||||
#endif
|
||||
|
||||
for (i = 0; i < test_cfg->tasks_num; i++) {
|
||||
for (int i = 0; i < test_cfg->tasks_num; i++) {
|
||||
test_cfg->tasks[i].data.mask = 0xFF;
|
||||
test_cfg->tasks[i].stop = 0;
|
||||
test_cfg->tasks[i].done = xSemaphoreCreateBinary();
|
||||
if (!test_cfg->tasks[i].done) {
|
||||
ESP_APPTRACE_TEST_LOGE("Failed to create task completion semaphore!");
|
||||
goto on_fail;
|
||||
}
|
||||
for (k = 0; k < test_cfg->tasks[i].timers_num; k++) {
|
||||
TEST_ASSERT_NOT_NULL(test_cfg->tasks[i].done);
|
||||
for (int k = 0; k < test_cfg->tasks[i].timers_num; k++) {
|
||||
test_cfg->tasks[i].timers[k].data.mask = 0xFF;
|
||||
tims_in_use[test_cfg->tasks[i].timers[k].group][test_cfg->tasks[i].timers[k].id] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int found = 0;
|
||||
for (i = 0; i < TIMER_GROUP_MAX; i++) {
|
||||
for (k = 0; k < TIMER_MAX; k++) {
|
||||
if (!tims_in_use[i][k]) {
|
||||
ESP_APPTRACE_TEST_LOGD("Found timer%d.%d", i, k);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
ESP_APPTRACE_TEST_LOGE("No free timer for TS!");
|
||||
goto on_fail;
|
||||
}
|
||||
esp_apptrace_test_ts_init(i, k);
|
||||
esp_apptrace_test_ts_init();
|
||||
|
||||
for (int i = 0; i < test_cfg->tasks_num; i++) {
|
||||
char name[30];
|
||||
@ -457,16 +363,15 @@ static void esp_apptrace_test(esp_apptrace_test_cfg_t *test_cfg)
|
||||
xTaskCreatePinnedToCore(test_cfg->tasks[i].task_func, name, 2048, &test_cfg->tasks[i], test_cfg->tasks[i].prio, &thnd, test_cfg->tasks[i].core);
|
||||
ESP_APPTRACE_TEST_LOGI("Created task %x", thnd);
|
||||
}
|
||||
xTaskCreatePinnedToCore(esp_apptrace_dummy_task, "dummy0", 2048, &dummy_task_arg[0], dummy_task_arg[0].prio, NULL, 0);
|
||||
xTaskCreatePinnedToCore(esp_apptrace_dummy_task, "dummy0", 2048, &dummy_task_arg, dummy_task_arg.prio, NULL, 0);
|
||||
#if CONFIG_FREERTOS_UNICORE == 0
|
||||
xTaskCreatePinnedToCore(esp_apptrace_dummy_task, "dummy1", 2048, &dummy_task_arg[0], dummy_task_arg[0].prio, NULL, 1);
|
||||
xTaskCreatePinnedToCore(esp_apptrace_dummy_task, "dummy1", 2048, &dummy_task_arg, dummy_task_arg.prio, NULL, 1);
|
||||
#endif
|
||||
for (int i = 0; i < test_cfg->tasks_num; i++) {
|
||||
//arg1.stop = 1;
|
||||
xSemaphoreTake(test_cfg->tasks[i].done, portMAX_DELAY);
|
||||
}
|
||||
|
||||
on_fail:
|
||||
for (int i = 0; i < test_cfg->tasks_num; i++) {
|
||||
if (test_cfg->tasks[i].done) {
|
||||
vSemaphoreDelete(test_cfg->tasks[i].done);
|
||||
@ -494,8 +399,6 @@ TEST_CASE("App trace test (1 task + 1 crashed timer ISR @ 1 core)", "[trace][ign
|
||||
memset(s_test_timers, 0, sizeof(s_test_timers));
|
||||
memset(s_test_tasks, 0, sizeof(s_test_tasks));
|
||||
|
||||
s_test_timers[0].group = TIMER_GROUP_0;
|
||||
s_test_timers[0].id = TIMER_0;
|
||||
s_test_timers[0].isr_func = esp_apptrace_test_timer_isr_crash;
|
||||
s_test_timers[0].data.buf = s_bufs[0];
|
||||
s_test_timers[0].data.buf_sz = sizeof(s_bufs[0]);
|
||||
@ -548,15 +451,11 @@ TEST_CASE("App trace test (2 tasks + 1 timer @ each core", "[trace][ignore]")
|
||||
memset(s_test_tasks, 0, sizeof(s_test_tasks));
|
||||
memset(s_test_timers, 0, sizeof(s_test_timers));
|
||||
|
||||
s_test_timers[0].group = TIMER_GROUP_0;
|
||||
s_test_timers[0].id = TIMER_0;
|
||||
s_test_timers[0].isr_func = esp_apptrace_test_timer_isr;
|
||||
s_test_timers[0].data.buf = s_bufs[0];
|
||||
s_test_timers[0].data.buf_sz = sizeof(s_bufs[0]);
|
||||
s_test_timers[0].data.period = 150;
|
||||
|
||||
s_test_timers[1].group = TIMER_GROUP_1;
|
||||
s_test_timers[1].id = TIMER_0;
|
||||
s_test_timers[1].isr_func = esp_apptrace_test_timer_isr;
|
||||
s_test_timers[1].data.buf = s_bufs[1];
|
||||
s_test_timers[1].data.buf_sz = sizeof(s_bufs[1]);
|
||||
@ -612,8 +511,6 @@ TEST_CASE("App trace test (1 task + 1 timer @ 1 core)", "[trace][ignore]")
|
||||
memset(s_test_timers, 0, sizeof(s_test_timers));
|
||||
memset(s_test_tasks, 0, sizeof(s_test_tasks));
|
||||
|
||||
s_test_timers[0].group = TIMER_GROUP_0;
|
||||
s_test_timers[0].id = TIMER_0;
|
||||
s_test_timers[0].isr_func = esp_apptrace_test_timer_isr;
|
||||
s_test_timers[0].data.buf = s_bufs[0];
|
||||
s_test_timers[0].data.buf_sz = sizeof(s_bufs[0]);
|
||||
@ -792,11 +689,11 @@ TEST_CASE("Log trace test (2 tasks)", "[trace][ignore]")
|
||||
vSemaphoreDelete(arg2.done);
|
||||
}
|
||||
|
||||
#else
|
||||
#else // #if CONFIG_APPTRACE_SV_ENABLE == 0
|
||||
|
||||
typedef struct {
|
||||
int group;
|
||||
int timer;
|
||||
gptimer_handle_t gptimer;
|
||||
uint32_t period;
|
||||
int flags;
|
||||
uint32_t id;
|
||||
} esp_sysviewtrace_timer_arg_t;
|
||||
@ -810,50 +707,46 @@ typedef struct {
|
||||
uint32_t id;
|
||||
} esp_sysviewtrace_task_arg_t;
|
||||
|
||||
static void esp_sysview_test_timer_isr(void *arg)
|
||||
static bool esp_sysview_test_timer_isr(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
|
||||
{
|
||||
esp_sysviewtrace_timer_arg_t *tim_arg = (esp_sysviewtrace_timer_arg_t *)arg;
|
||||
|
||||
//ESP_APPTRACE_TEST_LOGI("tim-%d: IRQ %d/%d\n", tim_arg->id, tim_arg->group, tim_arg->timer);
|
||||
|
||||
timer_group_clr_intr_status_in_isr(tim_arg->group, tim_arg->id);
|
||||
timer_group_enable_alarm_in_isr(tim_arg->group, tim_arg->id);
|
||||
esp_sysviewtrace_timer_arg_t *tim_arg = (esp_sysviewtrace_timer_arg_t *)user_ctx;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void esp_sysviewtrace_test_task(void *p)
|
||||
{
|
||||
esp_sysviewtrace_task_arg_t *arg = (esp_sysviewtrace_task_arg_t *) p;
|
||||
volatile uint32_t tmp = 0;
|
||||
timer_isr_handle_t inth;
|
||||
|
||||
printf("%x: run sysview task\n", (uint32_t)xTaskGetCurrentTaskHandle());
|
||||
|
||||
if (arg->timer) {
|
||||
esp_err_t res = timer_isr_register(arg->timer->group, arg->timer->timer, esp_sysview_test_timer_isr, arg->timer, arg->timer->flags, &inth);
|
||||
if (res != ESP_OK) {
|
||||
printf("%x: failed to register timer ISR\n", (uint32_t)xTaskGetCurrentTaskHandle());
|
||||
}
|
||||
else {
|
||||
res = timer_start(arg->timer->group, arg->timer->timer);
|
||||
if (res != ESP_OK) {
|
||||
printf("%x: failed to start timer\n", (uint32_t)xTaskGetCurrentTaskHandle());
|
||||
}
|
||||
}
|
||||
gptimer_alarm_config_t alarm_config = {
|
||||
.reload_count = 0,
|
||||
.alarm_count = arg->timer->period,
|
||||
.flags.auto_reload_on_alarm = true,
|
||||
};
|
||||
gptimer_event_callbacks_t cbs = {
|
||||
.on_alarm = esp_sysview_test_timer_isr,
|
||||
};
|
||||
TEST_ESP_OK(gptimer_register_event_callbacks(arg->timer->gptimer, &cbs, arg->timer));
|
||||
TEST_ESP_OK(gptimer_set_alarm_action(arg->timer->gptimer, &alarm_config));
|
||||
TEST_ESP_OK(gptimer_start(arg->timer->gptimer));
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
while (1) {
|
||||
static uint32_t count;
|
||||
printf("%d", arg->id);
|
||||
if((++count % 80) == 0)
|
||||
if ((++count % 80) == 0) {
|
||||
printf("\n");
|
||||
}
|
||||
if (arg->sync) {
|
||||
xSemaphoreTake(*arg->sync, portMAX_DELAY);
|
||||
}
|
||||
for (uint32_t k = 0; k < arg->work_count; k++) {
|
||||
tmp++;
|
||||
}
|
||||
vTaskDelay(arg->sleep_tmo/portTICK_PERIOD_MS);
|
||||
vTaskDelay(arg->sleep_tmo / portTICK_PERIOD_MS);
|
||||
i++;
|
||||
if (arg->sync) {
|
||||
xSemaphoreGive(*arg->sync);
|
||||
@ -871,10 +764,9 @@ TEST_CASE("SysView trace test 1", "[trace][ignore]")
|
||||
TaskHandle_t thnd;
|
||||
|
||||
esp_sysviewtrace_timer_arg_t tim_arg1 = {
|
||||
.group = TIMER_GROUP_1,
|
||||
.timer = TIMER_1,
|
||||
.flags = ESP_INTR_FLAG_SHARED,
|
||||
.id = 0,
|
||||
.period = 500,
|
||||
};
|
||||
esp_sysviewtrace_task_arg_t arg1 = {
|
||||
.done = xSemaphoreCreateBinary(),
|
||||
@ -885,10 +777,9 @@ TEST_CASE("SysView trace test 1", "[trace][ignore]")
|
||||
.id = 0,
|
||||
};
|
||||
esp_sysviewtrace_timer_arg_t tim_arg2 = {
|
||||
.group = TIMER_GROUP_1,
|
||||
.timer = TIMER_0,
|
||||
.flags = 0,
|
||||
.id = 1,
|
||||
.period = 100,
|
||||
};
|
||||
esp_sysviewtrace_task_arg_t arg2 = {
|
||||
.done = xSemaphoreCreateBinary(),
|
||||
@ -899,8 +790,15 @@ TEST_CASE("SysView trace test 1", "[trace][ignore]")
|
||||
.id = 1,
|
||||
};
|
||||
|
||||
esp_apptrace_test_timer_init(TIMER_GROUP_1, TIMER_1, 500);
|
||||
esp_apptrace_test_timer_init(TIMER_GROUP_1, TIMER_0, 100);
|
||||
gptimer_config_t timer_config = {
|
||||
.clk_src = GPTIMER_CLK_SRC_APB,
|
||||
.direction = GPTIMER_COUNT_UP,
|
||||
.resolution_hz = 1000000,
|
||||
};
|
||||
timer_config.flags.intr_shared = (tim_arg1.flags & ESP_INTR_FLAG_SHARED) == ESP_INTR_FLAG_SHARED;
|
||||
TEST_ESP_OK(gptimer_new_timer(&timer_config, &tim_arg1.gptimer));
|
||||
timer_config.flags.intr_shared = (tim_arg2.flags & ESP_INTR_FLAG_SHARED) == ESP_INTR_FLAG_SHARED;
|
||||
TEST_ESP_OK(gptimer_new_timer(&timer_config, &tim_arg2.gptimer));
|
||||
|
||||
xTaskCreatePinnedToCore(esp_sysviewtrace_test_task, "svtrace0", 2048, &arg1, 3, &thnd, 0);
|
||||
ESP_APPTRACE_TEST_LOGI("Created task %x", thnd);
|
||||
@ -915,6 +813,10 @@ TEST_CASE("SysView trace test 1", "[trace][ignore]")
|
||||
vSemaphoreDelete(arg1.done);
|
||||
xSemaphoreTake(arg2.done, portMAX_DELAY);
|
||||
vSemaphoreDelete(arg2.done);
|
||||
TEST_ESP_OK(gptimer_stop(tim_arg1.gptimer));
|
||||
TEST_ESP_OK(gptimer_del_timer(tim_arg1.gptimer));
|
||||
TEST_ESP_OK(gptimer_stop(tim_arg2.gptimer));
|
||||
TEST_ESP_OK(gptimer_del_timer(tim_arg2.gptimer));
|
||||
}
|
||||
|
||||
TEST_CASE("SysView trace test 2", "[trace][ignore]")
|
||||
@ -922,10 +824,9 @@ TEST_CASE("SysView trace test 2", "[trace][ignore]")
|
||||
TaskHandle_t thnd;
|
||||
|
||||
esp_sysviewtrace_timer_arg_t tim_arg1 = {
|
||||
.group = TIMER_GROUP_1,
|
||||
.timer = TIMER_1,
|
||||
.flags = ESP_INTR_FLAG_SHARED,
|
||||
.id = 0,
|
||||
.period = 500,
|
||||
};
|
||||
esp_sysviewtrace_task_arg_t arg1 = {
|
||||
.done = xSemaphoreCreateBinary(),
|
||||
@ -936,10 +837,9 @@ TEST_CASE("SysView trace test 2", "[trace][ignore]")
|
||||
.id = 0,
|
||||
};
|
||||
esp_sysviewtrace_timer_arg_t tim_arg2 = {
|
||||
.group = TIMER_GROUP_1,
|
||||
.timer = TIMER_0,
|
||||
.flags = 0,
|
||||
.id = 1,
|
||||
.period = 100,
|
||||
};
|
||||
esp_sysviewtrace_task_arg_t arg2 = {
|
||||
.done = xSemaphoreCreateBinary(),
|
||||
@ -969,8 +869,15 @@ TEST_CASE("SysView trace test 2", "[trace][ignore]")
|
||||
.id = 3,
|
||||
};
|
||||
|
||||
esp_apptrace_test_timer_init(TIMER_GROUP_1, TIMER_1, 500);
|
||||
esp_apptrace_test_timer_init(TIMER_GROUP_1, TIMER_0, 100);
|
||||
gptimer_config_t timer_config = {
|
||||
.clk_src = GPTIMER_CLK_SRC_APB,
|
||||
.direction = GPTIMER_COUNT_UP,
|
||||
.resolution_hz = 1000000,
|
||||
};
|
||||
timer_config.flags.intr_shared = (tim_arg1.flags & ESP_INTR_FLAG_SHARED) == ESP_INTR_FLAG_SHARED;
|
||||
TEST_ESP_OK(gptimer_new_timer(&timer_config, &tim_arg1.gptimer));
|
||||
timer_config.flags.intr_shared = (tim_arg2.flags & ESP_INTR_FLAG_SHARED) == ESP_INTR_FLAG_SHARED;
|
||||
TEST_ESP_OK(gptimer_new_timer(&timer_config, &tim_arg2.gptimer));
|
||||
|
||||
xTaskCreatePinnedToCore(esp_sysviewtrace_test_task, "svtrace0", 2048, &arg1, 3, &thnd, 0);
|
||||
printf("Created task %x\n", (uint32_t)thnd);
|
||||
@ -999,6 +906,10 @@ TEST_CASE("SysView trace test 2", "[trace][ignore]")
|
||||
xSemaphoreTake(arg4.done, portMAX_DELAY);
|
||||
vSemaphoreDelete(arg4.done);
|
||||
vSemaphoreDelete(test_sync);
|
||||
TEST_ESP_OK(gptimer_stop(tim_arg1.gptimer));
|
||||
TEST_ESP_OK(gptimer_del_timer(tim_arg1.gptimer));
|
||||
TEST_ESP_OK(gptimer_stop(tim_arg2.gptimer));
|
||||
TEST_ESP_OK(gptimer_del_timer(tim_arg2.gptimer));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif // #if CONFIG_APPTRACE_SV_ENABLE == 0
|
||||
#endif // #if CONFIG_APPTRACE_ENABLE == 1
|
||||
|
@ -13,19 +13,10 @@
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/timer.h"
|
||||
|
||||
#include "driver/gptimer.h"
|
||||
|
||||
static const char *TAG = "example";
|
||||
|
||||
typedef struct {
|
||||
int group;
|
||||
int timer;
|
||||
int count;
|
||||
TaskHandle_t thnd;
|
||||
} example_event_data_t;
|
||||
|
||||
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
#if !CONFIG_USE_CUSTOM_EVENT_ID
|
||||
|
||||
@ -72,7 +63,7 @@ static void example_sysview_event_send(uint32_t id, uint32_t val)
|
||||
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, s_example_sysview_module.EventOffset + id);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // !CONFIG_USE_CUSTOM_EVENT_ID
|
||||
|
||||
#else
|
||||
|
||||
@ -81,36 +72,20 @@ static void example_sysview_event_send(uint32_t id, uint32_t val)
|
||||
#define SYSVIEW_EXAMPLE_WAIT_EVENT_START()
|
||||
#define SYSVIEW_EXAMPLE_WAIT_EVENT_END(_val_)
|
||||
|
||||
#endif
|
||||
#endif // CONFIG_APPTRACE_SV_ENABLE
|
||||
|
||||
typedef struct {
|
||||
gptimer_handle_t gptimer;
|
||||
int count;
|
||||
TaskHandle_t thnd;
|
||||
uint64_t period;
|
||||
char task_name[32];
|
||||
} example_event_data_t;
|
||||
|
||||
static void example_timer_init(int timer_group, int timer_idx, uint32_t period)
|
||||
static bool example_timer_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
|
||||
{
|
||||
uint64_t alarm_val = (period * (TIMER_BASE_CLK / 1000000UL)) / 2;
|
||||
|
||||
timer_config_t config = {
|
||||
.alarm_en = 1,
|
||||
.auto_reload = 1,
|
||||
.counter_dir = TIMER_COUNT_UP,
|
||||
.divider = 2, //Range is 2 to 65536
|
||||
.intr_type = TIMER_INTR_LEVEL,
|
||||
.counter_en = TIMER_PAUSE,
|
||||
};
|
||||
/*Configure timer*/
|
||||
timer_init(timer_group, timer_idx, &config);
|
||||
/*Stop timer counter*/
|
||||
timer_pause(timer_group, timer_idx);
|
||||
/*Load counter value */
|
||||
timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL);
|
||||
/*Set alarm value*/
|
||||
timer_set_alarm_value(timer_group, timer_idx, alarm_val);
|
||||
/*Enable timer interrupt*/
|
||||
timer_enable_intr(timer_group, timer_idx);
|
||||
}
|
||||
|
||||
static void example_timer_isr(void *arg)
|
||||
{
|
||||
example_event_data_t *tim_arg = (example_event_data_t *)arg;
|
||||
example_event_data_t *tim_arg = (example_event_data_t *)user_ctx;
|
||||
bool need_yield = false;
|
||||
|
||||
if (tim_arg->thnd != NULL) {
|
||||
if (tim_arg->count++ < 10) {
|
||||
@ -121,35 +96,32 @@ static void example_timer_isr(void *arg)
|
||||
} else {
|
||||
SYSVIEW_EXAMPLE_SEND_EVENT_END(tim_arg->count);
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR();
|
||||
need_yield = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// re-start timer
|
||||
timer_group_clr_intr_status_in_isr(tim_arg->group, tim_arg->timer);
|
||||
timer_group_enable_alarm_in_isr(tim_arg->group, tim_arg->timer);
|
||||
return need_yield;
|
||||
}
|
||||
|
||||
static void example_task(void *p)
|
||||
{
|
||||
example_event_data_t *arg = (example_event_data_t *) p;
|
||||
timer_isr_handle_t inth;
|
||||
|
||||
ESP_LOGI(TAG, "%p: run task", xTaskGetCurrentTaskHandle());
|
||||
|
||||
esp_err_t res = timer_isr_register(arg->group, arg->timer, example_timer_isr, arg, 0, &inth);
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(TAG, "%p: failed to register timer ISR", xTaskGetCurrentTaskHandle());
|
||||
} else {
|
||||
res = timer_start(arg->group, arg->timer);
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(TAG, "%p: failed to start timer", xTaskGetCurrentTaskHandle());
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
uint32_t event_val;
|
||||
example_event_data_t *arg = (example_event_data_t *) p;
|
||||
ESP_LOGI(TAG, "%p: run task", xTaskGetCurrentTaskHandle());
|
||||
gptimer_alarm_config_t alarm_config = {
|
||||
.reload_count = 0,
|
||||
.alarm_count = arg->period,
|
||||
.flags.auto_reload_on_alarm = true,
|
||||
};
|
||||
// This task is pinned to a specific core, to the interrupt will also be install to that core
|
||||
gptimer_event_callbacks_t cbs = {
|
||||
.on_alarm = example_timer_alarm_cb,
|
||||
};
|
||||
ESP_ERROR_CHECK(gptimer_register_event_callbacks(arg->gptimer, &cbs, arg));
|
||||
ESP_ERROR_CHECK(gptimer_set_alarm_action(arg->gptimer, &alarm_config));
|
||||
ESP_ERROR_CHECK(gptimer_start(arg->gptimer));
|
||||
while (1) {
|
||||
SYSVIEW_EXAMPLE_WAIT_EVENT_START();
|
||||
xTaskNotifyWait(0, 0, &event_val, portMAX_DELAY);
|
||||
SYSVIEW_EXAMPLE_WAIT_EVENT_END(event_val);
|
||||
@ -159,18 +131,7 @@ static void example_task(void *p)
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
static example_event_data_t event_data[portNUM_PROCESSORS] = {
|
||||
{
|
||||
.group = TIMER_GROUP_1,
|
||||
.timer = TIMER_0,
|
||||
},
|
||||
#if CONFIG_FREERTOS_UNICORE == 0
|
||||
{
|
||||
.group = TIMER_GROUP_0,
|
||||
.timer = TIMER_0,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
static example_event_data_t event_data[portNUM_PROCESSORS];
|
||||
|
||||
#if CONFIG_APPTRACE_SV_ENABLE && CONFIG_USE_CUSTOM_EVENT_ID
|
||||
// Currently OpenOCD does not support requesting module info from target. So do the following...
|
||||
@ -183,22 +144,19 @@ void app_main(void)
|
||||
SEGGER_SYSVIEW_RegisterModule(&s_example_sysview_module);
|
||||
#endif
|
||||
|
||||
#if !CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_10
|
||||
example_timer_init(TIMER_GROUP_1, TIMER_0, 2000);
|
||||
#else
|
||||
#warning "Timer (Group 1, Timer 0) is used by sysview module itself!"
|
||||
#endif
|
||||
for (int i = 0; i < portNUM_PROCESSORS; i++) {
|
||||
gptimer_config_t timer_config = {
|
||||
.clk_src = GPTIMER_CLK_SRC_APB,
|
||||
.direction = GPTIMER_COUNT_UP,
|
||||
.resolution_hz = 1000000,
|
||||
};
|
||||
ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &event_data[i].gptimer));
|
||||
event_data[i].period = 1000000 * (i + 1);
|
||||
}
|
||||
|
||||
#if !CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00
|
||||
example_timer_init(TIMER_GROUP_0, TIMER_0, 4000);
|
||||
#else
|
||||
#warning "Timer (Group 0, Timer 0) is used by sysview module itself!"
|
||||
#endif
|
||||
|
||||
xTaskCreatePinnedToCore(example_task, "svtrace0", 2048, &event_data[0], 3, &event_data[0].thnd, 0);
|
||||
ESP_LOGI(TAG, "Created task %p", event_data[0].thnd);
|
||||
#if CONFIG_FREERTOS_UNICORE == 0
|
||||
xTaskCreatePinnedToCore(example_task, "svtrace1", 2048, &event_data[1], 3, &event_data[1].thnd, 1);
|
||||
ESP_LOGI(TAG, "Created task %p", event_data[1].thnd);
|
||||
#endif
|
||||
for (int i = 0; i < portNUM_PROCESSORS; i++) {
|
||||
sprintf(event_data->task_name, "svtrace%d", i);
|
||||
xTaskCreatePinnedToCore(example_task, event_data->task_name, 4096, &event_data[i], 3, &event_data[i].thnd, i);
|
||||
ESP_LOGI(TAG, "Created task %p", event_data[i].thnd);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ CONFIG_APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE=y
|
||||
CONFIG_APPTRACE_ENABLE=y
|
||||
# Enable FreeRTOS SystemView Tracing by default
|
||||
CONFIG_APPTRACE_SV_ENABLE=y
|
||||
CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00=y
|
||||
CONFIG_APPTRACE_SV_TS_SOURCE_GPTIMER=y
|
||||
CONFIG_APPTRACE_SV_EVT_OVERFLOW_ENABLE=y
|
||||
CONFIG_APPTRACE_SV_EVT_ISR_ENTER_ENABLE=y
|
||||
CONFIG_APPTRACE_SV_EVT_ISR_EXIT_ENABLE=y
|
||||
|
Loading…
Reference in New Issue
Block a user