mirror of
https://github.com/esphome/esphome.git
synced 2025-09-18 03:02:20 +01:00
rename
This commit is contained in:
@@ -163,15 +163,15 @@ void Component::enable_loop() {
|
|||||||
App.enable_component_loop_(this);
|
App.enable_component_loop_(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void IRAM_ATTR HOT Component::enable_loop_soon_from_isr() {
|
void IRAM_ATTR HOT Component::enable_loop_soon_any_context() {
|
||||||
// This method is ISR-safe because:
|
// This method is thread and ISR-safe because:
|
||||||
// 1. Only performs simple assignments to volatile variables (atomic on all platforms)
|
// 1. Only performs simple assignments to volatile variables (atomic on all platforms)
|
||||||
// 2. No read-modify-write operations that could be interrupted
|
// 2. No read-modify-write operations that could be interrupted
|
||||||
// 3. No memory allocation, object construction, or function calls
|
// 3. No memory allocation, object construction, or function calls
|
||||||
// 4. IRAM_ATTR ensures code is in IRAM, not flash (required for ISR execution)
|
// 4. IRAM_ATTR ensures code is in IRAM, not flash (required for ISR execution)
|
||||||
// 5. Components are never destroyed, so no use-after-free concerns
|
// 5. Components are never destroyed, so no use-after-free concerns
|
||||||
// 6. App is guaranteed to be initialized before any ISR could fire
|
// 6. App is guaranteed to be initialized before any ISR could fire
|
||||||
// 7. Multiple ISR calls are safe - just sets the same flags to true
|
// 7. Multiple ISR/thread calls are safe - just sets the same flags to true
|
||||||
// 8. Race condition with main loop is handled by clearing flag before processing
|
// 8. Race condition with main loop is handled by clearing flag before processing
|
||||||
this->pending_enable_loop_ = true;
|
this->pending_enable_loop_ = true;
|
||||||
App.has_pending_enable_loop_requests_ = true;
|
App.has_pending_enable_loop_requests_ = true;
|
||||||
|
@@ -171,15 +171,15 @@ class Component {
|
|||||||
*/
|
*/
|
||||||
void enable_loop();
|
void enable_loop();
|
||||||
|
|
||||||
/** ISR-safe version of enable_loop() that can be called from interrupt context.
|
/** Thread and ISR-safe version of enable_loop() that can be called from any context.
|
||||||
*
|
*
|
||||||
* This method defers the actual enable via enable_pending_loops_ to the main loop,
|
* This method defers the actual enable via enable_pending_loops_ to the main loop,
|
||||||
* making it safe to call from ISR handlers, timer callbacks, or other
|
* making it safe to call from ISR handlers, timer callbacks, other threads,
|
||||||
* interrupt contexts.
|
* or any interrupt context.
|
||||||
*
|
*
|
||||||
* @note The actual loop enabling will happen on the next main loop iteration.
|
* @note The actual loop enabling will happen on the next main loop iteration.
|
||||||
* @note Only one pending enable request is tracked per component.
|
* @note Only one pending enable request is tracked per component.
|
||||||
* @note There is no disable_loop_soon_from_isr() on purpose - it would race
|
* @note There is no disable_loop_soon_any_context() on purpose - it would race
|
||||||
* against enable calls and synchronization would get too complex
|
* against enable calls and synchronization would get too complex
|
||||||
* to provide a safe version that would work for each component.
|
* to provide a safe version that would work for each component.
|
||||||
*
|
*
|
||||||
@@ -190,7 +190,7 @@ class Component {
|
|||||||
* disable_loop() in its next ::loop() iteration. Implementations
|
* disable_loop() in its next ::loop() iteration. Implementations
|
||||||
* will need to carefully consider all possible race conditions.
|
* will need to carefully consider all possible race conditions.
|
||||||
*/
|
*/
|
||||||
void enable_loop_soon_from_isr();
|
void enable_loop_soon_any_context();
|
||||||
|
|
||||||
bool is_failed() const;
|
bool is_failed() const;
|
||||||
|
|
||||||
@@ -363,7 +363,7 @@ class Component {
|
|||||||
/// Bit 3: STATUS_LED_ERROR
|
/// Bit 3: STATUS_LED_ERROR
|
||||||
/// Bits 4-7: Unused - reserved for future expansion (50% of the bits are free)
|
/// Bits 4-7: Unused - reserved for future expansion (50% of the bits are free)
|
||||||
uint8_t component_state_{0x00};
|
uint8_t component_state_{0x00};
|
||||||
volatile bool pending_enable_loop_{false}; ///< ISR-safe flag for enable_loop_soon_from_isr
|
volatile bool pending_enable_loop_{false}; ///< ISR-safe flag for enable_loop_soon_any_context
|
||||||
};
|
};
|
||||||
|
|
||||||
/** This class simplifies creating components that periodically check a state.
|
/** This class simplifies creating components that periodically check a state.
|
||||||
|
@@ -67,10 +67,10 @@ void IRAM_ATTR LoopTestISRComponent::simulate_isr_enable() {
|
|||||||
|
|
||||||
this->isr_call_count_++;
|
this->isr_call_count_++;
|
||||||
|
|
||||||
// Call enable_loop_soon_from_isr multiple times to test that it's safe
|
// Call enable_loop_soon_any_context multiple times to test that it's safe
|
||||||
this->enable_loop_soon_from_isr();
|
this->enable_loop_soon_any_context();
|
||||||
this->enable_loop_soon_from_isr(); // Test multiple calls
|
this->enable_loop_soon_any_context(); // Test multiple calls
|
||||||
this->enable_loop_soon_from_isr(); // Should be idempotent
|
this->enable_loop_soon_any_context(); // Should be idempotent
|
||||||
|
|
||||||
// Note: In a real ISR, we cannot use ESP_LOG* macros as they're not ISR-safe
|
// Note: In a real ISR, we cannot use ESP_LOG* macros as they're not ISR-safe
|
||||||
// For testing, we'll track the call count and log it from the main loop
|
// For testing, we'll track the call count and log it from the main loop
|
||||||
|
@@ -14,7 +14,7 @@ class LoopTestISRComponent : public Component {
|
|||||||
void setup() override;
|
void setup() override;
|
||||||
void loop() override;
|
void loop() override;
|
||||||
|
|
||||||
// Simulates an ISR calling enable_loop_soon_from_isr
|
// Simulates an ISR calling enable_loop_soon_any_context
|
||||||
void simulate_isr_enable();
|
void simulate_isr_enable();
|
||||||
|
|
||||||
float get_setup_priority() const override { return setup_priority::DATA; }
|
float get_setup_priority() const override { return setup_priority::DATA; }
|
||||||
|
@@ -35,7 +35,7 @@ loop_test_component:
|
|||||||
test_redundant_operations: true
|
test_redundant_operations: true
|
||||||
disable_after: 10
|
disable_after: 10
|
||||||
|
|
||||||
# ISR test component that uses enable_loop_soon_from_isr
|
# ISR test component that uses enable_loop_soon_any_context
|
||||||
isr_components:
|
isr_components:
|
||||||
- id: isr_test
|
- id: isr_test
|
||||||
name: "isr_test"
|
name: "isr_test"
|
||||||
|
Reference in New Issue
Block a user