mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-04 21:24:32 +02:00
freertos: Update task snapshot unit tests
This commit updates the task snapshot unit tests as follows: - Both uxTaskGetSnapshotAll() and vTaskGetSnapshot() are now both tested - Test cases are now dependent on CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
idf_component_register(SRC_DIRS .
|
||||
PRIV_INCLUDE_DIRS .
|
||||
PRIV_REQUIRES cmock test_utils esp_system driver)
|
||||
# Enable task snapshots by setting configENABLE_TASK_SNAPSHOT macro
|
||||
idf_build_set_property(COMPILE_OPTIONS "-DconfigENABLE_TASK_SNAPSHOT=1" APPEND)
|
||||
|
@@ -1,38 +1,151 @@
|
||||
/*
|
||||
Test FreeRTOS support for core dump.
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT
|
||||
#include <stdio.h>
|
||||
#include "esp_cpu.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/task_snapshot.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#define TEST_MAX_TASKS_NUM 32
|
||||
#define NUM_TASKS_PER_LIST 2
|
||||
#define TASK_PRIORITY (configMAX_PRIORITIES - 2)
|
||||
|
||||
/* simple test to check that in normal conditions uxTaskGetSnapshotAll does not generate exception */
|
||||
TEST_CASE("Tasks snapshot", "[freertos]")
|
||||
static void ready_task(void *arg)
|
||||
{
|
||||
TaskSnapshot_t tasks[TEST_MAX_TASKS_NUM];
|
||||
UBaseType_t tcb_sz;
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
int other_core_id = xPortGetCoreID() == 0 ? 1 : 0;
|
||||
#endif
|
||||
|
||||
// uxTaskGetSnapshotAll is supposed to be called when all tasks on both CPUs are
|
||||
// inactive and can not alter FreeRTOS internal tasks lists, e.g. from panic handler
|
||||
unsigned state = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
esp_cpu_stall(other_core_id);
|
||||
#endif
|
||||
UBaseType_t task_num = uxTaskGetSnapshotAll(tasks, TEST_MAX_TASKS_NUM, &tcb_sz);
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
esp_cpu_unstall(other_core_id);
|
||||
#endif
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR(state);
|
||||
|
||||
printf("Dumped %d tasks. TCB size %d\n", task_num, tcb_sz);
|
||||
TEST_ASSERT_NOT_EQUAL(0, task_num);
|
||||
TEST_ASSERT_NOT_EQUAL(0, tcb_sz);
|
||||
while (1) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static void blocked_task(void *arg)
|
||||
{
|
||||
// Delay for portMAX_DELAY - 1 as not to go on the suspended list
|
||||
vTaskDelay(portMAX_DELAY - 1);
|
||||
}
|
||||
|
||||
static void suspended_task(void *arg)
|
||||
{
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
|
||||
static void setup(TaskHandle_t *task_list, int *num_tasks_ret, UBaseType_t *old_priority_ret)
|
||||
{
|
||||
// Raise our priority so that we aren't preempted
|
||||
*old_priority_ret = uxTaskPriorityGet(NULL);
|
||||
vTaskPrioritySet(NULL, configMAX_PRIORITIES - 1);
|
||||
|
||||
// Create tasks
|
||||
int num_tasks = 0;
|
||||
for (int i = 0; i < NUM_TASKS_PER_LIST; i++) {
|
||||
//Ready task
|
||||
xTaskCreate(ready_task, "ready", 1024, NULL, TASK_PRIORITY, &(task_list[num_tasks]));
|
||||
num_tasks++;
|
||||
//Blocked task
|
||||
xTaskCreate(blocked_task, "blkd", 1024, NULL, TASK_PRIORITY, &(task_list[num_tasks]));
|
||||
num_tasks++;
|
||||
//Suspended task
|
||||
xTaskCreate(suspended_task, "susp", 1024, NULL, TASK_PRIORITY, &(task_list[num_tasks]));
|
||||
num_tasks++;
|
||||
}
|
||||
*num_tasks_ret = num_tasks;
|
||||
// Short delay to allow tasks to spin up
|
||||
vTaskDelay(10);
|
||||
|
||||
// Stop preemption on this core, and stall the other core
|
||||
taskDISABLE_INTERRUPTS();
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
esp_cpu_stall(!xPortGetCoreID());
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void check_snapshots(TaskHandle_t *task_list, int num_tasks, TaskSnapshot_t *task_snapshots, UBaseType_t num_snapshots)
|
||||
{
|
||||
// Check task snapshots. Every created task should be found in the task snapshot
|
||||
for (int i = 0; i < num_tasks; i++) {
|
||||
bool found = false;
|
||||
for (int j = 0; j < num_snapshots; j++) {
|
||||
if (task_list[i] == (TaskHandle_t)task_snapshots[j].pxTCB) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TEST_ASSERT(found);
|
||||
}
|
||||
}
|
||||
|
||||
static void teardown(TaskHandle_t *task_list, int num_tasks, UBaseType_t old_priority)
|
||||
{
|
||||
// Resume other cores and allow preemption
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
esp_cpu_unstall(!xPortGetCoreID());
|
||||
#endif
|
||||
taskENABLE_INTERRUPTS();
|
||||
|
||||
for (int i = 0; i < num_tasks; i++) {
|
||||
vTaskDelete(task_list[i]);
|
||||
}
|
||||
// Restore priority
|
||||
vTaskPrioritySet(NULL, old_priority);
|
||||
// Short delay to allow tasks to clean up
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
TEST_CASE("Task snapshot: Get all", "[freertos]")
|
||||
{
|
||||
// Short delay to allow both cores to spin up
|
||||
vTaskDelay(10);
|
||||
|
||||
TaskHandle_t task_list[TEST_MAX_TASKS_NUM];
|
||||
int num_tasks;
|
||||
UBaseType_t old_priority;
|
||||
setup(task_list, &num_tasks, &old_priority);
|
||||
|
||||
// Get task snapshots using uxTaskGetSnapshotAll()
|
||||
TaskSnapshot_t task_snapshots[TEST_MAX_TASKS_NUM];
|
||||
UBaseType_t tcb_size;
|
||||
UBaseType_t num_snapshots;
|
||||
num_snapshots = uxTaskGetSnapshotAll(task_snapshots, TEST_MAX_TASKS_NUM, &tcb_size);
|
||||
TEST_ASSERT_LESS_OR_EQUAL(TEST_MAX_TASKS_NUM, num_snapshots);
|
||||
|
||||
check_snapshots(task_list, num_tasks, task_snapshots, num_snapshots);
|
||||
teardown(task_list, num_tasks, old_priority);
|
||||
}
|
||||
|
||||
TEST_CASE("Task snapshot: Iterate", "[freertos]")
|
||||
{
|
||||
// Short delay to allow both cores to spin up
|
||||
vTaskDelay(10);
|
||||
|
||||
TaskHandle_t task_list[TEST_MAX_TASKS_NUM];
|
||||
int num_tasks;
|
||||
UBaseType_t old_priority;
|
||||
setup(task_list, &num_tasks, &old_priority);
|
||||
|
||||
// Get task snapshots using pxTaskGetNext() and vTaskGetSnapshot()
|
||||
TaskSnapshot_t task_snapshots[TEST_MAX_TASKS_NUM];
|
||||
UBaseType_t num_snapshots = 0;
|
||||
TaskHandle_t cur_task_handle = pxTaskGetNext(NULL);
|
||||
while (cur_task_handle != NULL) {
|
||||
// Get the task's snapshot
|
||||
vTaskGetSnapshot(cur_task_handle, &task_snapshots[num_snapshots]);
|
||||
num_snapshots++;
|
||||
cur_task_handle = pxTaskGetNext(cur_task_handle);
|
||||
}
|
||||
TEST_ASSERT_LESS_OR_EQUAL(TEST_MAX_TASKS_NUM, num_snapshots);
|
||||
|
||||
check_snapshots(task_list, num_tasks, task_snapshots, num_snapshots);
|
||||
teardown(task_list, num_tasks, old_priority);
|
||||
}
|
||||
|
||||
#endif // CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT
|
||||
|
@@ -20,3 +20,4 @@ CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
|
||||
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
|
||||
CONFIG_FREERTOS_FPU_IN_ISR=y
|
||||
CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=16
|
||||
CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y
|
||||
|
Reference in New Issue
Block a user