* ISR happens follow set_alarm, so change the ALARM_OVERFLOW_VAL to resolve this problem.
* Set it to 0xefffffffUL. The remain 0x10000000UL(about 3 second) is enough to handle ISR.
*/
-#define ALARM_OVERFLOW_VAL 0xefffffffUL
+#define DEFAULT_ALARM_OVERFLOW_VAL 0xefffffffUL
+
+/* Provision to set lower overflow value for unit testing. Lowering the
+ * overflow value helps check for race conditions which occur near overflow
+ * moment.
+ */
+#ifndef ESP_TIMER_DYNAMIC_OVERFLOW_VAL
+#define ALARM_OVERFLOW_VAL DEFAULT_ALARM_OVERFLOW_VAL
+#else
+static uint32_t s_alarm_overflow_val = DEFAULT_ALARM_OVERFLOW_VAL;
+#define ALARM_OVERFLOW_VAL (s_alarm_overflow_val)
+#endif
static const char* TAG = "esp_timer_impl";
{
return 50;
}
+
+#ifdef ESP_TIMER_DYNAMIC_OVERFLOW_VAL
+uint32_t esp_timer_impl_get_overflow_val()
+{
+ return s_alarm_overflow_val;
+}
+
+void esp_timer_impl_set_overflow_val(uint32_t overflow_val)
+{
+ s_alarm_overflow_val = overflow_val;
+ /* update alarm value */
+ esp_timer_impl_update_apb_freq(esp_clk_apb_freq() / 1000000);
+}
+#endif // ESP_TIMER_DYNAMIC_OVERFLOW_VAL
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
+#include <sys/param.h>
#include "unity.h"
#include "esp_timer.h"
#include "esp_heap_caps.h"
#define WITH_PROFILING 1
#endif
+extern uint32_t esp_timer_impl_get_overflow_val();
+extern void esp_timer_impl_set_overflow_val(uint32_t overflow_val);
+
+static uint32_t s_old_overflow_val;
+
+static void setup_overflow()
+{
+ s_old_overflow_val = esp_timer_impl_get_overflow_val();
+ esp_timer_impl_set_overflow_val(0x7fffff); /* overflow every ~0.1 sec */}
+
+static void teardown_overflow()
+{
+ esp_timer_impl_set_overflow_val(s_old_overflow_val);
+}
TEST_CASE("esp_timer orders timers correctly", "[esp_timer]")
{
const size_t num_timers = sizeof(timeouts)/sizeof(timeouts[0]);
esp_timer_handle_t handles[num_timers];
char* names[num_timers];
+ setup_overflow();
for (size_t i = 0; i < num_timers; ++i) {
asprintf(&names[i], "timer%d", i);
esp_timer_create_args_t args = {
TEST_ESP_OK(esp_timer_create(&args, &handles[i]));
TEST_ESP_OK(esp_timer_start_once(handles[i], timeouts[i] * 100));
}
+ teardown_overflow();
char* stream_str[1024];
FILE* stream = fmemopen(stream_str, sizeof(stream_str), "r+");
TEST_ESP_OK(esp_timer_dump(stream));
const size_t delays_count = sizeof(delays_ms)/sizeof(delays_ms[0]);
ref_clock_init();
+ setup_overflow();
for (size_t i = 0; i < delays_count; ++i) {
t_end = 0;
int64_t t_start = ref_clock_get();
TEST_ASSERT_INT32_WITHIN(portTICK_PERIOD_MS, delays_ms[i], ms_diff);
}
+ teardown_overflow();
ref_clock_deinit();
TEST_ESP_OK( esp_timer_dump(stdout) );
};
TEST_ESP_OK(esp_timer_create(&create_args, &timer1));
ref_clock_init();
+ setup_overflow();
args.timer = timer1;
args.t_start = ref_clock_get();
args.done = xSemaphoreCreateBinary();
for (size_t i = 0; i < NUM_INTERVALS; ++i) {
TEST_ASSERT_INT32_WITHIN(portTICK_PERIOD_MS, (i + 1) * delay_ms, args.intervals[i]);
}
+ teardown_overflow();
ref_clock_deinit();
TEST_ESP_OK( esp_timer_dump(stdout) );
esp_timer_handle_t timer1, timer2;
ESP_ERROR_CHECK( esp_timer_create(&timer_args, &timer1) );
ESP_ERROR_CHECK( esp_timer_create(&timer_args, &timer2) );
+ setup_overflow();
const int timeout_ms = 10;
for (int timeout_delta_us = -150; timeout_delta_us < 150; timeout_delta_us++) {
printf("delta=%d", timeout_delta_us);
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_timer_stop(timer2));
}
+ teardown_overflow();
vSemaphoreDelete(semaphore);
}