test_esp_timer.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #ifdef __cpp_exceptions
  7. #include "unity.h"
  8. #include "unity_cxx.hpp"
  9. #include <limits>
  10. #include <stdio.h>
  11. #include <iostream>
  12. #include "test_utils.h" // ref clock
  13. #include "freertos/FreeRTOS.h"
  14. #include "freertos/task.h"
  15. #include "freertos/semphr.h"
  16. #include "esp_timer_cxx.hpp"
  17. #include "esp_exception.hpp"
  18. using namespace std;
  19. using namespace idf;
  20. using namespace idf::esp_timer;
  21. struct RefClock {
  22. RefClock()
  23. {
  24. ref_clock_init();
  25. };
  26. ~RefClock()
  27. {
  28. ref_clock_deinit();
  29. }
  30. };
  31. TEST_CASE("ESPTimer produces correct delay", "[ESPTimer]")
  32. {
  33. int64_t t_end;
  34. RefClock ref_clock;
  35. function<void()> timer_cb = [&t_end]() {
  36. t_end = ref_clock_get();
  37. };
  38. ESPTimer timer(timer_cb, "timer1");
  39. const int delays_ms[] = {20, 100, 200, 250};
  40. const size_t delays_count = sizeof(delays_ms)/sizeof(delays_ms[0]);
  41. for (size_t i = 0; i < delays_count; ++i) {
  42. t_end = 0;
  43. int64_t t_start = ref_clock_get();
  44. timer.start(chrono::microseconds(delays_ms[i] * 1000));
  45. vTaskDelay(delays_ms[i] * 2 / portTICK_PERIOD_MS);
  46. TEST_ASSERT(t_end != 0);
  47. int32_t ms_diff = (t_end - t_start) / 1000;
  48. printf("%d %d\n", delays_ms[i], ms_diff);
  49. TEST_ASSERT_INT32_WITHIN(portTICK_PERIOD_MS, delays_ms[i], ms_diff);
  50. }
  51. }
  52. TEST_CASE("ESPtimer produces correct periodic delays", "[ESPTimer]")
  53. {
  54. const size_t NUM_INTERVALS = 3u;
  55. size_t cur_interval = 0;
  56. int intervals[NUM_INTERVALS];
  57. int64_t t_start;
  58. SemaphoreHandle_t done;
  59. const int DELAY_MS = 100;
  60. function<void()> timer_cb = [&]() {
  61. int64_t t_end = ref_clock_get();
  62. int32_t ms_diff = (t_end - t_start) / 1000;
  63. printf("timer #%d %dms\n", cur_interval, ms_diff);
  64. if (cur_interval < NUM_INTERVALS) {
  65. intervals[cur_interval++] = ms_diff;
  66. }
  67. // Deliberately make timer handler run longer.
  68. // We check that this doesn't affect the result.
  69. esp_rom_delay_us(10*1000);
  70. if (cur_interval == NUM_INTERVALS) {
  71. printf("done\n");
  72. xSemaphoreGive(done);
  73. }
  74. };
  75. ESPTimer timer(timer_cb, "timer1");
  76. RefClock ref_clock;
  77. t_start = ref_clock_get();
  78. done = xSemaphoreCreateBinary();
  79. timer.start_periodic(chrono::microseconds(DELAY_MS * 1000));
  80. TEST_ASSERT(xSemaphoreTake(done, DELAY_MS * NUM_INTERVALS * 2));
  81. timer.stop();
  82. TEST_ASSERT_EQUAL_UINT32(NUM_INTERVALS, cur_interval);
  83. for (size_t i = 0; i < NUM_INTERVALS; ++i) {
  84. TEST_ASSERT_INT32_WITHIN(portTICK_PERIOD_MS, (i + 1) * DELAY_MS, intervals[i]);
  85. }
  86. TEST_ESP_OK(esp_timer_dump(stdout));
  87. vSemaphoreDelete(done);
  88. #undef NUM_INTERVALS
  89. }
  90. #endif // __cpp_exceptions