feat(afe):add cpu loading test.

This commit is contained in:
xiewei 2023-07-21 11:54:56 +08:00
parent 61cb36e92c
commit e02b976769
4 changed files with 280 additions and 6 deletions

View File

@ -25,6 +25,8 @@ IGNORE_WARNINGS = [
r'pkg_resources is deprecated as an API',
r'the value \'y\' is invalid for SOC_PCNT_GROUPS',
r'\'1\' is not a valid value for the bool symbol SOC_PCNT_GROUPS',
r'\'task_stack\' defined but not used',
r'\'task_state\' defined but not used',
]
def _get_idf_version():

View File

@ -12,5 +12,5 @@ idf_component_register(SRCS ${srcs}
REQUIRES unity esp-sr
WHOLE_ARCHIVE)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
endif()

View File

@ -20,10 +20,32 @@
#include "dl_lib_convq_queue.h"
#include <sys/time.h>
#define ARRAY_SIZE_OFFSET 8 // Increase this if audio_sys_get_real_time_stats returns ESP_ERR_INVALID_SIZE
#define AUDIO_SYS_TASKS_ELAPSED_TIME_MS 1000 // Period of stats measurement
static const char *TAG = "AFE_TEST";
static volatile int s_cpu_test_task_flag = 0;
static esp_afe_sr_data_t *afe_data = NULL;
static int total_ram_size_before = 0;
static int internal_ram_size_before = 0;
static int psram_size_before = 0;
TEST_CASE("audio_front_end SR create/destroy API & memory leak", "[afe]")
const static char *task_state[] = {
"Running",
"Ready",
"Blocked",
"Suspended",
"Deleted"
};
/** @brief
* "Extr": Allocated task stack from psram, "Intr": Allocated task stack from internel
*/
const static char *task_stack[] = {"Extr", "Intr"};
TEST_CASE(">>>>>>>> audio_front_end SR create/destroy API & memory leak <<<<<<<<", "[afe]")
{
int audio_chunksize = 0;
int16_t *feed_buff = NULL;
@ -107,13 +129,224 @@ TEST_CASE("audio_front_end SR create/destroy API & memory leak", "[afe]")
}
}
void test_feed_Task(void *arg)
{
int sample_per_ms = 16;
// esp_afe_sr_iface_t *afe_handle = &ESP_AFE_SR_HANDLE;
esp_afe_sr_iface_t *afe_handle = (esp_afe_sr_iface_t *)arg;
int feed_chunksize = afe_handle->get_feed_chunksize(afe_data);
int total_nch = afe_handle->get_total_channel_num(afe_data);
int16_t *i2s_buff = malloc(feed_chunksize * sizeof(int16_t) * total_nch);
assert(i2s_buff);
ESP_LOGI(TAG, "feed task start\n");
// FILE *fp = fopen("/sdcard/out", "w");
// if (fp == NULL) printf("can not open file\n");
while (s_cpu_test_task_flag) {
// FatfsComboWrite(i2s_buff, audio_chunksize * I2S_CHANNEL_NUM * sizeof(int16_t), 1, fp);
afe_handle->feed(afe_data, i2s_buff);
vTaskDelay((feed_chunksize / sample_per_ms) / portTICK_PERIOD_MS);
}
if (i2s_buff) {
free(i2s_buff);
}
ESP_LOGI(TAG, "feed task quit\n");
vTaskDelete(NULL);
}
void test_detect_Task(void *arg)
{
// esp_afe_sr_iface_t *afe_handle = &ESP_AFE_SR_HANDLE;
esp_afe_sr_iface_t *afe_handle = (esp_afe_sr_iface_t *)arg;
int fetch_chunksize = afe_handle->get_fetch_chunksize(afe_data);
int16_t *buff = malloc(fetch_chunksize * sizeof(int16_t));
assert(buff);
ESP_LOGI(TAG, "------------detect start------------\n");
// FILE *fp = fopen("/sdcard/out1", "w");
// if (fp == NULL) printf("can not open file\n");
while (s_cpu_test_task_flag) {
afe_fetch_result_t* res = afe_handle->fetch(afe_data);
if (!res || res->ret_value == ESP_FAIL) {
printf("fetch error!\n");
break;
}
if (res->wakeup_state == WAKENET_DETECTED) {
ESP_LOGI(TAG, "wakeword detected\n");
}
if (res->wakeup_state == WAKENET_CHANNEL_VERIFIED) {
ESP_LOGI(TAG, "AFE_FETCH_CHANNEL_VERIFIED\n");
}
}
if (buff) {
free(buff);
}
ESP_LOGI(TAG, "detect task quit\n");
vTaskDelete(NULL);
}
esp_err_t audio_sys_get_real_time_stats(void)
{
#if (CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID && CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS)
TaskStatus_t *start_array = NULL, *end_array = NULL;
UBaseType_t start_array_size, end_array_size;
uint32_t start_run_time, end_run_time;
uint32_t task_elapsed_time, percentage_time;
esp_err_t ret;
// Allocate array to store current task states
start_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET;
start_array = malloc(sizeof(TaskStatus_t) * start_array_size);
assert(start_array);
// Get current task states
start_array_size = uxTaskGetSystemState(start_array, start_array_size, &start_run_time);
if (start_array_size == 0) {
ESP_LOGE(TAG, "Insufficient array size for uxTaskGetSystemState. Trying increasing ARRAY_SIZE_OFFSET");
ret = ESP_FAIL;
goto exit;
}
vTaskDelay(pdMS_TO_TICKS(AUDIO_SYS_TASKS_ELAPSED_TIME_MS));
// Allocate array to store tasks states post delay
end_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET;
end_array = malloc(sizeof(TaskStatus_t) * end_array_size);
assert(end_array);
// Get post delay task states
end_array_size = uxTaskGetSystemState(end_array, end_array_size, &end_run_time);
if (end_array_size == 0) {
ESP_LOGE(TAG, "Insufficient array size for uxTaskGetSystemState. Trying increasing ARRAY_SIZE_OFFSET");
ret = ESP_FAIL;
goto exit;
}
// Calculate total_elapsed_time in units of run time stats clock period.
uint32_t total_elapsed_time = (end_run_time - start_run_time);
if (total_elapsed_time == 0) {
ESP_LOGE(TAG, "Delay duration too short. Trying increasing AUDIO_SYS_TASKS_ELAPSED_TIME_MS");
ret = ESP_FAIL;
goto exit;
}
ESP_LOGI(TAG, "| Task | Run Time | Per | Prio | HWM | State | CoreId | Stack ");
// Match each task in start_array to those in the end_array
for (int i = 0; i < start_array_size; i++) {
for (int j = 0; j < end_array_size; j++) {
if (start_array[i].xHandle == end_array[j].xHandle) {
task_elapsed_time = end_array[j].ulRunTimeCounter - start_array[i].ulRunTimeCounter;
percentage_time = (task_elapsed_time * 100UL) / (total_elapsed_time * portNUM_PROCESSORS);
ESP_LOGI(TAG, "| %-17s | %-11d |%2d%% | %-4u | %-9u | %-7s | %-8x | %s",
start_array[i].pcTaskName, task_elapsed_time, percentage_time, start_array[i].uxCurrentPriority,
start_array[i].usStackHighWaterMark, task_state[(start_array[i].eCurrentState)],
start_array[i].xCoreID, task_stack[esp_ptr_internal(pxTaskGetStackStart(start_array[i].xHandle))]);
// Mark that task have been matched by overwriting their handles
start_array[i].xHandle = NULL;
end_array[j].xHandle = NULL;
break;
}
}
}
// Print unmatched tasks
for (int i = 0; i < start_array_size; i++) {
if (start_array[i].xHandle != NULL) {
ESP_LOGI(TAG, "| %s | Deleted", start_array[i].pcTaskName);
}
}
for (int i = 0; i < end_array_size; i++) {
if (end_array[i].xHandle != NULL) {
ESP_LOGI(TAG, "| %s | Created", end_array[i].pcTaskName);
}
}
printf("\n");
ret = ESP_OK;
exit: // Common return path
if (start_array) {
free(start_array);
start_array = NULL;
}
if (end_array) {
free(end_array);
end_array = NULL;
}
return ret;
#else
ESP_LOGW(TAG, "Please enbale `CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID` and `CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS` in menuconfig");
return ESP_FAIL;
#endif
}
void test_print_cpuloading(void *arg)
{
while (s_cpu_test_task_flag) {
audio_sys_get_real_time_stats();
int total_ram_size_after = heap_caps_get_free_size(MALLOC_CAP_8BIT);
int internal_ram_size_after = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
int psram_size_after = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
ESP_LOGI(TAG, "total ram consume: %d KB", (total_ram_size_before - total_ram_size_after)/1024);
ESP_LOGI(TAG, "internal ram consume: %d KB", (internal_ram_size_before - internal_ram_size_after)/1024);
ESP_LOGI(TAG, "psram consume: %d KB\n\n", (psram_size_before - psram_size_after)/1024);
}
vTaskDelete(NULL);
}
TEST_CASE(">>>>>>>> audio_front_end SR cpu loading and memory info <<<<<<<<", "[afe]")
{
srmodel_list_t *models = esp_srmodel_init("model");
if (models!=NULL) {
for (int i=0; i < models->num; i++) {
printf("Load: %s\n", models->model_name[i]);
}
}
char *wn_name = esp_srmodel_filter(models, ESP_WN_PREFIX, NULL);
printf("wn_name: %s\n", wn_name);
total_ram_size_before = heap_caps_get_free_size(MALLOC_CAP_8BIT);
internal_ram_size_before = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
psram_size_before = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
esp_afe_sr_iface_t *afe_handle = (esp_afe_sr_iface_t *)&ESP_AFE_SR_HANDLE;
afe_config_t afe_config = AFE_CONFIG_DEFAULT();
afe_config.wakenet_model_name = wn_name;
afe_data = afe_handle->create_from_config(&afe_config);
if (!afe_data) {
printf("afe_data is null!\n");
return;
}
s_cpu_test_task_flag = 1;
xTaskCreatePinnedToCore(&test_feed_Task, "feed", 8 * 1024, (void *)afe_handle, 5, NULL, 0);
xTaskCreatePinnedToCore(&test_detect_Task, "detect", 8 * 1024, (void *)afe_handle, 5, NULL, 1);
xTaskCreatePinnedToCore(&test_print_cpuloading, "cpuloading", 4 * 1024, NULL, 5, NULL, 1);
vTaskDelay(10000 / portTICK_PERIOD_MS);
s_cpu_test_task_flag = 0;
vTaskDelay(2000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "destroy\n");
afe_handle->destroy(afe_data);
afe_data = NULL;
esp_srmodel_deinit(models);
ESP_LOGI(TAG, "successful\n");
}
/******************************************** Divide VC Test ********************************************/
TEST_CASE("audio_front_end VC create/destroy API & memory leak", "[afe]")
TEST_CASE(">>>>>>>> audio_front_end VC create/destroy API & memory leak <<<<<<<<", "[afe]")
{
int start_total_mem_size = 0;
int start_internal_mem_size = 0;
@ -183,4 +416,37 @@ TEST_CASE("audio_front_end VC create/destroy API & memory leak", "[afe]")
}
}
}
}
}
TEST_CASE(">>>>>>>> audio_front_end VC cpu loading and memory info <<<<<<<<", "[afe]")
{
total_ram_size_before = heap_caps_get_free_size(MALLOC_CAP_8BIT);
internal_ram_size_before = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
psram_size_before = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
esp_afe_sr_iface_t *afe_handle = (esp_afe_sr_iface_t *)&ESP_AFE_VC_HANDLE;
afe_config_t afe_config = AFE_CONFIG_DEFAULT();
afe_config.wakenet_init = false;
afe_config.voice_communication_init = true;
afe_config.voice_communication_agc_init = true;
afe_data = afe_handle->create_from_config(&afe_config);
if (!afe_data) {
printf("afe_data is null!\n");
return;
}
s_cpu_test_task_flag = 1;
xTaskCreatePinnedToCore(&test_feed_Task, "feed", 8 * 1024, (void *)afe_handle, 5, NULL, 0);
xTaskCreatePinnedToCore(&test_detect_Task, "detect", 8 * 1024, (void *)afe_handle, 5, NULL, 1);
xTaskCreatePinnedToCore(&test_print_cpuloading, "cpuloading", 4 * 1024, NULL, 5, NULL, 1);
vTaskDelay(20000 / portTICK_PERIOD_MS);
s_cpu_test_task_flag = 0;
vTaskDelay(2000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "destroy\n");
afe_handle->destroy(afe_data);
afe_data = NULL;
ESP_LOGI(TAG, "successful\n");
}

View File

@ -401,6 +401,8 @@ CONFIG_ESP_ROM_HAS_ETS_PRINTF_BUG=y
CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y
CONFIG_ESP_ROM_NEEDS_SET_CACHE_MMU_SIZE=y
CONFIG_ESP_ROM_RAM_APP_NEEDS_MMU_INIT=y
CONFIG_ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG=y
CONFIG_ESP_ROM_HAS_CACHE_SUSPEND_WAITI_BUG=y
#
# Boot ROM Behavior
@ -1171,8 +1173,10 @@ CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048
CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10
CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1
# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set
# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y
CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
# end of Kernel
#
@ -1189,6 +1193,7 @@ CONFIG_FREERTOS_TICK_SUPPORT_SYSTIMER=y
CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL1=y
# CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL3 is not set
CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y
CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER=y
# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set
# CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH is not set
# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set
@ -1744,6 +1749,7 @@ CONFIG_VFS_SUPPORT_DIR=y
CONFIG_VFS_SUPPORT_SELECT=y
CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y
CONFIG_VFS_SUPPORT_TERMIOS=y
CONFIG_VFS_MAX_COUNT=8
#
# Host File System I/O (Semihosting)