1 /*
2 Test for FreeRTOS vTaskDelayUntil() function by comparing the delay period of
3 the function to comparing it to ref clock.
4 */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include "freertos/FreeRTOS.h"
9 #include "freertos/task.h"
10 #include "freertos/semphr.h"
11 #include "unity.h"
12 #include "test_utils.h"
13
14 #define TSK_PRIORITY (UNITY_FREERTOS_PRIORITY + 1)
15
16 #define NO_OF_CYCLES 5
17 #define NO_OF_TASKS_PER_CORE 2
18 #define TICKS_TO_DELAY 10
19 #define TICK_RATE configTICK_RATE_HZ
20 #define TICK_PERIOD_US (1000000/TICK_RATE)
21 #define IDEAL_DELAY_PERIOD_MS ((1000*TICKS_TO_DELAY)/TICK_RATE)
22 #define IDEAL_DELAY_PERIOD_US (IDEAL_DELAY_PERIOD_MS*1000)
23
24 #define TICKS_TO_MS(x) (((x)*1000)/TICK_RATE)
25 #define REF_TO_ROUND_MS(x) (((x)+500)/1000)
26
27 static SemaphoreHandle_t task_delete_semphr;
28
delaying_task(void * arg)29 static void delaying_task(void* arg)
30 {
31 uint64_t ref_prev, ref_current;
32 TickType_t last_wake_time;
33 TickType_t ticks_before_delay;
34
35 vTaskDelay(1); //Delay until next tick to synchronize operations to tick boundaries
36
37 last_wake_time = xTaskGetTickCount();
38 ticks_before_delay = last_wake_time;
39 ref_prev = ref_clock_get();
40
41 for(int i = 0; i < NO_OF_CYCLES; i++){
42 //Delay of TICKS_TO_DELAY
43 vTaskDelayUntil(&last_wake_time, TICKS_TO_DELAY);
44 //Get current ref clock
45 TEST_ASSERT_EQUAL(IDEAL_DELAY_PERIOD_MS, TICKS_TO_MS(xTaskGetTickCount() - ticks_before_delay));
46 ref_current = ref_clock_get();
47 TEST_ASSERT_UINT32_WITHIN(TICK_PERIOD_US, IDEAL_DELAY_PERIOD_US, (uint32_t)(ref_current - ref_prev));
48 ref_prev = ref_current;
49 ticks_before_delay = last_wake_time;
50 }
51
52 //Delete Task after prescribed number of cycles
53 xSemaphoreGive(task_delete_semphr);
54 vTaskDelete(NULL);
55 }
56
57 TEST_CASE("Test vTaskDelayUntil", "[freertos]")
58 {
59 task_delete_semphr = xQueueCreateCountingSemaphore(NO_OF_TASKS_PER_CORE*portNUM_PROCESSORS, 0);
60 ref_clock_init();
61
62 for(int i = 0; i < portNUM_PROCESSORS; i++){
63 xTaskCreatePinnedToCore(delaying_task, "delay_pinned", 1024, NULL, TSK_PRIORITY, NULL, i);
64 xTaskCreatePinnedToCore(delaying_task, "delay_no_aff", 1024, NULL, TSK_PRIORITY, NULL, tskNO_AFFINITY);
65 }
66
67 for(int i = 0; i < NO_OF_TASKS_PER_CORE*portNUM_PROCESSORS; i++){
68 xSemaphoreTake(task_delete_semphr, portMAX_DELAY);
69 }
70 //Cleanup
71 vSemaphoreDelete(task_delete_semphr);
72 ref_clock_deinit();
73 }
74