mirror of
https://github.com/esphome/esphome.git
synced 2026-09-19 11:08:38 +00:00
[esp32] Move HAL bodies from components/esp32/core.cpp into core/hal/
Per-platform follow-up to #15977. Move out-of-line HAL bodies (millis(), arch_restart(), arch_get_cpu_freq_hz()) from components/esp32/core.cpp into a new esphome/core/hal/hal_esp32.cpp so HAL implementation finally lives next to the HAL header. Inline the trivial one-liners directly in hal_esp32.h: delayMicroseconds(us) -> delay_microseconds_safe(us) arch_feed_wdt() -> esp_task_wdt_reset() arch_get_cpu_cycle_count() -> esp_cpu_get_cycle_count() arch_init() stays in components/esp32/core.cpp because it uses esp32::crash_handler_read_and_clear() from the component-private crash_handler.h header — moving it would require an awkward layering inversion of core/ -> components/esp32/. config.py FILTER_SOURCE_FILES gains a hal/hal_esp32.cpp entry so only ESP32 builds compile it (same pattern wake/wake_*.cpp uses). Cross-platform decls of delayMicroseconds(), arch_feed_wdt(), and arch_get_cpu_cycle_count() are dropped from the dispatcher hal.h and moved into each per-platform header — that way subsequent per-platform follow-up PRs (libretiny, rp2040, host, zephyr) only need to touch their own platform header instead of accumulating gates in hal.h.
This commit is contained in:
@@ -6,12 +6,8 @@
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "preferences.h"
|
||||
#include <esp_clk_tree.h>
|
||||
#include <esp_cpu.h>
|
||||
#include <esp_idf_version.h>
|
||||
#include <esp_ota_ops.h>
|
||||
#include <esp_task_wdt.h>
|
||||
#include <esp_timer.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
|
||||
@@ -23,29 +19,8 @@ extern "C" __attribute__((weak)) void initArduino() {}
|
||||
namespace esphome {
|
||||
|
||||
// yield(), delay(), micros(), millis_64() inlined in hal.h.
|
||||
// Use xTaskGetTickCount() when tick rate is 1 kHz (ESPHome's default via sdkconfig),
|
||||
// falling back to esp_timer for non-standard rates. IRAM_ATTR is required because
|
||||
// Wiegand and ZyAura call millis() from IRAM_ATTR ISR handlers on ESP32.
|
||||
// xTaskGetTickCountFromISR() is used in ISR context to satisfy the FreeRTOS API contract.
|
||||
uint32_t IRAM_ATTR HOT millis() {
|
||||
#if CONFIG_FREERTOS_HZ == 1000
|
||||
if (xPortInIsrContext()) [[unlikely]] {
|
||||
return xTaskGetTickCountFromISR();
|
||||
}
|
||||
return xTaskGetTickCount();
|
||||
#else
|
||||
return micros_to_millis(static_cast<uint64_t>(esp_timer_get_time()));
|
||||
#endif
|
||||
}
|
||||
void IRAM_ATTR HOT delayMicroseconds(uint32_t us) { delay_microseconds_safe(us); }
|
||||
void arch_restart() {
|
||||
esp_restart();
|
||||
// restart() doesn't always end execution
|
||||
while (true) { // NOLINT(clang-diagnostic-unreachable-code)
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
||||
// millis(), arch_restart(), arch_get_cpu_freq_hz() out-of-line in hal/hal_esp32.cpp.
|
||||
// delayMicroseconds(), arch_feed_wdt(), arch_get_cpu_cycle_count() inlined in hal/hal_esp32.h.
|
||||
void arch_init() {
|
||||
#ifdef USE_ESP32_CRASH_HANDLER
|
||||
// Read crash data from previous boot before anything else
|
||||
@@ -61,14 +36,6 @@ void arch_init() {
|
||||
esp_ota_mark_app_valid_cancel_rollback();
|
||||
#endif
|
||||
}
|
||||
void HOT arch_feed_wdt() { esp_task_wdt_reset(); }
|
||||
|
||||
uint32_t arch_get_cpu_cycle_count() { return esp_cpu_get_cycle_count(); }
|
||||
uint32_t arch_get_cpu_freq_hz() {
|
||||
uint32_t freq = 0;
|
||||
esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_CPU, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &freq);
|
||||
return freq;
|
||||
}
|
||||
|
||||
TaskHandle_t loop_task_handle = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
static StaticTask_t loop_task_tcb; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
@@ -815,6 +815,16 @@ FILTER_SOURCE_FILES = filter_source_files_from_platform(
|
||||
"wake/wake_zephyr.cpp": {
|
||||
PlatformFramework.NRF52_ZEPHYR,
|
||||
},
|
||||
# Per-platform HAL out-of-line implementations — hal.h dispatches to
|
||||
# exactly one platform header based on USE_*, and the matching .cpp
|
||||
# provides the few HAL functions that stay out-of-line. Other
|
||||
# platforms still keep their out-of-line bodies in
|
||||
# components/<platform>/core.cpp until their per-platform follow-up
|
||||
# PR moves them here.
|
||||
"hal/hal_esp32.cpp": {
|
||||
PlatformFramework.ESP32_ARDUINO,
|
||||
PlatformFramework.ESP32_IDF,
|
||||
},
|
||||
# Note: lock_free_queue.h and event_pool.h are header files and don't need to be filtered
|
||||
# as they are only included when needed by the preprocessor
|
||||
}
|
||||
|
||||
+3
-7
@@ -30,15 +30,11 @@
|
||||
|
||||
namespace esphome {
|
||||
|
||||
// ESP8266 inlines delayMicroseconds() and arch_feed_wdt() in hal/hal_esp8266.h;
|
||||
// every other platform keeps them out-of-line in components/<platform>/core.cpp.
|
||||
#ifndef USE_ESP8266
|
||||
void delayMicroseconds(uint32_t us); // NOLINT(readability-identifier-naming)
|
||||
void arch_feed_wdt();
|
||||
#endif
|
||||
// Cross-platform declarations. delayMicroseconds(), arch_feed_wdt(),
|
||||
// arch_get_cpu_cycle_count() vary per platform (some inline, some
|
||||
// out-of-line) so they live in hal/hal_<platform>.h.
|
||||
void __attribute__((noreturn)) arch_restart();
|
||||
void arch_init();
|
||||
uint32_t arch_get_cpu_cycle_count();
|
||||
uint32_t arch_get_cpu_freq_hz();
|
||||
|
||||
#ifndef USE_ESP8266
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include "esphome/core/hal.h"
|
||||
|
||||
#include <esp_clk_tree.h>
|
||||
#include <esp_system.h>
|
||||
#include <esp_timer.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
|
||||
namespace esphome {
|
||||
|
||||
// Use xTaskGetTickCount() when tick rate is 1 kHz (ESPHome's default via sdkconfig),
|
||||
// falling back to esp_timer for non-standard rates. IRAM_ATTR is required because
|
||||
// Wiegand and ZyAura call millis() from IRAM_ATTR ISR handlers on ESP32.
|
||||
// xTaskGetTickCountFromISR() is used in ISR context to satisfy the FreeRTOS API contract.
|
||||
uint32_t IRAM_ATTR HOT millis() {
|
||||
#if CONFIG_FREERTOS_HZ == 1000
|
||||
if (xPortInIsrContext()) [[unlikely]] {
|
||||
return xTaskGetTickCountFromISR();
|
||||
}
|
||||
return xTaskGetTickCount();
|
||||
#else
|
||||
return micros_to_millis(static_cast<uint64_t>(esp_timer_get_time()));
|
||||
#endif
|
||||
}
|
||||
|
||||
void arch_restart() {
|
||||
esp_restart();
|
||||
// restart() doesn't always end execution
|
||||
while (true) { // NOLINT(clang-diagnostic-unreachable-code)
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t arch_get_cpu_freq_hz() {
|
||||
uint32_t freq = 0;
|
||||
esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_CPU, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &freq);
|
||||
return freq;
|
||||
}
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ESP32
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <esp_attr.h>
|
||||
#include <esp_cpu.h>
|
||||
#include <esp_task_wdt.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
|
||||
@@ -15,6 +17,11 @@
|
||||
|
||||
namespace esphome {
|
||||
|
||||
// Forward decl from helpers.h (esphome/core/helpers.h) — kept here so this
|
||||
// header does not need to pull the rest of helpers.h.
|
||||
// NOLINTNEXTLINE(readability-redundant-declaration)
|
||||
void delay_microseconds_safe(uint32_t us);
|
||||
|
||||
/// Returns true when executing inside an interrupt handler.
|
||||
__attribute__((always_inline)) inline bool in_isr_context() { return xPortInIsrContext() != 0; }
|
||||
|
||||
@@ -30,6 +37,11 @@ __attribute__((always_inline)) inline uint64_t millis_64() {
|
||||
return micros_to_millis<uint64_t>(static_cast<uint64_t>(esp_timer_get_time()));
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
__attribute__((always_inline)) inline void delayMicroseconds(uint32_t us) { delay_microseconds_safe(us); }
|
||||
__attribute__((always_inline)) inline void arch_feed_wdt() { esp_task_wdt_reset(); }
|
||||
__attribute__((always_inline)) inline uint32_t arch_get_cpu_cycle_count() { return esp_cpu_get_cycle_count(); }
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ESP32
|
||||
|
||||
@@ -19,6 +19,10 @@ uint32_t micros();
|
||||
uint32_t millis();
|
||||
uint64_t millis_64();
|
||||
|
||||
void delayMicroseconds(uint32_t us); // NOLINT(readability-identifier-naming)
|
||||
void arch_feed_wdt();
|
||||
uint32_t arch_get_cpu_cycle_count();
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_HOST
|
||||
|
||||
@@ -88,6 +88,10 @@ __attribute__((always_inline)) inline uint32_t millis() { return static_cast<uin
|
||||
#endif
|
||||
__attribute__((always_inline)) inline uint64_t millis_64() { return Millis64Impl::compute(millis()); }
|
||||
|
||||
void delayMicroseconds(uint32_t us); // NOLINT(readability-identifier-naming)
|
||||
void arch_feed_wdt();
|
||||
uint32_t arch_get_cpu_cycle_count();
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_LIBRETINY
|
||||
|
||||
@@ -35,6 +35,10 @@ __attribute__((always_inline)) inline uint32_t micros() { return static_cast<uin
|
||||
__attribute__((always_inline)) inline uint32_t millis() { return micros_to_millis(::time_us_64()); }
|
||||
__attribute__((always_inline)) inline uint64_t millis_64() { return micros_to_millis<uint64_t>(::time_us_64()); }
|
||||
|
||||
void delayMicroseconds(uint32_t us); // NOLINT(readability-identifier-naming)
|
||||
void arch_feed_wdt();
|
||||
uint32_t arch_get_cpu_cycle_count();
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_RP2040
|
||||
|
||||
@@ -19,6 +19,10 @@ uint32_t micros();
|
||||
uint32_t millis();
|
||||
uint64_t millis_64();
|
||||
|
||||
void delayMicroseconds(uint32_t us); // NOLINT(readability-identifier-naming)
|
||||
void arch_feed_wdt();
|
||||
uint32_t arch_get_cpu_cycle_count();
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ZEPHYR
|
||||
|
||||
Reference in New Issue
Block a user