mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/FreeRTOS_Trace_Facilities' into 'master'
feature/make freertos trace facility configurable See merge request !1420
This commit is contained in:
commit
22756b6c02
@ -275,6 +275,23 @@ config TIMER_QUEUE_LENGTH
|
||||
|
||||
For most uses the default value of 10 is OK.
|
||||
|
||||
config FREERTOS_USE_TRACE_FACILITY
|
||||
bool "Enable FreeRTOS trace facility"
|
||||
default n
|
||||
help
|
||||
If enabled, configUSE_TRACE_FACILITY will be defined as 1 in FreeRTOS.
|
||||
This will allow the usage of trace facility functions such as
|
||||
uxTaskGetSystemState().
|
||||
|
||||
config FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
|
||||
bool "Enable FreeRTOS stats formatting functions"
|
||||
depends on FREERTOS_USE_TRACE_FACILITY
|
||||
default n
|
||||
help
|
||||
If enabled, configUSE_STATS_FORMATTING_FUNCTIONS will be defined as 1 in
|
||||
FreeRTOS. This will allow the usage of stats formatting functions such
|
||||
as vTaskList().
|
||||
|
||||
menuconfig FREERTOS_DEBUG_INTERNALS
|
||||
bool "Debug FreeRTOS internals"
|
||||
default n
|
||||
|
@ -190,8 +190,19 @@
|
||||
#define configTOTAL_HEAP_SIZE (&_heap_end - &_heap_start)//( ( size_t ) (64 * 1024) )
|
||||
|
||||
#define configMAX_TASK_NAME_LEN ( CONFIG_FREERTOS_MAX_TASK_NAME_LEN )
|
||||
#define configUSE_TRACE_FACILITY 0 /* Used by vTaskList in main.c */
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Used by vTaskList in main.c */
|
||||
|
||||
#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY
|
||||
#define configUSE_TRACE_FACILITY 1 /* Used by uxTaskGetSystemState(), and other trace facility functions */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 1 /* Used by vTaskList() */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
|
||||
#define configGENERATE_RUN_TIME_STATS 1 /* Used by vTaskGetRunTimeStats() */
|
||||
#endif
|
||||
|
||||
#define configUSE_TRACE_FACILITY_2 0 /* Provided by Xtensa port patch */
|
||||
#define configBENCHMARK 0 /* Provided by Xtensa port patch */
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
|
@ -2292,7 +2292,6 @@ UBaseType_t uxTaskGetNumberOfTasks( void )
|
||||
{
|
||||
UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES;
|
||||
|
||||
UNTESTED_FUNCTION();
|
||||
taskENTER_CRITICAL(&xTaskQueueMutex);
|
||||
{
|
||||
/* Is there a space in the array for each task in the system? */
|
||||
@ -3678,7 +3677,6 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
|
||||
volatile TCB_t *pxNextTCB, *pxFirstTCB;
|
||||
UBaseType_t uxTask = 0;
|
||||
|
||||
UNTESTED_FUNCTION();
|
||||
if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 )
|
||||
{
|
||||
listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
|
||||
@ -4268,7 +4266,6 @@ For ESP32 FreeRTOS, vTaskExitCritical implements both portEXIT_CRITICAL and port
|
||||
TaskStatus_t *pxTaskStatusArray;
|
||||
volatile UBaseType_t uxArraySize, x;
|
||||
char cStatus;
|
||||
UNTESTED_FUNCTION();
|
||||
|
||||
/*
|
||||
* PLEASE NOTE:
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "driver/timer.h"
|
||||
#include "unity.h"
|
||||
|
||||
#define BIT_CALL (1 << 0)
|
||||
@ -117,3 +118,85 @@ TEST_CASE("FreeRTOS Event Group Sync", "[freertos]")
|
||||
vEventGroupDelete(eg);
|
||||
}
|
||||
|
||||
/*-----------------Test case for event group trace facilities-----------------*/
|
||||
#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY
|
||||
/*
|
||||
* Test event group Trace Facility functions such as
|
||||
* xEventGroupClearBitsFromISR(), xEventGroupSetBitsFromISR()
|
||||
*/
|
||||
|
||||
//Use a timer to trigger an ISr
|
||||
#define TIMER_DIVIDER 10000
|
||||
#define TIMER_COUNT 1000
|
||||
#define TIMER_NUMBER 0
|
||||
#define SET_BITS 0xAA
|
||||
#define CLEAR_BITS 0x55
|
||||
|
||||
static bool event_grp_cleared = false;
|
||||
|
||||
static void IRAM_ATTR event_group_isr()
|
||||
{
|
||||
TIMERG0.int_clr_timers.t0 = 1;
|
||||
TIMERG0.hw_timer[xPortGetCoreID()].config.alarm_en = 1;
|
||||
if(!event_grp_cleared){
|
||||
xEventGroupClearBitsFromISR(eg, CLEAR_BITS);
|
||||
event_grp_cleared = true;
|
||||
}else{
|
||||
xEventGroupSetBitsFromISR(eg, SET_BITS, NULL);
|
||||
timer_pause(TIMER_GROUP_0, TIMER_NUMBER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void test_event_group_trace_facility(void* arg)
|
||||
{
|
||||
//Setup timer for ISR
|
||||
int timer_group = TIMER_GROUP_0;
|
||||
int timer_idx = TIMER_NUMBER;
|
||||
timer_config_t config;
|
||||
config.alarm_en = 1;
|
||||
config.auto_reload = 1;
|
||||
config.counter_dir = TIMER_COUNT_UP;
|
||||
config.divider = TIMER_DIVIDER;
|
||||
config.intr_type = TIMER_INTR_LEVEL;
|
||||
config.counter_en = TIMER_PAUSE;
|
||||
timer_init(timer_group, timer_idx, &config); //Configure timer
|
||||
timer_pause(timer_group, timer_idx); //Stop timer counter
|
||||
timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL); //Load counter value
|
||||
timer_set_alarm_value(timer_group, timer_idx, TIMER_COUNT); //Set alarm value
|
||||
timer_enable_intr(timer_group, timer_idx); //Enable timer interrupt
|
||||
timer_set_auto_reload(timer_group, timer_idx, 1); //Auto Reload
|
||||
timer_isr_register(timer_group, timer_idx, event_group_isr, NULL, ESP_INTR_FLAG_IRAM, NULL); //Set ISR handler
|
||||
|
||||
//Start timer to trigger isr
|
||||
timer_start(TIMER_GROUP_0, TIMER_NUMBER);
|
||||
TEST_ASSERT(xEventGroupWaitBits(eg, SET_BITS, pdFALSE, pdTRUE, portMAX_DELAY));
|
||||
//Check clear was successful
|
||||
TEST_ASSERT((xEventGroupGetBits(eg) & CLEAR_BITS) == 0);
|
||||
|
||||
//Give semaphore to signal done
|
||||
xSemaphoreGive(done_sem);
|
||||
vTaskDelete(NULL);
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("FreeRTOS Event Group ISR", "[freertos]")
|
||||
{
|
||||
|
||||
done_sem = xSemaphoreCreateBinary();
|
||||
eg = xEventGroupCreate();
|
||||
xEventGroupSetBits(eg, CLEAR_BITS); //Set bits to be cleared by ISR
|
||||
|
||||
xTaskCreatePinnedToCore(test_event_group_trace_facility, "Testing Task", 4096, NULL, configMAX_PRIORITIES - 1, NULL, 0);
|
||||
|
||||
//Wait until task and isr have finished testing
|
||||
xSemaphoreTake(done_sem, portMAX_DELAY);
|
||||
//Clean up
|
||||
vSemaphoreDelete(done_sem);
|
||||
vEventGroupDelete(eg);
|
||||
|
||||
vTaskDelay(10); //Give time for idle task to clear up delted tasks
|
||||
|
||||
}
|
||||
|
||||
#endif //CONFIG_FREERTOS_USE_TRACE_FACILITY
|
||||
|
132
components/freertos/test/test_freertos_trace_utilities.c
Normal file
132
components/freertos/test/test_freertos_trace_utilities.c
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Test FreeRTOS trace facility functions. These following functions are enabled
|
||||
* when configUSE_TRACE_FACILITY is defined 1 in FreeRTOS.
|
||||
* Tasks: uxTaskGetTaskNumber(), uxTaskSetTaskNumber()
|
||||
* Queues: ucQueueGetQueueType(), vQueueSetQueueNumber(), uxQueueGetQueueNumber()
|
||||
* Event Groups: xEventGroupSetBitsFromISR(), xEventGroupClearBitsFromISR(), uxEventGroupGetNumber()
|
||||
*
|
||||
* Note: uxTaskGetSystemState() is tested in a separate unit test
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "unity.h"
|
||||
|
||||
#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY
|
||||
#define TSK_PRIORITY (UNITY_FREERTOS_PRIORITY + 1)
|
||||
|
||||
#define NO_OF_CORES portNUM_PROCESSORS
|
||||
#define BIN_SEM_QUEUE_TYPE queueQUEUE_TYPE_BINARY_SEMAPHORE //Expected Queue Type
|
||||
|
||||
static QueueHandle_t test_queues[NO_OF_CORES];
|
||||
static TaskHandle_t task_handles[NO_OF_CORES];
|
||||
|
||||
void task_test_trace_utilities(void *arg)
|
||||
{
|
||||
int core = xPortGetCoreID();
|
||||
TaskHandle_t handle = xTaskGetCurrentTaskHandle();
|
||||
uint32_t id = (uint32_t)arg;
|
||||
|
||||
vTaskSetTaskNumber(handle, (UBaseType_t)id); //cast and store id as task number
|
||||
vQueueSetQueueNumber(test_queues[core], id); //store id as queue number
|
||||
|
||||
//Wait to start
|
||||
xSemaphoreTake(test_queues[core], portMAX_DELAY);
|
||||
|
||||
//Tests on this core
|
||||
TEST_ASSERT(uxTaskGetTaskNumber(task_handles[core]) == (0x0F << (core)));
|
||||
TEST_ASSERT(uxQueueGetQueueNumber(test_queues[core]) == (0x0F << (core)));
|
||||
TEST_ASSERT(ucQueueGetQueueType(test_queues[core]) == BIN_SEM_QUEUE_TYPE)
|
||||
|
||||
//Test on other core
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
TEST_ASSERT(uxTaskGetTaskNumber(task_handles[!core]) == (0x0F << (!core)));
|
||||
TEST_ASSERT(uxQueueGetQueueNumber(test_queues[!core]) == (0x0F << (!core)));
|
||||
TEST_ASSERT(ucQueueGetQueueType(test_queues[!core]) == BIN_SEM_QUEUE_TYPE)
|
||||
#endif
|
||||
|
||||
xSemaphoreGive(test_queues[core]); //Signal done
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("Test freertos trace facility functions", "[freertos]")
|
||||
{
|
||||
for(int i = 0; i < NO_OF_CORES; i++){
|
||||
test_queues[i] = xSemaphoreCreateBinary(); //Create a queue as binary semaphore for each core
|
||||
xTaskCreatePinnedToCore(task_test_trace_utilities, "Test Task", 4096, (void *)(0x0F << i), TSK_PRIORITY, &task_handles[i], i);
|
||||
}
|
||||
|
||||
vTaskDelay(10);
|
||||
|
||||
//Start the tasks
|
||||
for(int i = NO_OF_CORES - 1; i >= 0; i--){
|
||||
xSemaphoreGive(test_queues[i]);
|
||||
}
|
||||
|
||||
vTaskDelay(10); //Small delay to ensure semaphores are taken
|
||||
|
||||
//Wait for done
|
||||
for(int i = 0; i < NO_OF_CORES; i++){
|
||||
xSemaphoreTake(test_queues[i], portMAX_DELAY);
|
||||
vSemaphoreDelete(test_queues[i]);
|
||||
}
|
||||
|
||||
vTaskDelay(10); //Give time for idle task to clean up
|
||||
}
|
||||
|
||||
|
||||
#define MAX_TASKS 15
|
||||
#define TASKS_TO_CREATE 5
|
||||
|
||||
static TaskHandle_t created_handles[TASKS_TO_CREATE];
|
||||
static TaskStatus_t *tsk_status_array;
|
||||
|
||||
void created_task(void* arg)
|
||||
{
|
||||
while(1){
|
||||
vTaskDelay(100);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Test freertos uxTaskGetSystemState", "[freertos]")
|
||||
{
|
||||
tsk_status_array = calloc(MAX_TASKS, sizeof(TaskStatus_t));
|
||||
for(int i = 0; i < TASKS_TO_CREATE; i++){
|
||||
xTaskCreatePinnedToCore(created_task, "Created Task", 1024, NULL, TSK_PRIORITY, &created_handles[i], 0);
|
||||
}
|
||||
|
||||
//Get System states
|
||||
int no_of_tasks = uxTaskGetSystemState(tsk_status_array, MAX_TASKS, NULL);
|
||||
TEST_ASSERT((no_of_tasks > 0) && (no_of_tasks <= MAX_TASKS));
|
||||
|
||||
//Check if get system state has got all created tasks
|
||||
bool not_found = false;
|
||||
for(int i = 0; i < TASKS_TO_CREATE; i++){
|
||||
bool found = false;
|
||||
for(int j = 0; j < MAX_TASKS; j++){
|
||||
if(tsk_status_array[j].xHandle == created_handles[i]){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found){
|
||||
not_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TEST_ASSERT(not_found == false);
|
||||
|
||||
//Cleanup
|
||||
for(int i = 0; i < TASKS_TO_CREATE; i++){
|
||||
vTaskDelete(created_handles[i]);
|
||||
}
|
||||
free(tsk_status_array);
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
#endif //CONFIG_FREERTOS_USE_TRACE_FACILITY
|
||||
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
Test Bugfix for uxTaskGetSystemState where getting system state immediately after creating
|
||||
new tasks would lead them being include twice in the TaskStatusArray. Changed suspendScheduler
|
||||
in function to taskENTER_CRITICAL
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "unity.h"
|
||||
|
||||
#define CreatedTaskDelayTicks 1
|
||||
#define NumberOfTasksToCreate 4
|
||||
#define CreatedTaskPriority 10
|
||||
#define CoreToUse 1
|
||||
|
||||
#if (configUSE_TRACE_FACILITY)
|
||||
|
||||
void TaskCallback (void* pxParam){
|
||||
int counter = 0;
|
||||
while(1){
|
||||
counter++;
|
||||
vTaskDelay(CreatedTaskDelayTicks);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("uxTaskGetSystemState Bugfix Test", "[freertos]")
|
||||
{
|
||||
TaskStatus_t *TaskStatusArray;
|
||||
TaskHandle_t *TaskHandles;
|
||||
UBaseType_t NumberOfTasks = 0;
|
||||
UBaseType_t StartingNumberOfTasks = 0;
|
||||
|
||||
//Give Time for OS to remove dport tasks
|
||||
vTaskDelay(1000);
|
||||
|
||||
//Allocate TaskStatusArray
|
||||
StartingNumberOfTasks = uxTaskGetNumberOfTasks();
|
||||
|
||||
|
||||
TaskStatusArray = pvPortMalloc((StartingNumberOfTasks+NumberOfTasksToCreate) * sizeof(TaskStatus_t));
|
||||
TaskHandles = pvPortMalloc((StartingNumberOfTasks+NumberOfTasksToCreate) * sizeof(TaskHandle_t));
|
||||
|
||||
|
||||
|
||||
//Create Tasks
|
||||
for(int i = 0; i < NumberOfTasksToCreate; i++){
|
||||
xTaskCreatePinnedToCore(&TaskCallback, "Task" , 2048, NULL, CreatedTaskPriority, (TaskHandle_t*) &TaskHandles[i], CoreToUse);
|
||||
}
|
||||
NumberOfTasks = uxTaskGetSystemState(TaskStatusArray, (StartingNumberOfTasks+NumberOfTasksToCreate), NULL);
|
||||
|
||||
//Check if any taska have been repeated in TaskStatusArray
|
||||
if(NumberOfTasks != 0){
|
||||
printf("Tasks Created, Checking for Repeated Additions \n");
|
||||
for(int i = 0; i <NumberOfTasks; i++){
|
||||
for(int j = i + 1; j< NumberOfTasks; j++){
|
||||
//Give error task handle matches another
|
||||
configASSERT(!(TaskStatusArray[i].xHandle == TaskStatusArray[j].xHandle));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
@ -11,6 +11,7 @@ CONFIG_ESP32_XTAL_FREQ_AUTO=y
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
|
||||
CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=3
|
||||
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
||||
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
|
||||
CONFIG_MBEDTLS_HARDWARE_MPI=y
|
||||
CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y
|
||||
|
Loading…
x
Reference in New Issue
Block a user