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; int count_value = 0;
TEST_ESP_OK(pcnt_unit_clear_count(pwm_pcnt_unit)); TEST_ESP_OK(pcnt_unit_clear_count(pwm_pcnt_unit));
TEST_ESP_OK(pcnt_unit_start(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_stop(pwm_pcnt_unit));
TEST_ESP_OK(pcnt_unit_get_count(pwm_pcnt_unit, &count_value)); TEST_ESP_OK(pcnt_unit_get_count(pwm_pcnt_unit, &count_value));
printf("count value: %d\r\n", count_value); printf("count value: %d\r\n", count_value);

View File

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