I have piece of code that after running a few hours (3-5 hours) gives me the above kernel panic "Guru Meditation Error: Cache disabled but cached memory region accessed" . The callstack does not tell me anything (it doesn't dump much).
This is the culprit code (if I remove digitalWrite from timer ISR it no longer crashes, but that could be because the whole code gets optimized and doesn't execute).
- #pragma once
- #include <Settings.h>
- DRAM_ATTR volatile unsigned long long inctimer = 0;
- DRAM_ATTR volatile bool onlyLow = false;
- DRAM_ATTR volatile unsigned char g_state = 0;
- DRAM_ATTR volatile const unsigned long long divizor = 10;
- DRAM_ATTR volatile unsigned long startZCMicros = 0;
- DRAM_ATTR volatile unsigned long long intervalZCMicros = 10000/divizor; // 50 hz
- DRAM_ATTR volatile unsigned long long pulseLengthMicros = 300/divizor;
- DRAM_ATTR volatile unsigned long long pulseBeginMicros = LONG_MAX;
- DRAM_ATTR volatile unsigned long long pulseOffsetZCMicros = LONG_MAX;
- void IRAM_ATTR OnTimerHeater()
- {
- if(onlyLow)
- {
- digitalWrite(CONTROL_PIN, LOW);
- return;
- }
- volatile long currentMicros = micros()/divizor;
- volatile long localPulseBeginMicros = pulseBeginMicros + pulseOffsetZCMicros;
- volatile long localPulseEndMicros = pulseBeginMicros + pulseOffsetZCMicros + pulseLengthMicros;
- if(currentMicros >= localPulseEndMicros)
- {
- digitalWrite(CONTROL_PIN, LOW);
- }
- else if(currentMicros >= localPulseBeginMicros)
- {
- digitalWrite(CONTROL_PIN, HIGH);
- }
- }
- void IRAM_ATTR OnZeroCrossHeater()
- {
- volatile const long current_micros = micros()/divizor;
- volatile int i = 0;
- if(digitalRead(ZERO_CROSS_PIN) == LOW)
- {
- for (; i < 1000; ++i) {}
- if(digitalRead(ZERO_CROSS_PIN) == HIGH)
- {
- return;
- }
- }
- else
- {
- return;
- }
- if(current_micros - startZCMicros < 100)
- {
- return;
- }
- switch(g_state)
- {
- case 0:
- startZCMicros = current_micros;
- break;
- case 1:
- intervalZCMicros = current_micros - startZCMicros;
- break;
- }
- g_state++;
- if(g_state > 1)
- {
- g_state = 0;
- }
- if(intervalZCMicros != -1)
- {
- pulseBeginMicros = current_micros;
- }
- }
- class Heater
- {
- double m_prev_value = 0.0;
- hw_timer_t* m_timer = nullptr;
- public:
- Heater()
- {
- }
- void setup()
- {
- pinMode(CONTROL_PIN, OUTPUT);
- pinMode(ZERO_CROSS_PIN, INPUT_PULLUP);
- digitalWrite(CONTROL_PIN, LOW);
- m_timer = timerBegin(0, 80 * divizor, true);
- // per microsecond
- timerAttachInterrupt(m_timer, &OnTimerHeater, true);
- timerAlarmWrite(m_timer, 1, true);
- timerAlarmEnable(m_timer);
- attachInterrupt(ZERO_CROSS_PIN, OnZeroCrossHeater, RISING);
- }
- void set(double value)
- {
- if(value > 50.0)
- {
- value = 50.0;
- }
- if(value < 0.0)
- {
- value = 0.0;
- }
- unsigned long long localinterval = intervalZCMicros;
- if(m_prev_value == value)
- {
- return;
- }
- unsigned long long localCalculation = 0;
- if(abs(value) < 0.01 )
- {
- localCalculation = LONG_MAX;
- onlyLow = true;
- }
- else
- {
- onlyLow = false;
- localCalculation = (long long)((100.0 - value) * 0.01 * localinterval) - pulseLengthMicros;
- }
- if(localCalculation < 0)
- {
- localCalculation = 0;
- }
- pulseOffsetZCMicros = localCalculation;
- Serial.print("heating with ");
- Serial.print(value);
- Serial.println("--");
- m_prev_value = value;
- }
- void loop()
- {
- }
- };
Cheers,
Radu