diff --git a/components/esp_wifi/test/test_wifi_init.c b/components/esp_wifi/test/test_wifi_init.c index 8195f9c8d..9932551af 100644 --- a/components/esp_wifi/test/test_wifi_init.c +++ b/components/esp_wifi/test/test_wifi_init.c @@ -96,24 +96,27 @@ static void wifi_driver_can_start_on_APP_CPU_task(void* arg) TEST_ESP_OK(event_deinit()); ESP_LOGI(TAG, EMPH_STR("nvs_flash_deinit...")); TEST_ESP_OK(nvs_flash_deinit()); - xSemaphoreGive(*sema); ESP_LOGI(TAG, "exit task..."); - vTaskDelete(NULL); + xSemaphoreGive(*sema); + vTaskSuspend(NULL); } TEST_CASE("wifi driver can start on APP CPU", "[wifi_init]") { - TaskHandle_t th; + TaskHandle_t th = NULL; SemaphoreHandle_t sema = xSemaphoreCreateBinary(); + TEST_ASSERT_NOT_NULL(sema); printf("Creating tasks\n"); #ifndef CONFIG_FREERTOS_UNICORE xTaskCreatePinnedToCore(wifi_driver_can_start_on_APP_CPU_task, "wifi_driver_can_start_on_APP_CPU_task", 2048*2, &sema, 3, &th, 1); #else xTaskCreate(wifi_driver_can_start_on_APP_CPU_task, "wifi_driver_can_start_on_APP_CPU_task", 2048*2, &sema, 3, &th); #endif + TEST_ASSERT_NOT_NULL(th); xSemaphoreTake(sema, portMAX_DELAY); vSemaphoreDelete(sema); sema = NULL; + test_utils_task_delete(th); } static void wifi_start_stop_task(void* arg) @@ -148,22 +151,25 @@ static void wifi_start_stop_task(void* arg) nvs_flash_deinit(); ESP_LOGI(TAG, "test passed..."); xSemaphoreGive(*sema); - vTaskDelete(NULL); + vTaskSuspend(NULL); } TEST_CASE("Calling esp_wifi_stop() with start", "[wifi_init]") { - TaskHandle_t th; + TaskHandle_t th = NULL; SemaphoreHandle_t sema = xSemaphoreCreateBinary(); + TEST_ASSERT_NOT_NULL(sema); printf("Creating tasks\n"); #ifndef CONFIG_FREERTOS_UNICORE xTaskCreatePinnedToCore(wifi_start_stop_task, "wifi_start_stop_task", 2048*2, &sema, 3, &th, 0); #else xTaskCreate(wifi_start_stop_task, "wifi_start_stop_task", 2048*2, &sema, 3, &th); #endif + TEST_ASSERT_NOT_NULL(th); xSemaphoreTake(sema, portMAX_DELAY); vSemaphoreDelete(sema); sema = NULL; + test_utils_task_delete(th); } static void wifi_stop_task(void* arg) @@ -194,20 +200,23 @@ static void wifi_stop_task(void* arg) nvs_flash_deinit(); ESP_LOGI(TAG, "test passed..."); xSemaphoreGive(*sema); - vTaskDelete(NULL); + vTaskSuspend(NULL); } TEST_CASE("Calling esp_wifi_stop() without start", "[wifi_init]") { - TaskHandle_t th; + TaskHandle_t th = NULL; SemaphoreHandle_t sema = xSemaphoreCreateBinary(); + TEST_ASSERT_NOT_NULL(sema); printf("Creating tasks\n"); #ifndef CONFIG_FREERTOS_UNICORE xTaskCreatePinnedToCore(wifi_stop_task, "wifi_stop_task", 2048*2, &sema, 3, &th, 0); #else xTaskCreate(wifi_stop_task, "wifi_stop_task", 2048*2, &sema, 3, &th); #endif + TEST_ASSERT_NOT_NULL(th); xSemaphoreTake(sema, portMAX_DELAY); vSemaphoreDelete(sema); sema = NULL; + test_utils_task_delete(th); } diff --git a/tools/unit-test-app/components/test_utils/include/test_utils.h b/tools/unit-test-app/components/test_utils/include/test_utils.h index d2d7f0538..aa809972c 100644 --- a/tools/unit-test-app/components/test_utils/include/test_utils.h +++ b/tools/unit-test-app/components/test_utils/include/test_utils.h @@ -18,6 +18,8 @@ #include #include #include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" /* include performance pass standards header file */ #include "idf_performance.h" @@ -259,7 +261,6 @@ esp_err_t test_utils_set_leak_level(size_t leak_level, esp_type_leak_t type, esp size_t test_utils_get_leak_level(esp_type_leak_t type, esp_comp_leak_t component); - typedef struct test_utils_exhaust_memory_record_s *test_utils_exhaust_memory_rec; /** @@ -285,3 +286,9 @@ test_utils_exhaust_memory_rec test_utils_exhaust_memory(uint32_t caps, size_t li void test_utils_free_exhausted_memory(test_utils_exhaust_memory_rec rec); +/** + * @brief Delete task ensuring dynamic memory (for stack, tcb etc.) gets freed up immediately + * + * @param[in] thandle Handle of task to be deleted (should not be NULL or self handle) + */ +void test_utils_task_delete(TaskHandle_t thandle); diff --git a/tools/unit-test-app/components/test_utils/test_utils.c b/tools/unit-test-app/components/test_utils/test_utils.c index 7745f19c0..0bbce43fa 100644 --- a/tools/unit-test-app/components/test_utils/test_utils.c +++ b/tools/unit-test-app/components/test_utils/test_utils.c @@ -19,6 +19,11 @@ #include "freertos/task.h" #include "esp_netif.h" #include "lwip/sockets.h" +#include "sdkconfig.h" +#if !CONFIG_FREERTOS_UNICORE +#include "esp_ipc.h" +#include "esp_freertos_hooks.h" +#endif const esp_partition_t *get_test_data_partition(void) { @@ -142,7 +147,6 @@ size_t test_utils_get_leak_level(esp_type_leak_t type_of_leak, esp_comp_leak_t c return leak_level; } - #define EXHAUST_MEMORY_ENTRIES 100 struct test_utils_exhaust_memory_record_s { @@ -179,3 +183,56 @@ void test_utils_free_exhausted_memory(test_utils_exhaust_memory_rec rec) free(rec); } +#if !CONFIG_FREERTOS_UNICORE +static SemaphoreHandle_t test_sem; + +static bool test_idle_hook_func(void) +{ + if (test_sem) { + xSemaphoreGive(test_sem); + } + return true; +} + +static void test_task_delete_func(void *arg) +{ + vTaskDelete(arg); +} +#endif // !CONFIG_FREERTOS_UNICORE + +void test_utils_task_delete(TaskHandle_t thandle) +{ + /* Self deletion can not free up associated task dynamic memory immediately, + * hence not recommended for test scenarios */ + TEST_ASSERT_NOT_NULL_MESSAGE(thandle, "test_utils_task_delete: handle is NULL"); + TEST_ASSERT_NOT_EQUAL_MESSAGE(thandle, xTaskGetCurrentTaskHandle(), "test_utils_task_delete: handle is of currently executing task"); + +#if CONFIG_FREERTOS_UNICORE + vTaskDelete(thandle); +#else // CONFIG_FREERTOS_UNICORE + const BaseType_t tsk_affinity = xTaskGetAffinity(thandle); + const uint32_t core_id = xPortGetCoreID(); + + printf("Task_affinity: 0x%x, current_core: %d\n", tsk_affinity, core_id); + + if (tsk_affinity == tskNO_AFFINITY) { + /* For no affinity case, we wait for idle hook to trigger on different core */ + esp_err_t ret = esp_register_freertos_idle_hook_for_cpu(test_idle_hook_func, !core_id); + TEST_ASSERT_EQUAL_MESSAGE(ret, ESP_OK, "test_utils_task_delete: failed to register idle hook"); + vTaskDelete(thandle); + test_sem = xSemaphoreCreateBinary(); + TEST_ASSERT_NOT_NULL_MESSAGE(test_sem, "test_utils_task_delete: failed to create semaphore"); + xSemaphoreTake(test_sem, portMAX_DELAY); + esp_deregister_freertos_idle_hook_for_cpu(test_idle_hook_func, !core_id); + vSemaphoreDelete(test_sem); + test_sem = NULL; + } else if (tsk_affinity != core_id) { + /* Task affinity and current core are differnt, schedule IPC call (to delete task) + * on core where task is pinned to */ + esp_ipc_call_blocking(tsk_affinity, test_task_delete_func, thandle); + } else { + /* Task affinity and current core are same, so we can safely proceed for deletion */ + vTaskDelete(thandle); + } +#endif // !CONFIG_FREERTOS_UNICORE +}