Timer interrupt and WiFi events dont work together

Hello guys,

I am taking advantage of the time at home to play with my ESP32. But I ran into a problem.

I am making a program with WiFi events and interrupt with timer. The programs individually work well but when joining them the program shows the following error and restarts all the time.

Guru Meditation Error: Core 1 panic’ed (Cache disabled but cached memory region accessed)
Core 1 register dump:
PC : 0x400d10bc PS : 0x00060034 A0 : 0x80081048 A1 : 0x3ffbe790
A2 : 0x3ffbec00 A3 : 0x20000000 A4 : 0x00000400 A5 : 0x3ffbe790
A6 : 0x3ffbe7d8 A7 : 0x00000001 A8 : 0x80080f4d A9 : 0x00000001
A10 : 0x00060223 A11 : 0x00000000 A12 : 0x8008a40b A13 : 0x3ffbe760
A14 : 0x00000008 A15 : 0x00000001 SAR : 0x0000001e EXCCAUSE: 0x00000007
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
Core 1 was running in ISR context:
EPC1 : 0x40086ab9 EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x400d10bc
Backtrace: 0x400d10bc:0x3ffbe790 0x40081045:0x3ffbe7b0 0x40084809:0x3ffbe7d0 0x40086ab6:0x3ffba190 0x40082c23:0x3ffba1b0 0x40088c15:0x3ffba1d0

and my test program is as follows

#include <Arduino.h>
#include <WiFi.h>

const char* ssid = “yourNetworkName”;
const char* password = “yourNetworkPass”;
hw_timer_t * timer = NULL;
uint32_t cnt=0;

void test();
void IRAM_ATTR onTimer();
void WiFiEvent(WiFiEvent_t event);

void setup()
{
Serial.begin(115200);

timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &onTimer, true);
timerAlarmWrite(timer, 1358, true);
timerAlarmEnable(timer);

WiFi.onEvent(WiFiEvent);
WiFi.begin(ssid, password);
}

void loop(){}

void test(){cnt++;}

void IRAM_ATTR onTimer() {
test();
}

void WiFiEvent(WiFiEvent_t event){
Serial.printf(“[WiFi-event] event: %d\n”, event);
switch (event){ //Obtiene evento wifi
case SYSTEM_EVENT_WIFI_READY:
Serial.println(“WiFi interface ready”);
break;
case SYSTEM_EVENT_SCAN_DONE:
Serial.println(“Completed scan for access points”);
break;
case SYSTEM_EVENT_STA_START:
Serial.println(“WiFi client started”);
break;
case SYSTEM_EVENT_STA_STOP:
Serial.println(“WiFi clients stopped”);
break;
case SYSTEM_EVENT_STA_CONNECTED:
Serial.println(“Connected to access point”);
break;
case SYSTEM_EVENT_STA_DISCONNECTED: //Evento de desconexión STA
Serial.println(“Disconnected from WiFi access point”);
break;
case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
Serial.println(“Authentication mode of access point has changed”);
break;
case SYSTEM_EVENT_STA_GOT_IP:
Serial.print("Obtained IP address: ");
Serial.println(WiFi.localIP());
break;
case SYSTEM_EVENT_STA_LOST_IP:
Serial.println(“Lost IP address and IP address is reset to 0”);
break;
case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
Serial.println(“WiFi Protected Setup (WPS): succeeded in enrollee mode”);
break;
case SYSTEM_EVENT_STA_WPS_ER_FAILED:
Serial.println(“WiFi Protected Setup (WPS): failed in enrollee mode”);
break;
case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT:
Serial.println(“WiFi Protected Setup (WPS): timeout in enrollee mode”);
break;
case SYSTEM_EVENT_STA_WPS_ER_PIN:
Serial.println(“WiFi Protected Setup (WPS): pin code in enrollee mode”);
break;
case SYSTEM_EVENT_AP_START:
Serial.println(“WiFi access point started”);
break;
case SYSTEM_EVENT_AP_STOP:
Serial.println(“WiFi access point stopped”);
break;
case SYSTEM_EVENT_AP_STACONNECTED:
Serial.println(“Client connected”);
break;
case SYSTEM_EVENT_AP_STADISCONNECTED:
Serial.println(“Client disconnected”);
break;
case SYSTEM_EVENT_AP_STAIPASSIGNED:
Serial.println(“Assigned IP address to client”);
break;
case SYSTEM_EVENT_AP_PROBEREQRECVED:
Serial.println(“Received probe request”);
break;
case SYSTEM_EVENT_GOT_IP6:
Serial.println(“IPv6 is preferred”);
break;
case SYSTEM_EVENT_ETH_START:
Serial.println(“Ethernet started”);
break;
case SYSTEM_EVENT_ETH_STOP:
Serial.println(“Ethernet stopped”);
break;
case SYSTEM_EVENT_ETH_CONNECTED:
Serial.println(“Ethernet connected”);
break;
case SYSTEM_EVENT_ETH_DISCONNECTED:
Serial.println(“Ethernet disconnected”);
break;
case SYSTEM_EVENT_ETH_GOT_IP:
Serial.println(“Obtained IP address”);
break;
default:
break;
}
}

