Guru Meditation Error: Cache disabled but cached memory region accessed
Posted: Mon Jun 10, 2019 5:06 am
Hello,
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).
I researched the problem but I can't understand what is the cache that is accessed.. I made everything volatile and in DRAM... (I don't use SPI , only I2C)
Cheers,
Radu
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).
Code: Untitled.cpp Select all
#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