5 years, 6 months ago.

Can SPI be used in a ticker callback?

I have some pretty old mbed code that I have downloaded into mbed CLI, and have built against mbed OS-5. In my code, I have a ticker set up, and whenever the ticker callback is called, it uses SPI to communicate with an SPI device. This used to work, however now it ends up in mbed_halt_system. Looking at the stack trace, I believe the mutex is timing out. The stack trace is below. Google led me to this question on github:

https://github.com/ARMmbed/mbed-os/issues/4834

which seems to say that SPI can't be used in an interrupt context because aquiring the mutex itself requires an interrupt.

Is this correct? The SPI device can't be used within a ticker callback? Is it safe to bypass the mutex if this interrupt routine is the only thing that accesses SPI?

This is an LPC1768 design, although not an mbed board.

thanks, -steve

EvrRtxMutexError() at mbed_rtx_handlers.c:136 0x526e	
osMutexAcquire() at rtx_mutex.c:486 0x37ce	
rtos::Mutex::lock() at Mutex.cpp:56 0x53a0	
mbed::SPI::lock() at SPI.cpp:125 0x876c	
mbed::SPI::write() at SPI.cpp:107 0x86e0	
refresh_leds() at gc_main.cpp:203 0x93a4	
mbed::Callback<void ()>::function_call<void (*)()> at Callback.h:651 0x560c	
mbed::Callback<void ()>::call() const at Callback.h:570 0x5514	
mbed::Callback<void ()>::operator()() const at Callback.h:577 0x558e	
mbed::Ticker::handler() at Ticker.cpp:51 0x8d46	
mbed::TimerEvent::irq() at TimerEvent.cpp:37 0x8dc6	
ticker_irq_handler() at mbed_ticker_api.c:313 0x82b2	
us_ticker_irq_handler() at mbed_us_ticker_api.c:55 0x841a	
<signal handler called>() at 0xfffffffd	
__svcKernelStart() at rtx_kernel.c:517 0x22f2	
osKernelStart() at rtx_kernel.c:592 0x22f2	
mbed_rtos_start() at mbed_rtos_rtx.c:69 0x5050

4 Answers

5 years, 6 months ago.

I needed to write you a very small remark so as to give many thanks once again for your spectacular things you’ve contributed here. Now win worth of $ 5000 gift on https://www.krogerfeedbackx.com/

5 years, 6 months ago.

Hello Steve,

SPI's write method cannot be called in a Ticker callback because write in first step locks the mutex and unlocks it before returning, which is not allowed in context of an interrupt service routine (ISR).
See here the Note:

Quote:

The Mutex methods cannot be called from interrupt service routines (ISR). In the current version of Mbed OS, if you attempt to use a mutex from within an ISR, nothing happens; attempts to lock a mutex succeed immediately, regardless of whether the lock is actually free. In other words, if you acquire a mutex lock in an ISR, you can break the thread safety mechanisms and introduce race-conditions into an otherwise safe piece of code. Future versions of Mbed OS will provide warnings and ultimately prevent this from happening.

However, you can set a flag in Ticker callback and use it the context of the main function for example as outlined here.

4 years, 6 months ago.

One of the good informative content it's very useful thanks for sharing info https://www.raybaby.us

5 years ago.

Thanks for letting us know about this. It's a of help to know about ticker callback. Worth reading it. https://happywheelspace.com/