[core] Conditionally compile get_loop_priority with USE_LOOP_PRIORITY (#14210)

This commit is contained in:
J. Nick Koston
2026-02-22 15:57:23 -06:00
committed by GitHub
parent 509f06afac
commit ede2da2fbc
20 changed files with 45 additions and 0 deletions

View File

@@ -124,9 +124,11 @@ bool CH422GComponent::write_outputs_() {
float CH422GComponent::get_setup_priority() const { return setup_priority::IO; }
#ifdef USE_LOOP_PRIORITY
// Run our loop() method very early in the loop, so that we cache read values
// before other components call our digital_read() method.
float CH422GComponent::get_loop_priority() const { return 9.0f; } // Just after WIFI
#endif
void CH422GGPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
bool CH422GGPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) ^ this->inverted_; }

View File

@@ -23,7 +23,9 @@ class CH422GComponent : public Component, public i2c::I2CDevice {
void pin_mode(uint8_t pin, gpio::Flags flags);
float get_setup_priority() const override;
#ifdef USE_LOOP_PRIORITY
float get_loop_priority() const override;
#endif
void dump_config() override;
protected:

View File

@@ -129,9 +129,11 @@ bool CH423Component::write_outputs_() {
float CH423Component::get_setup_priority() const { return setup_priority::IO; }
#ifdef USE_LOOP_PRIORITY
// Run our loop() method very early in the loop, so that we cache read values
// before other components call our digital_read() method.
float CH423Component::get_loop_priority() const { return 9.0f; } // Just after WIFI
#endif
void CH423GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
bool CH423GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) ^ this->inverted_; }

View File

@@ -22,7 +22,9 @@ class CH423Component : public Component, public i2c::I2CDevice {
void pin_mode(uint8_t pin, gpio::Flags flags);
float get_setup_priority() const override;
#ifdef USE_LOOP_PRIORITY
float get_loop_priority() const override;
#endif
void dump_config() override;
protected:

View File

@@ -40,9 +40,11 @@ void DeepSleepComponent::loop() {
this->begin_sleep();
}
#ifdef USE_LOOP_PRIORITY
float DeepSleepComponent::get_loop_priority() const {
return -100.0f; // run after everything else is ready
}
#endif
void DeepSleepComponent::set_sleep_duration(uint32_t time_ms) { this->sleep_duration_ = uint64_t(time_ms) * 1000; }

View File

@@ -113,7 +113,9 @@ class DeepSleepComponent : public Component {
void setup() override;
void dump_config() override;
void loop() override;
#ifdef USE_LOOP_PRIORITY
float get_loop_priority() const override;
#endif
float get_setup_priority() const override;
/// Helper to enter deep sleep mode

View File

@@ -122,8 +122,10 @@ bool PCA9554Component::write_register_(uint8_t reg, uint16_t value) {
float PCA9554Component::get_setup_priority() const { return setup_priority::IO; }
#ifdef USE_LOOP_PRIORITY
// Run our loop() method early to invalidate cache before any other components access the pins
float PCA9554Component::get_loop_priority() const { return 9.0f; } // Just after WIFI
#endif
void PCA9554GPIOPin::setup() { pin_mode(flags_); }
void PCA9554GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }

View File

@@ -23,7 +23,9 @@ class PCA9554Component : public Component,
float get_setup_priority() const override;
#ifdef USE_LOOP_PRIORITY
float get_loop_priority() const override;
#endif
void dump_config() override;

View File

@@ -99,8 +99,10 @@ bool PCF8574Component::write_gpio_() {
}
float PCF8574Component::get_setup_priority() const { return setup_priority::IO; }
#ifdef USE_LOOP_PRIORITY
// Run our loop() method early to invalidate cache before any other components access the pins
float PCF8574Component::get_loop_priority() const { return 9.0f; } // Just after WIFI
#endif
void PCF8574GPIOPin::setup() { pin_mode(flags_); }
void PCF8574GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }

View File

@@ -26,7 +26,9 @@ class PCF8574Component : public Component,
void pin_mode(uint8_t pin, gpio::Flags flags);
float get_setup_priority() const override;
#ifdef USE_LOOP_PRIORITY
float get_loop_priority() const override;
#endif
void dump_config() override;

View File

@@ -30,7 +30,9 @@ class StatusLEDLightOutput : public light::LightOutput, public Component {
void dump_config() override;
float get_setup_priority() const override { return setup_priority::HARDWARE; }
#ifdef USE_LOOP_PRIORITY
float get_loop_priority() const override { return 50.0f; }
#endif
protected:
GPIOPin *pin_{nullptr};

View File

@@ -28,7 +28,9 @@ void StatusLED::loop() {
}
}
float StatusLED::get_setup_priority() const { return setup_priority::HARDWARE; }
#ifdef USE_LOOP_PRIORITY
float StatusLED::get_loop_priority() const { return 50.0f; }
#endif
} // namespace status_led
} // namespace esphome

