mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
49256fe5c9
- Add a new test case for SMP FreeRTOS - Old test case is preserved. To be removed in the future
165 lines
5.5 KiB
C
165 lines
5.5 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include "sdkconfig.h"
|
|
|
|
#if CONFIG_FREERTOS_SMP
|
|
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "unity.h"
|
|
#include "test_utils.h"
|
|
|
|
/*
|
|
Test TLSP Deletion Callbacks
|
|
|
|
Purpose:
|
|
- Test that TLSP Deletion Callbacks can be registered
|
|
- Test that TLSP Deletion Callbacks are called when a task is deleted
|
|
|
|
Procedure:
|
|
- Create a task on each core along with an array of integers to act as TLSP data
|
|
- Each task should initialize their integers to a particular value (i.e., the index value)
|
|
- Each task should register those integers as TLSPs along with a deletion callback
|
|
- Each task should self delete to trigger the TLSP deletion callback
|
|
- The TLSP deletion callback should indicate that it has run by negating the integer values
|
|
|
|
Expected:
|
|
- The TLSP deletion callback should check that the correct TLSP is provided by checking the TLSPs initialization
|
|
value (i.e., should be set to the index value)
|
|
- After deletion, the integer values should be negated to indicate deletion callback execution
|
|
*/
|
|
|
|
#define NUM_TLSP CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS
|
|
|
|
static void tlsp_del_cb(int index, void *tlsp)
|
|
{
|
|
int *val = (int *)tlsp;
|
|
|
|
// Check that the TLSP's initialization value is correct
|
|
TEST_ASSERT_EQUAL(index, *val);
|
|
// Set the TLSP's value again to a negative value to indicate that the del cb has ran
|
|
*val = -*val;
|
|
}
|
|
|
|
static void tlsp_task(void *arg)
|
|
{
|
|
int *tlsps = (int *)arg;
|
|
|
|
for (int index = 0; index < NUM_TLSP; index++) {
|
|
// Initialize the TLSPs to a positive value
|
|
tlsps[index] = index;
|
|
// Set TLSPs and deletion callbacks
|
|
vTaskSetThreadLocalStoragePointerAndDelCallback(NULL, index, &tlsps[index], tlsp_del_cb);
|
|
}
|
|
|
|
// Self delete to trigger TLSP del cb
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
TEST_CASE("Test TLSP deletion callbacks", "[freertos]")
|
|
{
|
|
TaskHandle_t tasks[portNUM_PROCESSORS];
|
|
int tlsps[portNUM_PROCESSORS][NUM_TLSP];
|
|
|
|
for (int i = 0; i < portNUM_PROCESSORS; i++) {
|
|
TEST_ASSERT_EQUAL(pdPASS, xTaskCreatePinnedToCore(tlsp_task, "tlsp_tsk", configMINIMAL_STACK_SIZE * 2, (void *)&tlsps[i], UNITY_FREERTOS_PRIORITY - 1, &tasks[i], i));
|
|
}
|
|
// Significant delay to let tasks run and delete themselves
|
|
vTaskDelay(pdMS_TO_TICKS(100));
|
|
|
|
// Check the values of the TLSPs to see if the del cb have ran
|
|
for (int i = 0; i < portNUM_PROCESSORS; i++) {
|
|
for (int index = 0; index < NUM_TLSP; index++) {
|
|
// Del cb should have set the TLSP to a negative value
|
|
TEST_ASSERT_EQUAL(-index, tlsps[i][index]);
|
|
}
|
|
}
|
|
}
|
|
|
|
#else // CONFIG_FREERTOS_SMP
|
|
|
|
// Todo: Remove IDF FreeRTOS Test Case
|
|
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/semphr.h"
|
|
#include "unity.h"
|
|
#include "test_utils.h"
|
|
|
|
/* --------Test backported thread local storage pointer and deletion cb feature----------
|
|
* vTaskSetThreadLocalStoragePointerAndDelCallback()
|
|
* pvTaskGetThreadLocalStoragePointer(),
|
|
*
|
|
* This test creates a task and set's the task's TLSPs. The task is then deleted
|
|
* which should trigger the deletion cb.
|
|
*/
|
|
|
|
#define NO_OF_TLSP configNUM_THREAD_LOCAL_STORAGE_POINTERS
|
|
#define TLSP_SET_BASE 0x0F //0b1111 to be bit shifted by index
|
|
#define TLSP_DEL_BASE 0x05 //0b0101 to be bit shifted by index
|
|
|
|
//The variables pointed to by Thread Local Storage Pointer
|
|
static uint32_t task_storage[portNUM_PROCESSORS][NO_OF_TLSP] = {0};
|
|
|
|
/* If static task cleanup is defined, can't set index 0 even if the calling task is not a pthread,
|
|
as the cleanup is called for every task.
|
|
*/
|
|
#if defined(CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP)
|
|
static const int skip_index = 0; /*PTHREAD_TLS_INDEX*/
|
|
#else
|
|
static const int skip_index = -1;
|
|
#endif
|
|
|
|
static void del_cb(int index, void *ptr)
|
|
{
|
|
*((uint32_t *)ptr) = (TLSP_DEL_BASE << index); //Indicate deletion by setting task storage element to a unique value
|
|
}
|
|
|
|
static void task_cb(void *arg)
|
|
{
|
|
int core = xPortGetCoreID();
|
|
for(int i = 0; i < NO_OF_TLSP; i++){
|
|
if (i == skip_index) {
|
|
continue;
|
|
}
|
|
|
|
task_storage[core][i] = (TLSP_SET_BASE << i); //Give each element of task_storage a unique number
|
|
vTaskSetThreadLocalStoragePointerAndDelCallback(NULL, i, (void *)&task_storage[core][i], del_cb); //Set each TLSP to point to a task storage element
|
|
}
|
|
|
|
for(int i = 0; i < NO_OF_TLSP; i++){
|
|
if (i == skip_index) {
|
|
continue;
|
|
}
|
|
|
|
uint32_t * tlsp = (uint32_t *)pvTaskGetThreadLocalStoragePointer(NULL, i);
|
|
TEST_ASSERT_EQUAL(*tlsp, (TLSP_SET_BASE << i)); //Check if TLSP points to the correct task storage element by checking unique value
|
|
}
|
|
|
|
vTaskDelete(NULL); //Delete Task to Trigger TSLP deletion callback
|
|
}
|
|
|
|
TEST_CASE("Test FreeRTOS thread local storage pointers and del cb", "[freertos]")
|
|
{
|
|
//Create Task
|
|
for(int core = 0; core < portNUM_PROCESSORS; core++){
|
|
xTaskCreatePinnedToCore(task_cb, "task", 1024, NULL, UNITY_FREERTOS_PRIORITY+1, NULL, core);
|
|
}
|
|
vTaskDelay(10); //Delay long enough for tasks to run to completion
|
|
|
|
for(int core = 0; core < portNUM_PROCESSORS; core++){
|
|
for(int i = 0; i < NO_OF_TLSP; i++){
|
|
if (i == skip_index) {
|
|
continue;
|
|
}
|
|
TEST_ASSERT_EQUAL((TLSP_DEL_BASE << i), task_storage[core][i]); //Check del_cb ran by checking task storage for unique value
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif // CONFIG_FREERTOS_SMP
|