ESP32 crashes when reading RTC in task?

I'm getting a crash when I try to read from an RTC (via GitHub - adafruit/RTClib: A fork of Jeelab's fantastic RTC Arduino library) inside a FreeRTOS task. This code, specifically the "rtc.lostPower()" crashes the esp32 but only when used inside a task created by xTaskCreatePinnedToCore. If I put that same code in "loop()" it runs fine.

#include <RTClib.h>
RTC_DS3231 rtc;
const byte RTC_pin = 34;

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

    if (!rtc.begin()) {
        Serial.println("Couldn't find RTC");
        Serial.flush();
        abort();
    }
    rtc.disable32K();
    pinMode(RTC_pin, INPUT);
    attachInterrupt(digitalPinToInterrupt(RTC_pin), RTCAlarmHandler, FALLING);
    rtc.writeSqwPinMode(DS3231_SquareWave1Hz);
    disableCore0WDT();
    xTaskCreatePinnedToCore(clockTask, "ClockTask", 10000, NULL, 20, NULL, 0);
}

void clockTask(void *pvParameters) {
    for (;;) {
        delayMicroseconds(250);
        if (rtc.lostPower()) {
            Serial.println('lost power');
        }
    }
}

void loop() {
    delay(1000);
}

This is the error message on the crash:

Guru Meditation Error: Core  0 panic'ed (StoreProhibited). Exception was unhandled.
Core 0 register dump:
PC      : 0x40089252  PS      : 0x00050033  A0      : 0x4008915b  A1      : 0x3ffce570  
A2      : 0x00000000  A3      : 0x00000000  A4      : 0x00000001  A5      : 0x400890dc  
A6      : 0x3ff000dc  A7      : 0x00000001  A8      : 0x80083cf1  A9      : 0x3ffbe9e0  
A10     : 0x3ffbf014  A11     : 0x00000001  A12     : 0x00000001  A13     : 0x00000001  
A14     : 0x00060021  A15     : 0x00000000  SAR     : 0x00000014  EXCCAUSE: 0x0000001d  
EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0x00000000  

ELF file SHA256: 0000000000000000

Backtrace: 0x40089252:0x3ffce570 0x40089158:0x3ffce580

Is reading from an i2c bus not allowed inside a task?

IIRC, the interrupts used for an I2C interface are associated with a specific core when you call Wire.begin(). You cannot use it from a different core afterwards. Make sure you initialize your I2C interface etc. in the same task (pinned to a core) that you'll be using the RTC in.

You'll probably want to synchronize things like Serial.print with a mutex if you're going to use it from multiple tasks. Similarly, all data shared between tasks should either be atomic variables (see std::atomic), or protected by a mutex.

Always post the decoded stack trace, the binary stack trace is useless without the binary. See GitHub - me-no-dev/EspExceptionDecoder: Exception Stack Trace Decoder for ESP8266 and ESP32.

Serial.println('lost power'); is incorrect, use double quotes for strings, single quotes for a single character.

Pieter

1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.