After playing with it a bit, it seems like wrapping all my SD card / SPI operations in SINGLE_THREADED_SECTIONs effectively minimizes the issue. While I can’t guarantee that it solves it, it seems to statistically reduce the chances of the conflict enough to be effectively zero, even in high stress corner cases. The timing seems to be acceptable for my application so far. For the photon only, I define my resource control locks as SINGLE_THREADED_SECTION instead of a mutex lock_guard.
For anyone else using an SD card via SPI or other SPI peripheral and doing any meaningful networking stuff, I definitely recommend doing the same. If you don’t need this to also be thread safe within the application context for the electron, you can define LOCK()
as nothing just like UNLOCK()
, or simply use SINGLE_THREADED_SECTION()
directly. For a sample implementation that is working for me, see the below:
// sd card .cpp file
// private macros
#if PLATFORM_ID == 6 // photon
#define LOCK() SINGLE_THREADED_SECTION() // needed due to SPI conflict with system networking
#define UNLOCK()
#else // electron, others
#define LOCK() std::lock_guard<std::mutex> sd_guard_(sd_mutex_);
#define UNLOCK()
#endif
// example use
void SdManager::MyFunction() {
LOCK();
//my code
UNLOCK();
return;
}