Skip to content

Commit c060a85

Browse files
committed
fix(newlib): usleep returning early
1 parent b5ac4fb commit c060a85

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

components/newlib/src/time.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,19 @@ int usleep(useconds_t us)
207207
if (us < us_per_tick) {
208208
esp_rom_delay_us((uint32_t) us);
209209
} else {
210-
/* since vTaskDelay(1) blocks for anywhere between 0 and portTICK_PERIOD_MS,
211-
* round up to compensate.
212-
*/
213-
vTaskDelay((us + us_per_tick - 1) / us_per_tick);
210+
/* vTaskDelay may return up to (n-1) tick periods due to the tick ISR
211+
being asynchronous to the call. We must sleep at least the specified
212+
time, or longer. Checking the monotonic clock allows making an
213+
additional call to vTaskDelay when needed to ensure minimal time is
214+
actually slept. Adding `us_per_tick - 1` prevents ever passing 0 to
215+
vTaskDelay().
216+
*/
217+
uint64_t now_us = esp_time_impl_get_time();
218+
uint64_t target_us = now_us + us;
219+
do {
220+
vTaskDelay((((target_us - now_us) + us_per_tick - 1) / us_per_tick));
221+
now_us = esp_time_impl_get_time();
222+
} while (now_us < target_us);
214223
}
215224
return 0;
216225
}

0 commit comments

Comments
 (0)