Skip to content

Commit 22756b6

Browse files
committed
Merge branch 'feature/FreeRTOS_Trace_Facilities' into 'master'
feature/make freertos trace facility configurable See merge request !1420
2 parents b6f37bd + a6854b7 commit 22756b6

File tree

7 files changed

+246
-72
lines changed

7 files changed

+246
-72
lines changed

components/freertos/Kconfig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,23 @@ config TIMER_QUEUE_LENGTH
275275

276276
For most uses the default value of 10 is OK.
277277

278+
config FREERTOS_USE_TRACE_FACILITY
279+
bool "Enable FreeRTOS trace facility"
280+
default n
281+
help
282+
If enabled, configUSE_TRACE_FACILITY will be defined as 1 in FreeRTOS.
283+
This will allow the usage of trace facility functions such as
284+
uxTaskGetSystemState().
285+
286+
config FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
287+
bool "Enable FreeRTOS stats formatting functions"
288+
depends on FREERTOS_USE_TRACE_FACILITY
289+
default n
290+
help
291+
If enabled, configUSE_STATS_FORMATTING_FUNCTIONS will be defined as 1 in
292+
FreeRTOS. This will allow the usage of stats formatting functions such
293+
as vTaskList().
294+
278295
menuconfig FREERTOS_DEBUG_INTERNALS
279296
bool "Debug FreeRTOS internals"
280297
default n

components/freertos/include/freertos/FreeRTOSConfig.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,19 @@
190190
#define configTOTAL_HEAP_SIZE (&_heap_end - &_heap_start)//( ( size_t ) (64 * 1024) )
191191

192192
#define configMAX_TASK_NAME_LEN ( CONFIG_FREERTOS_MAX_TASK_NAME_LEN )
193-
#define configUSE_TRACE_FACILITY 0 /* Used by vTaskList in main.c */
194-
#define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Used by vTaskList in main.c */
193+
194+
#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY
195+
#define configUSE_TRACE_FACILITY 1 /* Used by uxTaskGetSystemState(), and other trace facility functions */
196+
#endif
197+
198+
#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
199+
#define configUSE_STATS_FORMATTING_FUNCTIONS 1 /* Used by vTaskList() */
200+
#endif
201+
202+
#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
203+
#define configGENERATE_RUN_TIME_STATS 1 /* Used by vTaskGetRunTimeStats() */
204+
#endif
205+
195206
#define configUSE_TRACE_FACILITY_2 0 /* Provided by Xtensa port patch */
196207
#define configBENCHMARK 0 /* Provided by Xtensa port patch */
197208
#define configUSE_16_BIT_TICKS 0