is there any way to fix it?

Thanks :smiley:

void test(){cnt++;}

void IRAM_ATTR onTimer() {
test();
}

Your onTimer function is called during an ISR, so putting it into IRAM_ATTR is mandatory to place into instruction RAM. You did that and that’s fine. But then you call test() which is located in flash → boom, crash. Just place it in IRAM too.

2 Likes

Hi @maxgerhardt :smiley:

I already tried it as you mention and it works correctly. Thanks a lot.

Just one doubt. Is it possible to put the IRAM_ATTR attribute in a method of a class?

Regards

I don’t see why that would not be possible. Do you have any specific error?

@maxgerhardt Hi, i saw this chat and I have a similar problem with the ESP32.

But I could not find a solution here.

I use wifi events and a timer for control of a PxMatrix

the timer code looks like:

#if defined (ESP32)
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
#endif

#if defined (ESP32)
void IRAM_ATTR display_updater() {
  // Increment the counter and set the time of ISR
  portENTER_CRITICAL_ISR(&timerMux);
  // Call PXMatrix display method 
  display.display(display_draw_time);
  portEXIT_CRITICAL_ISR(&timerMux);
}
#endif


void display_update_enable(bool is_enable) {
  if (is_enable)
  {
    timer = timerBegin(0, 80, true);
    timerAttachInterrupt(timer, &display_updater, true);
    timerAlarmWrite(timer, 4000, true);
    timerAlarmEnable(timer);
  }
  else
  {
    timerDetachInterrupt(timer);
    timerAlarmDisable(timer);
  }
}

The wifi event should detect disconnected

// define wifi event when diconnected
  WiFi.onEvent([] (WiFiEvent_t event, WiFiEventInfo_t info) -> void {
      DBG__PRINT("\n\nSTA disconnected!");
      DBG__PRINT("STA disonnected reason: ", "");
      DBG__PRINT(info.wifi_sta_disconnected.reason);
      DBG__PRINT("WiFi reason name: ", "");
      DBG__PRINT(WiFi.disconnectReasonName(static_cast<wifi_err_reason_t>(info.wifi_sta_disconnected.reason)));
      WiFi.disconnect();
      is_connected = false;
  }, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);

If I now activate the timer at end of setup() => display_update_enable(true); and a wifi disconnected event occurs the ESP32 crashes like:

Could you give an hint to solve?

If I did not activate the timer => //display_update_enable(true);
So comment this line, every thing is fine and no crash occurs.

Does this reproduce in the Arduino IDE too? If yes, it’s not PlatformIO specific and you can use the Espressif people as resource. https://github.com/espressif/arduino-esp32/issues.

Hi Max,

in meanwhile I found the issue… :slight_smile :slight_smile:

The display… call in the ISR,
takes too long and crashes together then when the wifi event occurs.
display.display(display_draw_time);
See above.