1
\$\begingroup\$

I've been trying to use spi.write() in a Ticker function, but the following error is thrown out onto the serial line:

Code: 324 Module: 255
Error Message: Assertion failed: _id
Location: 0xCE97
File: /extras/mbed-os.lib/rtos/Mutex.cpp+51
Error Value: 0x0
Current Thread: rtx_idle Id: 0x1000037C Entry: 0xF117 StackSize: 0x200 StackMem: 0x10000408 SP: 0x10007F30
For more info, visit: https://armmbed.github.io/mbedos-error/?error=0x80FF0144
-- MbedOS Error Info --

I'm now starting to wonder whether mbed's SPI is non-reentrant.

If so, what are my options? Not using Ticker would involve a lot of code being re-written, which I really don't want to do. If I use the internal LPC1768 SPI registers instead of the mbed SPI class, would the problem go away?

Dave Tweed
184k17 gold badges248 silver badges431 bronze badges
asked Jun 2, 2019 at 18:14
\$\endgroup\$
2
  • \$\begingroup\$ Note that if you do visit that URL, it says that this particular error code is undefined. \$\endgroup\$ Commented Jun 2, 2019 at 20:01
  • \$\begingroup\$ @DaveTweed, yes I noticed that. \$\endgroup\$ Commented Jun 2, 2019 at 20:26

2 Answers 2

2
\$\begingroup\$

Mutexes cannot be acquired in an ISR context, and the SPI write function requires one. An easy way around would be to use an EventQueue to defer the operation to the main thread. Barely any code change required.

answered Jun 2, 2019 at 20:56
\$\endgroup\$
5
  • \$\begingroup\$ The problem is that I have TCP recv calls in main which block. Would this get in the way? I really need the SPI to write every tick of the Ticker. \$\endgroup\$ Commented Jun 3, 2019 at 17:31
  • \$\begingroup\$ Start a second thread with priority osPriorityRealtime. Then defer from ISR to that thread. Then you can keep your main thread code unchanged. \$\endgroup\$ Commented Jun 4, 2019 at 9:37
  • \$\begingroup\$ Would I start the thread in main? \$\endgroup\$ Commented Jun 4, 2019 at 16:48
  • \$\begingroup\$ Could you please provide a code example? \$\endgroup\$ Commented Jun 4, 2019 at 18:28
  • \$\begingroup\$ I've asked a new question with some example code: electronics.stackexchange.com/questions/441943/… \$\endgroup\$ Commented Jun 8, 2019 at 12:27
0
\$\begingroup\$

I'm now starting to wonder whether mbed's SPI is non-reentrant.

Browsing the source code, it definitely is not. spi.write() ends up calling spi_master_write() in the file mbed-os/targets/TARGET_NXP/TARGET_LPC176X/spi_api.c. Nowhere along the way that I can see is there any attempt to serialize accesses to the hardware.

The documentation says that the API is thread-safe, and it appears to be true. In embed-os/drivers/SPI.ccp, the code is essentially

int SPI::write(...)
{
 select();
 int ret = spi_master_[block_]write(...);
 deselect();
 return ret;
}

In order for this to be thread-safe, there would have to be a mutex around the first three statements. The select() function calls lock() as its first statement and the deselect() function calls unlock() as its final statement. But that still doesn't mean that it can be called from both interrupt and non-interrupt code.

To be safe, you'll have to add such protection at the application level. Specifically, disable interrupts when accessing the SPI controller in non-interrupt code.

How many different threads do you have, and how many SPI slaves do have connected?

If I use the internal LPC1768 SPI registers instead of the mbed SPI class, would the problem go away?

No, you'd still need to add protection among the various users of the SPI hardware.

answered Jun 2, 2019 at 20:26
\$\endgroup\$
3
  • \$\begingroup\$ I'm only using one thread, and one SPI slave. \$\endgroup\$ Commented Jun 2, 2019 at 21:08
  • \$\begingroup\$ could you please clarify what you mean by "add protection"? \$\endgroup\$ Commented Jun 17, 2019 at 21:05
  • \$\begingroup\$ How about using EventQueue as Jan suggested, and defer the SPI_write call to another thread? \$\endgroup\$ Commented Jun 17, 2019 at 21:16

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.