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
#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
{
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? */
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 );
TaskStatus_t *pxTaskStatusArray;
volatile UBaseType_t uxArraySize, x;
char cStatus;
- UNTESTED_FUNCTION();
/*
* PLEASE NOTE:
#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)
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
--- /dev/null
+/*
+ * 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
+
+++ /dev/null
-/*
- 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
\ No newline at end of file
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