View File

@@ -14,7 +14,9 @@ class StatusLED : public Component {
void dump_config() override;
void loop() override;
float get_setup_priority() const override;
#ifdef USE_LOOP_PRIORITY
float get_loop_priority() const override;
#endif
protected:
GPIOPin *pin_;

View File

@@ -536,6 +536,13 @@ async def to_code(config):
cg.add_library("ESP8266WiFi", None)
elif CORE.is_rp2040:
cg.add_library("WiFi", None)
# RP2040's mDNS library (LEAmDNS) relies on LwipIntf::stateUpCB() to restart
# mDNS when the network interface reconnects. However, this callback is disabled
# in the arduino-pico framework. As a workaround, we block component setup until
# WiFi is connected via can_proceed(), ensuring mDNS.begin() is called with an
# active connection. This define enables the loop priority sorting infrastructure
# used during the setup blocking phase.
cg.add_define("USE_LOOP_PRIORITY")
if CORE.is_esp32:
if config[CONF_ENABLE_BTM] or config[CONF_ENABLE_RRM]:

View File

@@ -968,9 +968,11 @@ void WiFiComponent::set_ap(const WiFiAP &ap) {
}
#endif // USE_WIFI_AP
#ifdef USE_LOOP_PRIORITY
float WiFiComponent::get_loop_priority() const {
return 10.0f; // before other loop components
}
#endif
void WiFiComponent::init_sta(size_t count) { this->sta_.init(count); }
void WiFiComponent::add_sta(const WiFiAP &ap) { this->sta_.push_back(ap); }

View File

@@ -458,7 +458,9 @@ class WiFiComponent : public Component {
void restart_adapter();
/// WIFI setup_priority.
float get_setup_priority() const override;
#ifdef USE_LOOP_PRIORITY
float get_loop_priority() const override;
#endif
/// Reconnect WiFi if required.
void loop() override;

View File

@@ -109,9 +109,11 @@ void Application::setup() {
if (component->can_proceed())
continue;
#ifdef USE_LOOP_PRIORITY
// Sort components 0 through i by loop priority
insertion_sort_by_priority<decltype(this->components_.begin()), &Component::get_loop_priority>(
this->components_.begin(), this->components_.begin() + i + 1);
#endif
do {
uint8_t new_app_state = STATUS_LED_WARNING;

View File

@@ -85,7 +85,9 @@ void store_component_error_message(const Component *component, const char *messa
static constexpr uint16_t WARN_IF_BLOCKING_INCREMENT_MS =
10U; ///< How long the blocking time must be larger to warn again
#ifdef USE_LOOP_PRIORITY
float Component::get_loop_priority() const { return 0.0f; }
#endif
float Component::get_setup_priority() const { return setup_priority::DATA; }

View File

@@ -5,6 +5,7 @@
#include <functional>
#include <string>
#include "esphome/core/defines.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
#include "esphome/core/optional.h"
@@ -117,7 +118,9 @@ class Component {
*
* @return The loop priority of this component
*/
#ifdef USE_LOOP_PRIORITY
virtual float get_loop_priority() const;
#endif
void call();

View File

@@ -312,6 +312,7 @@
#ifdef USE_RP2040
#define USE_ARDUINO_VERSION_CODE VERSION_CODE(3, 3, 0)
#define USE_LOOP_PRIORITY
#define USE_HTTP_REQUEST_RESPONSE
#define USE_I2C
#define USE_LOGGER_USB_CDC