1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <time.h>
4 #include <sys/time.h>
5 #include "unity.h"
6 #include "esp_rom_sys.h"
7 #include "freertos/FreeRTOS.h"
8 #include "freertos/task.h"
9 #include "freertos/semphr.h"
10 #include "test_utils.h"
11 
12 typedef struct {
13     int delay_us;
14     int method;
15     int result;
16     SemaphoreHandle_t done;
17 } delay_test_arg_t;
18 
test_delay_task(void * p)19 static void test_delay_task(void *p)
20 {
21     delay_test_arg_t *arg = (delay_test_arg_t *)p;
22     vTaskDelay(1);
23     uint64_t start = ref_clock_get();
24     switch (arg->method) {
25     case 0:
26         esp_rom_delay_us(arg->delay_us);
27         break;
28     case 1:
29         vTaskDelay(arg->delay_us / portTICK_PERIOD_MS / 1000);
30         break;
31     default:
32         TEST_FAIL();
33     }
34     uint64_t stop = ref_clock_get();
35 
36     arg->result = (int)(stop - start);
37     xSemaphoreGive(arg->done);
38     vTaskDelete(NULL);
39 }
40 
41 TEST_CASE("esp_rom_delay_us produces correct delay on CPUs", "[delay]")
42 {
43     int delay_ms = 50;
44     const delay_test_arg_t args = {
45         .delay_us = delay_ms * 1000,
46         .method = 0,
47         .done = xSemaphoreCreateBinary()
48     };
49     ref_clock_init();
50     xTaskCreatePinnedToCore(test_delay_task, "", 2048, (void *)&args, 3, NULL, 0);
51     TEST_ASSERT(xSemaphoreTake(args.done, delay_ms * 2 / portTICK_PERIOD_MS));
52     TEST_ASSERT_INT32_WITHIN(1000, args.delay_us, args.result);
53 
54 #if portNUM_PROCESSORS == 2
55     xTaskCreatePinnedToCore(test_delay_task, "", 2048, (void *)&args, 3, NULL, 1);
56     TEST_ASSERT(xSemaphoreTake(args.done, delay_ms * 2 / portTICK_PERIOD_MS));
57     TEST_ASSERT_INT32_WITHIN(1000, args.delay_us, args.result);
58 #endif
59 
60     ref_clock_deinit();
61     vSemaphoreDelete(args.done);
62 }
63 
64 TEST_CASE("vTaskDelay produces correct delay on CPUs", "[delay]")
65 {
66     int delay_ms = 50;
67     const delay_test_arg_t args = {
68         .delay_us = delay_ms * 1000,
69         .method = 1,
70         .done = xSemaphoreCreateBinary()
71     };
72     ref_clock_init();
73     xTaskCreatePinnedToCore(test_delay_task, "", 2048, (void *)&args, 3, NULL, 0);
74     TEST_ASSERT(xSemaphoreTake(args.done, delay_ms * 2 / portTICK_PERIOD_MS));
75     TEST_ASSERT_INT32_WITHIN(1000, args.delay_us, args.result);
76 
77 #if portNUM_PROCESSORS == 2
78     xTaskCreatePinnedToCore(test_delay_task, "", 2048, (void *)&args, 3, NULL, 1);
79     TEST_ASSERT(xSemaphoreTake(args.done, delay_ms * 2 / portTICK_PERIOD_MS));
80     TEST_ASSERT_INT32_WITHIN(1000, args.delay_us, args.result);
81 #endif
82 
83     ref_clock_deinit();
84     vSemaphoreDelete(args.done);
85 }
86