Fix ISR safety: add IRAM_ATTR, remove ESP_LOG calls, add volatile

Co-authored-by: pmarchini <49943249+pmarchini@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-01-25 18:41:05 +00:00
parent c57271fc5c
commit aa284ddead

View File

@@ -33,7 +33,7 @@ typedef struct {
} example_queue_element_t; } example_queue_element_t;
/* Event queue for single-fire timer implementation */ /* Event queue for single-fire timer implementation */
static timer_event_t event_queue[MAX_TIMER_EVENTS]; static volatile timer_event_t event_queue[MAX_TIMER_EVENTS];
static volatile int event_queue_size = 0; static volatile int event_queue_size = 0;
static uint64_t alarm_interval_ticks = 0; // Calculated based on AC frequency (set by config_alarm) static uint64_t alarm_interval_ticks = 0; // Calculated based on AC frequency (set by config_alarm)
static uint64_t pulse_width_ticks = 0; // Pre-calculated pulse width in ticks (set by config_alarm) static uint64_t pulse_width_ticks = 0; // Pre-calculated pulse width in ticks (set by config_alarm)
@@ -79,7 +79,7 @@ static void init_event_queue(void)
* @brief Find the next event in queue (earliest timestamp) * @brief Find the next event in queue (earliest timestamp)
* @return Index of next event, or -1 if queue is empty * @return Index of next event, or -1 if queue is empty
*/ */
static int find_next_event_index(void) static int IRAM_ATTR find_next_event_index(void)
{ {
int next_idx = -1; int next_idx = -1;
uint64_t earliest_time = UINT64_MAX; uint64_t earliest_time = UINT64_MAX;
@@ -103,19 +103,19 @@ static int find_next_event_index(void)
* @param event_type Type of event (fire or end pulse) * @param event_type Type of event (fire or end pulse)
* @return true if event was scheduled, false if queue is full or invalid input * @return true if event was scheduled, false if queue is full or invalid input
*/ */
static bool schedule_timer_event(uint64_t timestamp, uint8_t dimmer_id, timer_event_type_t event_type) static bool IRAM_ATTR schedule_timer_event(uint64_t timestamp, uint8_t dimmer_id, timer_event_type_t event_type)
{ {
// Validate dimmer_id to prevent array bounds violations // Validate dimmer_id to prevent array bounds violations
if (dimmer_id >= ALL_DIMMERS) if (dimmer_id >= ALL_DIMMERS)
{ {
ESP_LOGE(TAG, "Invalid dimmer_id: %d (max: %d)", dimmer_id, ALL_DIMMERS - 1); // Cannot use ESP_LOGE in ISR - silently fail
return false; return false;
} }
// Validate event_type // Validate event_type
if (event_type != EVENT_FIRE_TRIAC && event_type != EVENT_END_PULSE) if (event_type != EVENT_FIRE_TRIAC && event_type != EVENT_END_PULSE)
{ {
ESP_LOGE(TAG, "Invalid event_type: %d", event_type); // Cannot use ESP_LOGE in ISR - silently fail
return false; return false;
} }
@@ -133,8 +133,7 @@ static bool schedule_timer_event(uint64_t timestamp, uint8_t dimmer_id, timer_ev
} }
} }
// Queue is full // Queue is full - cannot use ESP_LOGE in ISR
ESP_LOGE(TAG, "Event queue full!");
return false; return false;
} }
@@ -142,7 +141,7 @@ static bool schedule_timer_event(uint64_t timestamp, uint8_t dimmer_id, timer_ev
* @brief Remove an event from the queue * @brief Remove an event from the queue
* @param index Index of event to remove * @param index Index of event to remove
*/ */
static void remove_event(int index) static void IRAM_ATTR remove_event(int index)
{ {
if (index >= 0 && index < MAX_TIMER_EVENTS && event_queue[index].active) if (index >= 0 && index < MAX_TIMER_EVENTS && event_queue[index].active)
{ {
@@ -518,10 +517,10 @@ static void IRAM_ATTR onTimerISR(void *para)
// If scheduling failed, turn off triac immediately // If scheduling failed, turn off triac immediately
// to prevent it staying on // to prevent it staying on
// Cannot use ESP_LOGE in ISR - silently handle error
if (!scheduled) if (!scheduled)
{ {
gpio_set_level(dimOutPin[event->dimmer_id], 0); gpio_set_level(dimOutPin[event->dimmer_id], 0);
ESP_LOGE(TAG, "Failed to schedule pulse end for dimmer %d", event->dimmer_id);
} }
} }
else if (event->event_type == EVENT_END_PULSE) else if (event->event_type == EVENT_END_PULSE)
@@ -530,10 +529,7 @@ static void IRAM_ATTR onTimerISR(void *para)
gpio_set_level(dimOutPin[event->dimmer_id], 0); gpio_set_level(dimOutPin[event->dimmer_id], 0);
} }
} }
else // Silently ignore invalid dimmer_id - cannot use ESP_LOGE in ISR
{
ESP_LOGE(TAG, "Invalid dimmer_id in event: %d", event->dimmer_id);
}
// Remove processed event // Remove processed event
remove_event(i); remove_event(i);