Files
esp-idf/components/freertos/test_apps/freertos/port/test_hwlp.c

95 lines
3.0 KiB
C

/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include <string.h>
#include "soc/soc_caps.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "unity.h"
/**
* On RISC-V targets that have coprocessors, the contexts are saved at the lowest address of the stack,
* which can lead to wrong stack watermark calculation in FreeRTOS in theory.
* As such, the port layer of FreeRTOS will adjust the lowest address of the stack when a coprocessor
* context is saved.
*/
#if SOC_CPU_HAS_HWLOOP
uint32_t use_hwlp(uint32_t count);
TEST_CASE("HWLP: Context save does not affect stack watermark", "[freertos]")
{
/* Force the FreeRTOS port layer to store a HWLP context in the current task.
* So let's use the it and make sure another task, on the SAME CORE, also uses it */
const TaskHandle_t current_handle = xTaskGetCurrentTaskHandle();
/* Get the current stack watermark */
const UBaseType_t before_watermark = uxTaskGetStackHighWaterMark(current_handle);
/* Use the HWLP unit, the context will NOT be flushed until a context switch is done */
use_hwlp(20);
/* Make sure FreeRTOS switches to another task, even Idle task, so that the current Task saves
* the HWLP current context */
vTaskDelay(10);
const UBaseType_t after_watermark = uxTaskGetStackHighWaterMark(current_handle);
TEST_ASSERT_TRUE(after_watermark > before_watermark / 2);
}
#if CONFIG_FREERTOS_NUMBER_OF_CORES > 1
typedef struct {
uint32_t count;
TaskHandle_t main;
} hwlp_params_t;
static void calculation(void* arg)
{
hwlp_params_t* p = (hwlp_params_t*) arg;
const uint32_t count = p->count;
uint32_t result = 0;
int i = 0;
for (i = 0; i < 50000; i++) {
uint32_t current = use_hwlp(count);
result += current;
/* Using TEST_ASSERT_TRUE triggers a stack overflow, make sure the count is still correct.
* The function `use_hwlp` should return (count * 16) */
assert(count * 16 == current);
}
/* Make sure the result is correct */
assert(count * 16 * i == result);
xTaskNotifyGive(p->main);
vTaskDelete(NULL);
}
TEST_CASE("HWLP: Unsolicited context switch between tasks using HWLP", "[freertos]")
{
/* Create two tasks that are on the same core and use the same FPU */
TaskHandle_t unity_task_handle = xTaskGetCurrentTaskHandle();
TaskHandle_t tasks[2];
hwlp_params_t params[2] = {
{ .count = 1024, .main = unity_task_handle },
{ .count = 2048, .main = unity_task_handle },
};
xTaskCreatePinnedToCore(calculation, "Task1", 2048, params + 0, CONFIG_UNITY_FREERTOS_PRIORITY + 1, &tasks[0], 1);
xTaskCreatePinnedToCore(calculation, "Task2", 2048, params + 1, CONFIG_UNITY_FREERTOS_PRIORITY + 1, &tasks[1], 1);
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
}
#endif /* CONFIG_FREERTOS_NUMBER_OF_CORES > 1 */
#endif // SOC_CPU_HAS_HWLOOP