mirror of
				https://github.com/esphome/esphome.git
				synced 2025-11-04 00:51:49 +00:00 
			
		
		
		
	Merge branch 'dev' into zero_copy_str
This commit is contained in:
		@@ -71,8 +71,11 @@ void Application::setup() {
 | 
			
		||||
 | 
			
		||||
    do {
 | 
			
		||||
      uint8_t new_app_state = STATUS_LED_WARNING;
 | 
			
		||||
      this->scheduler.call(millis());
 | 
			
		||||
      this->feed_wdt();
 | 
			
		||||
      uint32_t now = millis();
 | 
			
		||||
 | 
			
		||||
      // Process pending loop enables to handle GPIO interrupts during setup
 | 
			
		||||
      this->before_loop_tasks_(now);
 | 
			
		||||
 | 
			
		||||
      for (uint32_t j = 0; j <= i; j++) {
 | 
			
		||||
        // Update loop_component_start_time_ right before calling each component
 | 
			
		||||
        this->loop_component_start_time_ = millis();
 | 
			
		||||
@@ -81,6 +84,8 @@ void Application::setup() {
 | 
			
		||||
        this->app_state_ |= new_app_state;
 | 
			
		||||
        this->feed_wdt();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this->after_loop_tasks_();
 | 
			
		||||
      this->app_state_ = new_app_state;
 | 
			
		||||
      yield();
 | 
			
		||||
    } while (!component->can_proceed());
 | 
			
		||||
@@ -100,27 +105,7 @@ void Application::loop() {
 | 
			
		||||
  // Get the initial loop time at the start
 | 
			
		||||
  uint32_t last_op_end_time = millis();
 | 
			
		||||
 | 
			
		||||
  this->scheduler.call(last_op_end_time);
 | 
			
		||||
 | 
			
		||||
  // Feed WDT with time
 | 
			
		||||
  this->feed_wdt(last_op_end_time);
 | 
			
		||||
 | 
			
		||||
  // Process any pending enable_loop requests from ISRs
 | 
			
		||||
  // This must be done before marking in_loop_ = true to avoid race conditions
 | 
			
		||||
  if (this->has_pending_enable_loop_requests_) {
 | 
			
		||||
    // Clear flag BEFORE processing to avoid race condition
 | 
			
		||||
    // If ISR sets it during processing, we'll catch it next loop iteration
 | 
			
		||||
    // This is safe because:
 | 
			
		||||
    // 1. Each component has its own pending_enable_loop_ flag that we check
 | 
			
		||||
    // 2. If we can't process a component (wrong state), enable_pending_loops_()
 | 
			
		||||
    //    will set this flag back to true
 | 
			
		||||
    // 3. Any new ISR requests during processing will set the flag again
 | 
			
		||||
    this->has_pending_enable_loop_requests_ = false;
 | 
			
		||||
    this->enable_pending_loops_();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Mark that we're in the loop for safe reentrant modifications
 | 
			
		||||
  this->in_loop_ = true;
 | 
			
		||||
  this->before_loop_tasks_(last_op_end_time);
 | 
			
		||||
 | 
			
		||||
  for (this->current_loop_index_ = 0; this->current_loop_index_ < this->looping_components_active_end_;
 | 
			
		||||
       this->current_loop_index_++) {
 | 
			
		||||
@@ -141,7 +126,7 @@ void Application::loop() {
 | 
			
		||||
    this->feed_wdt(last_op_end_time);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this->in_loop_ = false;
 | 
			
		||||
  this->after_loop_tasks_();
 | 
			
		||||
  this->app_state_ = new_app_state;
 | 
			
		||||
 | 
			
		||||
#ifdef USE_RUNTIME_STATS
 | 
			
		||||
@@ -411,6 +396,36 @@ void Application::enable_pending_loops_() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Application::before_loop_tasks_(uint32_t loop_start_time) {
 | 
			
		||||
  // Process scheduled tasks
 | 
			
		||||
  this->scheduler.call(loop_start_time);
 | 
			
		||||
 | 
			
		||||
  // Feed the watchdog timer
 | 
			
		||||
  this->feed_wdt(loop_start_time);
 | 
			
		||||
 | 
			
		||||
  // Process any pending enable_loop requests from ISRs
 | 
			
		||||
  // This must be done before marking in_loop_ = true to avoid race conditions
 | 
			
		||||
  if (this->has_pending_enable_loop_requests_) {
 | 
			
		||||
    // Clear flag BEFORE processing to avoid race condition
 | 
			
		||||
    // If ISR sets it during processing, we'll catch it next loop iteration
 | 
			
		||||
    // This is safe because:
 | 
			
		||||
    // 1. Each component has its own pending_enable_loop_ flag that we check
 | 
			
		||||
    // 2. If we can't process a component (wrong state), enable_pending_loops_()
 | 
			
		||||
    //    will set this flag back to true
 | 
			
		||||
    // 3. Any new ISR requests during processing will set the flag again
 | 
			
		||||
    this->has_pending_enable_loop_requests_ = false;
 | 
			
		||||
    this->enable_pending_loops_();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Mark that we're in the loop for safe reentrant modifications
 | 
			
		||||
  this->in_loop_ = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Application::after_loop_tasks_() {
 | 
			
		||||
  // Clear the in_loop_ flag to indicate we're done processing components
 | 
			
		||||
  this->in_loop_ = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef USE_SOCKET_SELECT_SUPPORT
 | 
			
		||||
bool Application::register_socket_fd(int fd) {
 | 
			
		||||
  // WARNING: This function is NOT thread-safe and must only be called from the main loop
 | 
			
		||||
 
 | 
			
		||||
@@ -512,6 +512,8 @@ class Application {
 | 
			
		||||
  void enable_component_loop_(Component *component);
 | 
			
		||||
  void enable_pending_loops_();
 | 
			
		||||
  void activate_looping_component_(uint16_t index);
 | 
			
		||||
  void before_loop_tasks_(uint32_t loop_start_time);
 | 
			
		||||
  void after_loop_tasks_();
 | 
			
		||||
 | 
			
		||||
  void feed_wdt_arch_();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user