Guru Meditation Error in `task_MCPCAN`
driftregion opened this issue · 2 comments
I wrote a callback function for CANCOMMON.setGeneralCallback
. It forwards specific frames from one CAN bus to another. The base case looks like this:
void forward_frame(CAN_FRAME *frame)
{
if (frame->id == 0xbaa)
{
CAN0.sendFrame(*frame);
}
}
...
CAN1.setGeneralCallback(&forward_frame);
This works fine when forwarding frames from CAN1 (MCP) to CAN0 (native). However, when forwarding frames in the other direction, I get the following traceback reported over serial:
(Note: no CAN id's are forwarded in BOTH directions, so I'm fairly certain this isn't the result of an infinite loopback)
Guru Meditation Error: Core 0 panic'ed (InstrFetchProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x00000000 PS : 0x00060e30 A0 : 0x800d7aa4 A1 : 0x3ffdcd20
A2 : 0x00000000 A3 : 0x3ffdcd60 A4 : 0x3ffc45ec A5 : 0x00000000
A6 : 0x3ffe6544 A7 : 0x00060623 A8 : 0x800d7a5f A9 : 0x00000001
A10 : 0x3ffdcd60 A11 : 0xffffffff A12 : 0xffffffff A13 : 0x00000001
A14 : 0x00060e20 A15 : 0x00000000 SAR : 0x00000000 EXCCAUSE: 0x00000014
EXCVADDR: 0x00000000 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0x00000000
Backtrace: 0x00000000:0x3ffdcd20 0x400d7aa1:0x3ffdcd60 0x400888b5:0x3ffdcfa0
Here, decoded with EspExceptionDecoder:
PC: 0x00000000
EXCVADDR: 0x00000000
Decoding stack results
0x400d7aa1: task_MCPCAN(void*) at /home/n/Arduino/libraries/esp32_can/src/mcp2517fd.cpp line 108
0x400888b5: vPortTaskWrapper at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/port.c line 143
got it:
sendCallback is aborting because there is no callback specified for that mailbox, only a general callback. I got this to work as (i) expected it would by making the following change:
void MCP2517FD::sendCallback(CAN_FRAME_FD *frame)
{
//frame buffer
CANListener *thisListener;
int mb;
int idx;
CAN_FRAME stdFrame;
bool isFD = false;
if (!fdToCan(*frame, stdFrame)) isFD = true;
mb = (frame->fid & 0xFF);
if (mb == 0xFF) mb = -1;
if (frame->fid & 0x80000000ul) //object callback
{
idx = (frame->fid >> 24) & 0x7F;
thisListener = listener[idx];
if (isFD) thisListener->gotFrameFD(frame, mb);
else thisListener->gotFrame(&stdFrame, mb);
}
else //C function callback
{
(*cbGeneral)(&stdFrame);
// if (isFD)
// {
// if (mb > -1) (*cbCANFrameFD[mb])(frame);
// else (*cbGeneralFD)(frame);
// }
// else
// {
// if (mb > -1) (*cbCANFrame[mb])(&stdFrame);
// else (*cbGeneral)(&stdFrame);
// }
}
}
@collin80 , I'm closing this because I've found my mistake.
I'd like to ask: what is the intended use of a mailbox callback?
The intended use is to allow people to get targeted messages straight to a function without needing to do anything else. For instance, one might create a filter that allows a specific power train message through, say id 0x11D. With a mailbox callback you can set the library to immediately call a function in your program when 0x11D messages come in. This is just a convenience thing as obviously otherwise you could read incoming can frames and use switch/case or if blocks to process messages based on their ID.