mirror of
https://github.com/esphome/esphome.git
synced 2026-09-14 08:38:39 +00:00
[esp32] Use xTaskGetTickCount() for millis() when tick rate is 1kHz
ESPHome sets CONFIG_FREERTOS_HZ=1000, so one FreeRTOS tick equals one millisecond and xTaskGetTickCount() returns ms directly. This replaces esp_timer_get_time() + micros_to_millis() (a hardware timer read plus a 64-bit multiply-shift conversion) with a single volatile memory read. Benchmarked on real ESP32 hardware: Before: 686 ns/call (esp_timer_get_time + micros_to_millis) After: ~20 ns/call (volatile read of xTickCount) millis() is called 1+N times per main loop iteration (once at the top and once per component via WarnIfComponentBlockingGuard::finish()), so on a 5-component device this saves ~3.4 μs per loop iteration. millis_64() is left on esp_timer_get_time() for full 64-bit μs precision — it is only called once per loop by the Scheduler. micros() is also unchanged (runtime_stats needs μs precision). Falls back to the original implementation if CONFIG_FREERTOS_HZ != 1000 (non-standard user override).
This commit is contained in:
@@ -23,7 +23,19 @@ extern "C" __attribute__((weak)) void initArduino() {}
|
||||
namespace esphome {
|
||||
|
||||
void HOT yield() { vPortYield(); }
|
||||
uint32_t IRAM_ATTR HOT millis() { return micros_to_millis(static_cast<uint64_t>(esp_timer_get_time())); }
|
||||
uint32_t IRAM_ATTR HOT millis() {
|
||||
// ESPHome sets CONFIG_FREERTOS_HZ=1000 (see esp32/__init__.py), so one tick = one millisecond
|
||||
// and xTaskGetTickCount() returns ms directly. This is a single volatile memory read (~20ns)
|
||||
// vs esp_timer_get_time() + micros_to_millis() which does a hardware timer read + 64-bit
|
||||
// multiply-shift conversion (~686ns measured). millis() is called 1+N times per main loop
|
||||
// iteration (once at top + once per component for warn_blocking), so this saves ~3.4μs/loop
|
||||
// on a 5-component device. micros() still uses esp_timer_get_time() for μs precision.
|
||||
#if CONFIG_FREERTOS_HZ == 1000
|
||||
return xTaskGetTickCount();
|
||||
#else
|
||||
return micros_to_millis(static_cast<uint64_t>(esp_timer_get_time()));
|
||||
#endif
|
||||
}
|
||||
uint64_t HOT millis_64() { return micros_to_millis<uint64_t>(static_cast<uint64_t>(esp_timer_get_time())); }
|
||||
void HOT delay(uint32_t ms) { vTaskDelay(ms / portTICK_PERIOD_MS); }
|
||||
uint32_t IRAM_ATTR HOT micros() { return (uint32_t) esp_timer_get_time(); }
|
||||
|
||||
Reference in New Issue
Block a user