Calling invoke() encounters Guru Meditation Error on esp32
Closed this issue · 5 comments
I am currently working with your program and encountered a Guru Meditation Error after adding logging to the TfLiteStatus MicroInterpreterGraph::InvokeSubgraph(int subgraph_idx) function, specifically in the line:
TfLiteStatus MicroInterpreterGraph::InvokeSubgraph(int subgraph_idx) {
....
TfLiteStatus invoke_status = registration->invoke(context_, node);
....
}
Guru Meditation Error: Core 0 panic'ed (InstructionFetchError). Exception was unhandled.
Core 0 register dump:
PC : 0x3ffb6b3d PS : 0x00060f30 A0 : 0x80140e3d A1 : 0x3ffe2890
A2 : 0x3ffc6ed8 A3 : 0x00000000 A4 : 0x3ffd483c A5 : 0x3ffe2760
A6 : 0x00000000 A7 : 0x0000000b A8 : 0x801411c1 A9 : 0x00000000
A10 : 0x3ffc6e70 A11 : 0x3ffd483c A12 : 0x00000001 A13 : 0x00000000
A14 : 0x3ffb6884 A15 : 0x00000001 SAR : 0x00000004 EXCCAUSE: 0x00000002
EXCVADDR: 0x3ffb6b3c LBEG : 0x400899c0 LEND : 0x400899d6 LCOUNT : 0x00000000
Backtrace: 0x3ffb6b3a:0x3ffe2890 |<-CORRUPTED
I believe the error might be related to the function pointer registration->invoke, which seems to be pointing to an address that is causing the InstructionFetchError. However, I'm not entirely sure how to proceed with debugging this issue.
Could you please offer any advice on how to troubleshoot this problem? Have you encountered similar issues in your experience?
Thank you very much for your assistance and guidance. I greatly appreciate your help!
I don't understand what you're doing:
- which topology does your network has?
- how did you add logging?
- are you using TF directly or throughout EloquentTinyML library?
I'm sorry, I didn't make myself clear.
- After converting the CNN to TFLite, open it with netron.app to see: input, ExpandDims, Conv2D, Reshape, MaxPool2D, ReduceMax and FullyConnected Layer.

And I added the opresolver to the code.

2.Regarding the issue, I added printf() statements directly inside the Invoke() function to trace the execution step by step. The error appeared when I reached this line of code:
TfLiteStatus invoke_status = registration->invoke(context_, node);
The program printed the error right after this line, indicating that something might be going wrong with the function pointer or the invocation process.
- I’m only using the tflm_esp32 library available on PlatformIO.
The environment is
platformIO ver. = 6.1.15
Platform = espressif32
Espressif 32 version = 6.8.1
Board = esp32doit-devkit-v1
Framework = arduino
library = eloquentarduino/tflm_esp32@^2.0.0
Modeling:
def Build1DCNN(input_shape, classes):
# Initialize the model
model = models.Sequential()
model.add(Input(shape=input_shape))
# First convolutional layer
model.add(Conv1D(filters=16, kernel_size=5, activation="relu"))
model.add(MaxPooling1D(2)) # default pool_size=2
# Second convolutional layer
model.add(Conv1D(filters=32, kernel_size=3, activation="relu"))
model.add(GlobalMaxPooling1D())
# Dropout layer
model.add(Dropout(0.3))
# Dense (fully connected) layer
model.add(Dense(classes))
return model
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv1d (Conv1D) (None, 116, 16) 496
max_pooling1d (MaxPooling1 (None, 58, 16) 0
D)
conv1d_1 (Conv1D) (None, 56, 32) 1568
global_max_pooling1d (Glob (None, 32) 0
alMaxPooling1D)
dropout (Dropout) (None, 32) 0
dense (Dense) (None, 2) 66
=================================================================
Total params: 2130 (8.32 KB)
Trainable params: 2130 (8.32 KB)
Non-trainable params: 0 (0.00 Byte)
_________________________________________________________________
Converting the TFLM:
import tensorflow as tf
import pathlib, os
from tinymlgen import port
modelPath = "Loss_Best_1DCNN_model_120"
converter = tf.lite.TFLiteConverter.from_saved_model(modelPath) # path to the SavedModel directory
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.float32]
tflite_model = converter.convert()
saved_model_loaded = tf.saved_model.load(modelPath)
# Use tinymlgen to convert the model to C code
c_code = port(saved_model_loaded, optimize=True, pretty_print=True, variable_name="model_p")
open("quant_f32_port.h", "w").write(c_code)
Here's the list of supported operators: https://github.com/eloquentarduino/tflm_esp32/blob/5fe67df0264113863fa54997924e20b01df31318/src/tensorflow/lite/micro/micro_mutable_op_resolver.h
Conv1D and GlobalMaxPooling1D are not supported. These days, coincidentally, I was thinking of using a Conv2D with shape 1 x N as an hack to emulate Conv1D, you may try that. As for the GlobalMaxPooling, you can replace it with a MaxPooling of the correct shape, I guess.