fix(newlib): Fixed an issue where usleep() could consume more CPU cycles

The following changes are made in this commit:

1. This commit updates the implementation of usleep() to now always yield
   CPU time if undergoing a multi-tick sleep. This reduces the accuracy of
   usleep() but in turn allows the scheduler to schedule different tasks.

2. The commit also updates the MCPWM unit test which fails due to the
   change in the behavior of usleep().

Closes: https://github.com/espressif/esp-idf/pull/15132
This commit is contained in:
Sudeep Mohanty
2025-04-28 16:42:40 +02:00
parent bdf0ccaa74
commit 1e616eeb84
2 changed files with 8 additions and 7 deletions

View File

@@ -172,7 +172,7 @@ static uint32_t pcnt_get_pulse_number(pcnt_unit_handle_t pwm_pcnt_unit, int capt
int count_value = 0;
TEST_ESP_OK(pcnt_unit_clear_count(pwm_pcnt_unit));
TEST_ESP_OK(pcnt_unit_start(pwm_pcnt_unit));
usleep(capture_window_ms * 1000);
vTaskDelay(pdMS_TO_TICKS(capture_window_ms));
TEST_ESP_OK(pcnt_unit_stop(pwm_pcnt_unit));
TEST_ESP_OK(pcnt_unit_get_count(pwm_pcnt_unit, &count_value));
printf("count value: %d\r\n", count_value);

View File

@@ -219,12 +219,13 @@ int usleep(useconds_t us)
do {
vTaskDelay((((target_us - now_us) + us_per_tick - 1) / us_per_tick));
now_us = esp_time_impl_get_time();
/* If the time left until the target is less than 1 tick, then we use ROM delay to fill the gap */
uint64_t time_left = target_us - now_us;
if (time_left != 0 && time_left < us_per_tick) {
esp_rom_delay_us(time_left);
break;
}
/* It is possible that the time left until the target time is less
* than a tick period. However, we let usleep() to sleep for an
* entire tick period. This, could result in usleep() sleeping for
* a longer time than the requested time but that does not violate
* the spec of usleep(). Additionally, it allows FreeRTOS to schedule
* other tasks while the current task is sleeping.
*/
} while (now_us < target_us);
}
return 0;