1 /*
2  * Test FreeRTOS trace facility functions. These following functions are enabled
3  * when configUSE_TRACE_FACILITY is defined 1 in FreeRTOS.
4  * Tasks:           uxTaskGetTaskNumber(), uxTaskSetTaskNumber()
5  * Queues:          ucQueueGetQueueType(), vQueueSetQueueNumber(), uxQueueGetQueueNumber()
6  * Event Groups:    xEventGroupSetBitsFromISR(), xEventGroupClearBitsFromISR(), uxEventGroupGetNumber()
7  *
8  * Note: uxTaskGetSystemState() is tested in a separate unit test
9  */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include "freertos/FreeRTOS.h"
14 #include "freertos/task.h"
15 #include "freertos/semphr.h"
16 #include "freertos/event_groups.h"
17 #include "unity.h"
18 #include "test_utils.h"
19 
20 #ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY
21 #define TSK_PRIORITY    (UNITY_FREERTOS_PRIORITY + 1)
22 
23 #define NO_OF_CORES portNUM_PROCESSORS
24 #define BIN_SEM_QUEUE_TYPE queueQUEUE_TYPE_BINARY_SEMAPHORE     //Expected Queue Type
25 
26 static QueueHandle_t test_queues[NO_OF_CORES];
27 static TaskHandle_t task_handles[NO_OF_CORES];
28 
task_test_trace_utilities(void * arg)29 void task_test_trace_utilities(void *arg)
30 {
31     int core = xPortGetCoreID();
32     TaskHandle_t handle = xTaskGetCurrentTaskHandle();
33     uint32_t id = (uint32_t)arg;
34 
35     vTaskSetTaskNumber(handle, (UBaseType_t)id);    //cast and store id as task number
36     vQueueSetQueueNumber(test_queues[core], id);    //store id as queue number
37 
38     //Wait to start
39     xSemaphoreTake(test_queues[core], portMAX_DELAY);
40 
41     //Tests on this core
42     TEST_ASSERT(uxTaskGetTaskNumber(task_handles[core]) == (0x0F << (core)));
43     TEST_ASSERT(uxQueueGetQueueNumber(test_queues[core]) == (0x0F << (core)));
44     TEST_ASSERT(ucQueueGetQueueType(test_queues[core]) == BIN_SEM_QUEUE_TYPE)
45 
46     //Test on other core
47 #ifndef CONFIG_FREERTOS_UNICORE
48     TEST_ASSERT(uxTaskGetTaskNumber(task_handles[!core]) == (0x0F << (!core)));
49     TEST_ASSERT(uxQueueGetQueueNumber(test_queues[!core]) == (0x0F << (!core)));
50     TEST_ASSERT(ucQueueGetQueueType(test_queues[!core]) == BIN_SEM_QUEUE_TYPE)
51 #endif
52 
53     xSemaphoreGive(test_queues[core]);      //Signal done
54     vTaskDelete(NULL);
55 }
56 
57 TEST_CASE("Test freertos trace facility functions", "[freertos]")
58 {
59     for(int i = 0; i < NO_OF_CORES; i++){
60         test_queues[i] = xSemaphoreCreateBinary();   //Create a queue as binary semaphore for each core
61         xTaskCreatePinnedToCore(task_test_trace_utilities, "Test Task", 4096, (void *)(0x0F << i), TSK_PRIORITY, &task_handles[i], i);
62     }
63 
64     vTaskDelay(10);
65 
66     //Start the tasks
67     for(int i = NO_OF_CORES - 1; i >= 0; i--){
68         xSemaphoreGive(test_queues[i]);
69     }
70 
71     vTaskDelay(10); //Small delay to ensure semaphores are taken
72 
73     //Wait for done
74     for(int i = 0; i < NO_OF_CORES; i++){
75         xSemaphoreTake(test_queues[i], portMAX_DELAY);
76         vSemaphoreDelete(test_queues[i]);
77     }
78 
79     vTaskDelay(10);     //Give time for idle task to clean up
80 }
81 
82 
83 #define MAX_TASKS           15
84 #define TASKS_TO_CREATE     5
85 
86 static TaskHandle_t created_handles[TASKS_TO_CREATE];
87 static TaskStatus_t *tsk_status_array;
88 
created_task(void * arg)89 void created_task(void* arg)
90 {
91     while(1){
92         vTaskDelay(100);
93     }
94 }
95 
96 TEST_CASE("Test freertos uxTaskGetSystemState", "[freertos]")
97 {
98     tsk_status_array = calloc(MAX_TASKS, sizeof(TaskStatus_t));
99     for(int i = 0; i < TASKS_TO_CREATE; i++){
100         xTaskCreatePinnedToCore(created_task, "Created Task", 1024, NULL, TSK_PRIORITY, &created_handles[i], 0);
101     }
102 
103     //Get System states
104     int no_of_tasks = uxTaskGetSystemState(tsk_status_array, MAX_TASKS, NULL);
105     TEST_ASSERT((no_of_tasks > 0) && (no_of_tasks <= MAX_TASKS));
106 
107     //Check if get system state has got all created tasks
108     bool not_found = false;
109     for(int i = 0; i < TASKS_TO_CREATE; i++){
110         bool found = false;
111         for(int j = 0; j < MAX_TASKS; j++){
112             if(tsk_status_array[j].xHandle == created_handles[i]){
113                 found = true;
114                 break;
115             }
116         }
117         if(!found){
118             not_found = true;
119             break;
120         }
121     }
122     TEST_ASSERT(not_found == false);
123 
124     //Cleanup
125     for(int i = 0; i < TASKS_TO_CREATE; i++){
126         vTaskDelete(created_handles[i]);
127     }
128     free(tsk_status_array);
129     vTaskDelay(10);
130 }
131 
132 #endif //CONFIG_FREERTOS_USE_TRACE_FACILITY
133