SPI transactions with interrupts

akhodakivskiy
Posts: 3
Joined: Fri Aug 11, 2023 8:25 am

SPI transactions with interrupts

Postby akhodakivskiy » Fri Aug 11, 2023 10:10 am

I'm programming a device using ESP32. The device uses SPI for control and raises interrupts on GPIO pins for feedback. I need to run SPI commands from the task context as well as the from ISR context. All SPI comm is wrapped into spi.beginTransaction / spi.endTransaction. In the task context SPI comm is additionally wrapped into noInterrupts / interrupts blocks. Once in a while a crash happens in spi.endTransaction as below. What can cause this?

Also what are best practices for SPI programming when interrupts are involved that I'm not aware of?

Thanks!

Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.

Core 1 register dump:
PC : 0x4008c1f5 PS : 0x00060f33 A0 : 0x8008b199 A1 : 0x3ffc7d80
A2 : 0x3ffb8c74 A3 : 0x3ffc50dc A4 : 0x00000004 A5 : 0x00060f23
A6 : 0x00060f23 A7 : 0x00000001 A8 : 0x00000000 A9 : 0x3ffb8c74
A10 : 0x3ffb8c74 A11 : 0x3ffc50dc A12 : 0x00000004 A13 : 0x00060f23
A14 : 0x007bf338 A15 : 0x003fffff SAR : 0x00000011 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000004 LBEG : 0x400872d4 LEND : 0x400872ea LCOUNT : 0x00000000


Backtrace: 0x4008c1f2:0x3ffc7d80 0x4008b196:0x3ffc7da0 0x40089f94:0x3ffc7dc0 0x400d25d1:0x3ffc7e00 0x400812e1:0x3ffc7e20 0x4008138d:0x3ffc7e40 0x400822f6:0x3ffc7e60 0x40081edd:0x3ffc7ef0 0x400d19c2:0x3ffc7f40

#0 0x4008c1f2:0x3ffc7d80 in uxListRemove at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/freertos/list.c:192
#1 0x4008b196:0x3ffc7da0 in xTaskRemoveFromEventList at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/freertos/tasks.c:3657
#2 0x40089f94:0x3ffc7dc0 in xQueueGenericSend at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/freertos/queue.c:883
#3 0x400d25d1:0x3ffc7e00 in SPIClass::endTransaction() at /Users/anton/.platformio/packages/framework-arduinoespressif32/libraries/SPI/src/SPI.cpp:194
...

MicroController
Posts: 1708
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: SPI transactions with interrupts

Postby MicroController » Sat Aug 12, 2023 6:38 pm

what are best practices for SPI programming when interrupts are involved that I'm not aware of?
Answer: Don't.
Never call potentially blocking APIs from an ISR.

The normal pattern is to have the ISR put a message e.g. into a queue and have a task to process the messages from the queue outside the ISR context; the task can then take any desired action, including making blocking calls.

"Best practice" is: Make ISRs return as quickly as possible.
And beyond best practice is the (FreeRTOS) requirement to not call (potentially) blocking APIs from an ISR.
One of the reasons for this is that when some code needs to block/wait the RTOS will put the task that's executing that code to its list of currently paused tasks, to be resumed later. An ISR is not a task and not run as part of a task. Thus, the RTOS cannot put the ISR into "pause" like a task.
Another reason is that while an ISR is executing other (lower-level) interrupts are usually disabled. If the ISR would come to wait for some event corresponding to one of those other interrupts, it would wait forever.

Who is online

Users browsing this forum: Bing [Bot], Majestic-12 [Bot], MicroController and 58 guests