ESP32: SimpleFIFO.h verursacht in ISR einen Reboot beim Schreiben ins EEPROM

Hallo,

ich habe einen sketch, bei dem ich mit einem cc1101 ASK/OOK Signale empfange.
Dabei löst jede Pulsflanke an GDO2 einen Interrupt aus. In der Interruptroutine werden die Pulsedauer in einen Fifo geschrieben.
Wenn beim ESP32 während dem Schreiben ins EEPROM die Interruptroutine aufgerufen wird, dann bekomme ich im Serial Monitor die folgende Fehlermeldung:

Guru Meditation Error: Core  1 panic'ed (Cache disabled but cached memory region accessed)
....
Core 1 was running in ISR context:
....
Rebooting...

Ich konnte es auf die SimpleFIFO.h eingrenzen
SimpleFIFO.h

Im Hauptsketch steht u.a. folgendes:

#define FIFO_LENGTH            170
SimpleFIFO<int16_t,FIFO_LENGTH> FiFoB;
volatile unsigned long lastTimeB = micros();
...
attachInterrupt(digitalPinToInterrupt(PIN_RECEIVE_B), handleInterruptB, CHANGE);
...
  void IRAM_ATTR handleInterruptB() {
  cli();
  const unsigned long Time=micros();
  const unsigned long  duration = Time - lastTimeB;
  lastTimeB = Time;
  if (duration >= pulseMin) {//kleinste zulaessige Pulslaenge
	int16_t sDuration;
    if (duration < maxPulse) {//groesste zulaessige Pulslaenge, max = 32000
      sDuration = int16_t(duration); //das wirft bereits hier unnoetige Nullen raus und vergroessert den Wertebereich
    }else {
      sDuration = maxPulse; // Maximalwert set to maxPulse defined in lib.
    }
    if (isHigh(PIN_RECEIVE_B)) { // Wenn jetzt high ist, dann muss vorher low gewesen sein, und dafuer gilt die gemessene Dauer.
      sDuration=-sDuration;
    }
    FiFoB.enqueue(sDuration);
  } // else => trash
  sei();
}

Die SimpleFIFO_h habe ich auch angepasst:

template<typename T, int16_t rawSize>
bool IRAM_ATTR SimpleFIFO<T,rawSize>::enqueue( T element ) {
	if ( numberOfElements >= rawSize ) { return false; }
	numberOfElements++;
	nextIn %= size;
	raw[nextIn] = element;
	nextIn++; //advance to next index
	return true;
}

Dies ist aber noch nicht ausreichend, ich habe das Problem, daß ich nicht den kompletten Code der SimpleFIFO.h verstehe.
Mir ist nicht klar wie in der SimpleFIFO.h die übergebende FIFO_LENGTH in size und rawSize übergeben wird?
Ist size evtl im flash da es eine "const" ist?

template<typename T, int16_t rawSize>
SimpleFIFO<T,rawSize>::SimpleFIFO() : size(rawSize) {
	flush();
}

Gruß Ralf

Warum benutzt du nicht die RTOS Queues?

Warum benutzt du nicht die RTOS Queues?

Ist mir zu aufwändig, der sketch funktioniert momentan auf dem MapleMini.
Ich möchte ihn so anpassen, damit er auch auf dem ESP32 funktioniert

Na dann viel Spaß beim Neuerfinden des Rades.

Seitdem ich die templates aus der class entfernt habe, habe ich beim Schreiben ins EEPROM keine reboots mehr.
Gibts auch ohne templates eine Möglichkeit die Dimension vom array rawFifo zu übergeben?

Hauptsketch:

define FIFO_LENGTH            200
SimpleFIFO FiFo(FIFO_LENGTH);

SimpleFIFO_h

#pragma once

#ifndef SimpleFIFO_h
#define SimpleFIFO_h
#include <Arduino.h>
/*
||
|| @file 		SimpleFIFO.h
|| @version 	1.2
|| @author 	Alexander Brevig
|| @contact 	alexanderbrevig@gmail.com
||
|| @description
|| | A simple FIFO class, mostly for primitive types but can be used with classes if assignment to int is allowed
|| | This FIFO is not dynamic, so be sure to choose an appropriate size for it
|| #
||
|| @license
|| | Copyright (c) 2010 Alexander Brevig
|| | This library is free software; you can redistribute it and/or
|| | modify it under the terms of the GNU Lesser General Public
|| | License as published by the Free Software Foundation; version
|| | 2.1 of the License.
|| |
|| | This library is distributed in the hope that it will be useful,
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
|| | Lesser General Public License for more details.
|| |
|| | You should have received a copy of the GNU Lesser General Public
|| | License along with this library; if not, write to the Free Software
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
|| #
||
*/

#define FIFO_LENGTH            200

class SimpleFIFO {
public:

	SimpleFIFO(uint8_t rawsize);

	int16_t dequeue();				//get next element
	void IRAM_ATTR enqueue(int16_t element );	//add an element
	void flush();				//[1.1] reset to default state 
	
	uint8_t count() { return numberOfElements; }

private:
  uint8_t size;
  volatile uint8_t numberOfElements = 0;
  volatile uint8_t nextIn = 0;
  volatile uint8_t nextOut = 0;
  volatile int16_t rawFifo[FIFO_LENGTH];
};

SimpleFIFO::SimpleFIFO(uint8_t rawsize)
{
	size = rawsize; // configured size
	flush();
}

void IRAM_ATTR SimpleFIFO::enqueue(int16_t element) {
	if ( numberOfElements >=  size) { return; }
	numberOfElements++;
	nextIn %= size;
	rawFifo[nextIn] = element;
	nextIn++;
	return;
}

int16_t SimpleFIFO::dequeue() {
	numberOfElements--;
	nextOut %= size;
	return rawFifo[nextOut++];
}

void SimpleFIFO::flush() {
	nextIn = nextOut = numberOfElements = 0;
}

#endif

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