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