components/freertos/tasks.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2292,7 +2292,6 @@ UBaseType_t uxTaskGetNumberOfTasks( void )
22922292
{
22932293
UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES;
22942294

2295-
UNTESTED_FUNCTION();
22962295
taskENTER_CRITICAL(&xTaskQueueMutex);
22972296
{
22982297
/* Is there a space in the array for each task in the system? */
@@ -3678,7 +3677,6 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
36783677
volatile TCB_t *pxNextTCB, *pxFirstTCB;
36793678
UBaseType_t uxTask = 0;
36803679

3681-
UNTESTED_FUNCTION();
36823680
if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 )
36833681
{
36843682
listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
@@ -4268,7 +4266,6 @@ For ESP32 FreeRTOS, vTaskExitCritical implements both portEXIT_CRITICAL and port
42684266
TaskStatus_t *pxTaskStatusArray;
42694267
volatile UBaseType_t uxArraySize, x;
42704268
char cStatus;
4271-
UNTESTED_FUNCTION();
42724269

42734270
/*
42744271
* PLEASE NOTE:

components/freertos/test/test_freertos_eventgroups.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "freertos/semphr.h"
66
#include "freertos/queue.h"
77
#include "freertos/event_groups.h"
8+
#include "driver/timer.h"
89
#include "unity.h"
910

1011
#define BIT_CALL (1 << 0)
@@ -117,3 +118,85 @@ TEST_CASE("FreeRTOS Event Group Sync", "[freertos]")
117118
vEventGroupDelete(eg);
118119
}
119120

121+
/*-----------------Test case for event group trace facilities-----------------*/
122+
#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY
123+
/*
124+
* Test event group Trace Facility functions such as
125+
* xEventGroupClearBitsFromISR(), xEventGroupSetBitsFromISR()
126+
*/
127+
128+
//Use a timer to trigger an ISr
129+
#define TIMER_DIVIDER 10000
130+
#define TIMER_COUNT 1000
131+
#define TIMER_NUMBER 0
132+
#define SET_BITS 0xAA
133+
#define CLEAR_BITS 0x55
134+
135+
static bool event_grp_cleared = false;
136+
137+
static void IRAM_ATTR event_group_isr()
138+
{
139+
TIMERG0.int_clr_timers.t0 = 1;
140+
TIMERG0.hw_timer[xPortGetCoreID()].config.alarm_en = 1;
141+
if(!event_grp_cleared){
142+
xEventGroupClearBitsFromISR(eg, CLEAR_BITS);
143+
event_grp_cleared = true;
144+
}else{
145+
xEventGroupSetBitsFromISR(eg, SET_BITS, NULL);
146+
timer_pause(TIMER_GROUP_0, TIMER_NUMBER);
147+
}
148+
}
149+
150+
151+
static void test_event_group_trace_facility(void* arg)
152+
{
153+
//Setup timer for ISR
154+
int timer_group = TIMER_GROUP_0;
155+
int timer_idx = TIMER_NUMBER;
156+
timer_config_t config;
157+
config.alarm_en = 1;
158+
config.auto_reload = 1;
159+
config.counter_dir = TIMER_COUNT_UP;
160+
config.divider = TIMER_DIVIDER;
161+
config.intr_type = TIMER_INTR_LEVEL;
162+
config.counter_en = TIMER_PAUSE;
163+
timer_init(timer_group, timer_idx, &config); //Configure timer
164+
timer_pause(timer_group, timer_idx); //Stop timer counter
165+
timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL); //Load counter value
166+
timer_set_alarm_value(timer_group, timer_idx, TIMER_COUNT); //Set alarm value
167+
timer_enable_intr(timer_group, timer_idx); //Enable timer interrupt
168+
timer_set_auto_reload(timer_group, timer_idx, 1); //Auto Reload
169+
timer_isr_register(timer_group, timer_idx, event_group_isr, NULL, ESP_INTR_FLAG_IRAM, NULL); //Set ISR handler
170+
171+
//Start timer to trigger isr
172+
timer_start(TIMER_GROUP_0, TIMER_NUMBER);
173+
TEST_ASSERT(xEventGroupWaitBits(eg, SET_BITS, pdFALSE, pdTRUE, portMAX_DELAY));
174+
//Check clear was successful
175+
TEST_ASSERT((xEventGroupGetBits(eg) & CLEAR_BITS) == 0);
176+
177+
//Give semaphore to signal done
178+
xSemaphoreGive(done_sem);
179+
vTaskDelete(NULL);
180+
181+
}
182+
183+
TEST_CASE("FreeRTOS Event Group ISR", "[freertos]")
184+
{
185+
186+
done_sem = xSemaphoreCreateBinary();
187+
eg = xEventGroupCreate();
188+
xEventGroupSetBits(eg, CLEAR_BITS); //Set bits to be cleared by ISR
189+
190+
xTaskCreatePinnedToCore(test_event_group_trace_facility, "Testing Task", 4096, NULL, configMAX_PRIORITIES - 1, NULL, 0);
191+
192+
//Wait until task and isr have finished testing
193+
xSemaphoreTake(done_sem, portMAX_DELAY);
194+
//Clean up
195+
vSemaphoreDelete(done_sem);
196+
vEventGroupDelete(eg);
197+
198+
vTaskDelay(10); //Give time for idle task to clear up delted tasks
199+
200+
}
201+
202+
#endif //CONFIG_FREERTOS_USE_TRACE_FACILITY
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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+
19+
#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY
20+
#define TSK_PRIORITY (UNITY_FREERTOS_PRIORITY + 1)
21+
22+
#define NO_OF_CORES portNUM_PROCESSORS
23+
#define BIN_SEM_QUEUE_TYPE queueQUEUE_TYPE_BINARY_SEMAPHORE //Expected Queue Type
24+
25+
static QueueHandle_t test_queues[NO_OF_CORES];
26+
static TaskHandle_t task_handles[NO_OF_CORES];
27+
28+
void task_test_trace_utilities(void *arg)
29+
{
30+
int core = xPortGetCoreID();
31+
TaskHandle_t handle = xTaskGetCurrentTaskHandle();
32+
uint32_t id = (uint32_t)arg;
33+
34+
vTaskSetTaskNumber(handle, (UBaseType_t)id); //cast and store id as task number
35+
vQueueSetQueueNumber(test_queues[core], id); //store id as queue number
36+
37+
//Wait to start
38+
xSemaphoreTake(test_queues[core], portMAX_DELAY);
39+
40+
//Tests on this core
41+
TEST_ASSERT(uxTaskGetTaskNumber(task_handles[core]) == (0x0F << (core)));
42+
TEST_ASSERT(uxQueueGetQueueNumber(test_queues[core]) == (0x0F << (core)));
43+
TEST_ASSERT(ucQueueGetQueueType(test_queues[core]) == BIN_SEM_QUEUE_TYPE)
44+
45+
//Test on other core
46+
#ifndef CONFIG_FREERTOS_UNICORE
47+
TEST_ASSERT(uxTaskGetTaskNumber(task_handles[!core]) == (0x0F << (!core)));
48+
TEST_ASSERT(uxQueueGetQueueNumber(test_queues[!core]) == (0x0F << (!core)));
49+
TEST_ASSERT(ucQueueGetQueueType(test_queues[!core]) == BIN_SEM_QUEUE_TYPE)
50+
#endif
51+
52+
xSemaphoreGive(test_queues[core]); //Signal done
53+
vTaskDelete(NULL);
54+
}
55+
56+
TEST_CASE("Test freertos trace facility functions", "[freertos]")
57+
{
58+
for(int i = 0; i < NO_OF_CORES; i++){
59+
test_queues[i] = xSemaphoreCreateBinary(); //Create a queue as binary semaphore for each core
60+
xTaskCreatePinnedToCore(task_test_trace_utilities, "Test Task", 4096, (void *)(0x0F << i), TSK_PRIORITY, &task_handles[i], i);
61+
}
62+
63+
vTaskDelay(10);
64+
65+
//Start the tasks
66+
for(int i = NO_OF_CORES - 1; i >= 0; i--){
67+
xSemaphoreGive(test_queues[i]);
68+
}
69+
70+
vTaskDelay(10); //Small delay to ensure semaphores are taken
71+
72+
//Wait for done
73+
for(int i = 0; i < NO_OF_CORES; i++){
74+
xSemaphoreTake(test_queues[i], portMAX_DELAY);
75+
vSemaphoreDelete(test_queues[i]);
76+
}
77+
78+
vTaskDelay(10); //Give time for idle task to clean up
79+
}
80+
81+
82+
#define MAX_TASKS 15
83+
#define TASKS_TO_CREATE 5
84+
85+
static TaskHandle_t created_handles[TASKS_TO_CREATE];
86+
static TaskStatus_t *tsk_status_array;
87+
88+
void created_task(void* arg)
89+
{
90+
while(1){
91+
vTaskDelay(100);
92+
}
93+
}
94+
95+
TEST_CASE("Test freertos uxTaskGetSystemState", "[freertos]")
96+
{
97+
tsk_status_array = calloc(MAX_TASKS, sizeof(TaskStatus_t));
98+
for(int i = 0; i < TASKS_TO_CREATE; i++){
99+
xTaskCreatePinnedToCore(created_task, "Created Task", 1024, NULL, TSK_PRIORITY, &created_handles[i], 0);
100+
}
101+
102+
//Get System states
103+
int no_of_tasks = uxTaskGetSystemState(tsk_status_array, MAX_TASKS, NULL);
104+
TEST_ASSERT((no_of_tasks > 0) && (no_of_tasks <= MAX_TASKS));
105+
106+
//Check if get system state has got all created tasks
107+
bool not_found = false;
108+
for(int i = 0; i < TASKS_TO_CREATE; i++){
109+
bool found = false;
110+
for(int j = 0; j < MAX_TASKS; j++){
111+
if(tsk_status_array[j].xHandle == created_handles[i]){
112+
found = true;
113+
break;
114+
}
115+
}
116+
if(!found){
117+
not_found = true;
118+
break;
119+
}
120+
}
121+
TEST_ASSERT(not_found == false);
122+
123+
//Cleanup
124+
for(int i = 0; i < TASKS_TO_CREATE; i++){
125+
vTaskDelete(created_handles[i]);
126+
}
127+
free(tsk_status_array);
128+
vTaskDelay(10);
129+
}
130+
131+
#endif //CONFIG_FREERTOS_USE_TRACE_FACILITY
132+

components/freertos/test/test_uxGetSystemState_Bugfix.c

Lines changed: 0 additions & 67 deletions
This file was deleted.

tools/unit-test-app/sdkconfig.defaults

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ CONFIG_ESP32_XTAL_FREQ_AUTO=y
1111
CONFIG_FREERTOS_HZ=1000
1212
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
1313
CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=3
14+
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
1415
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
1516
CONFIG_MBEDTLS_HARDWARE_MPI=y
1617
CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y

0 commit comments

Comments
 (0)