]> granicus.if.org Git - esp-idf/commitdiff
freertos/make trace facility configurable
authorDarian Leung <darian@espressif.com>
Thu, 28 Sep 2017 04:33:53 +0000 (12:33 +0800)
committerDarian Leung <darian@espressif.com>
Fri, 20 Oct 2017 07:17:17 +0000 (15:17 +0800)
This commit makes configUSE_TRACE_FACILITY and
configUSE_STATS_FORMATTING_FUNCTIONS configurable in kconfig. Test cases fro the
functions enabled by the two configurations above have also been added.

Test cases for the following functions have been added...

- uxTaskGetSystemState()
- uxTaskGetTaskNumber()
- vTaskSetTaskNumber()

- xEventGroupClearBitsFromISR()
- xEventGroupSetBitsFromISR()
- uxEventGroupGetNumber()

- uxQueueGetQueueNumber()
- vQueueSetQueueNumber()
- ucQueueGetQueueType()

Test cases for the following functions were not required...

- prvListTaskWithinSingleList()
- prvWriteNameToBuffer()
- vTaskList()

components/freertos/Kconfig
components/freertos/include/freertos/FreeRTOSConfig.h
components/freertos/tasks.c
components/freertos/test/test_freertos_eventgroups.c
components/freertos/test/test_freertos_trace_utilities.c [new file with mode: 0644]
components/freertos/test/test_uxGetSystemState_Bugfix.c [deleted file]
tools/unit-test-app/sdkconfig.defaults

index 44541a54a9af6ab75926238faf7f92407e24e22e..e56cb1a01b53bed2ba82b84c615ece58c9f9fb94 100644 (file)
@@ -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
index 3ccd3fda695f3032a24f44185caad6ae005545f4..e38c1426d44a24bdce3597afbedac48c24ec2511 100644 (file)
 #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
index 24373a91eac0e259a8100e287484b34cabbc4b4f..f6931c40176c1473054f38c88bc8689d1743ffc4 100644 (file)
@@ -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:
index 8d5a5fb326b1c97785fd6cdea80131dce4c79453..2b79060f4f913a3d155ac8962343696fe6c2a6f3 100644 (file)
@@ -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
diff --git a/components/freertos/test/test_freertos_trace_utilities.c b/components/freertos/test/test_freertos_trace_utilities.c
new file mode 100644 (file)
index 0000000..da01b8a
--- /dev/null
@@ -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
+
diff --git a/components/freertos/test/test_uxGetSystemState_Bugfix.c b/components/freertos/test/test_uxGetSystemState_Bugfix.c
deleted file mode 100644 (file)
index e7e447f..0000000
+++ /dev/null
@@ -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
\ No newline at end of file
index 00f2a865fb1d11bb4625b9c05e3a2cfda3ec929e..5875356e6c53ee6bf5a5a3ce5d0a7437f75cb4c9 100644 (file)
@@ -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