-
Notifications
You must be signed in to change notification settings - Fork 7.6k
fixing beginTransaction() thread safety #6425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
534978d
957f818
db409b9
3480fa9
7c2d808
5f4bc38
70431bb
5b2e387
8be51a4
41be2fc
2d1098f
15fcc21
28943f4
5a30b8a
262a000
eaca28f
d0cc215
cf1363a
3e42a87
b4a6329
22e2881
64cb9c8
d157e52
beda8cd
a4950f2
e91e10a
1b3c34a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,14 @@ | |
|
||
#include "SPI.h" | ||
|
||
#if !CONFIG_DISABLE_HAL_LOCKS | ||
#define SPI_PARAM_LOCK() do {} while (xSemaphoreTake(paramLock, portMAX_DELAY) != pdPASS) | ||
#define SPI_PARAM_UNLOCK() xSemaphoreGive(paramLock) | ||
#else | ||
#define SPI_PARAM_LOCK() | ||
#define SPI_PARAM_UNLOCK() | ||
#endif | ||
|
||
SPIClass::SPIClass(uint8_t spi_bus) | ||
:_spi_num(spi_bus) | ||
,_spi(NULL) | ||
|
@@ -48,6 +56,12 @@ void SPIClass::begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss) | |
if(!_spi) { | ||
return; | ||
} | ||
#if !CONFIG_DISABLE_HAL_LOCKS | ||
if(paramLock==NULL){ | ||
paramLock = xSemaphoreCreateMutex(); | ||
if(paramLock==NULL) return; // fail to create mutex so abort initialization | ||
} | ||
#endif | ||
|
||
if(sck == -1 && miso == -1 && mosi == -1 && ss == -1) { | ||
#if CONFIG_IDF_TARGET_ESP32S2 | ||
|
@@ -106,19 +120,23 @@ void SPIClass::setHwCs(bool use) | |
|
||
void SPIClass::setFrequency(uint32_t freq) | ||
{ | ||
//check if last freq changed | ||
SPI_PARAM_LOCK(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Protects "_div" from cross-thread modification. OK |
||
//check if last freq changed | ||
uint32_t cdiv = spiGetClockDiv(_spi); | ||
if(_freq != freq || _div != cdiv) { | ||
_freq = freq; | ||
_div = spiFrequencyToClockDiv(_freq); | ||
spiSetClockDiv(_spi, _div); | ||
} | ||
SPI_PARAM_UNLOCK(); | ||
} | ||
|
||
void SPIClass::setClockDivider(uint32_t clockDiv) | ||
{ | ||
_div = clockDiv; | ||
SPI_PARAM_LOCK(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Protects "_div" from cross-thread modification. OK |
||
_div = clockDiv; | ||
spiSetClockDiv(_spi, _div); | ||
SPI_PARAM_UNLOCK(); | ||
} | ||
|
||
uint32_t SPIClass::getClockDivider() | ||
|
@@ -138,7 +156,8 @@ void SPIClass::setBitOrder(uint8_t bitOrder) | |
|
||
void SPIClass::beginTransaction(SPISettings settings) | ||
{ | ||
//check if last freq changed | ||
SPI_PARAM_LOCK(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Protects "_div" from cross-thread modification. OK |
||
//check if last freq changed | ||
uint32_t cdiv = spiGetClockDiv(_spi); | ||
if(_freq != settings._clock || _div != cdiv) { | ||
_freq = settings._clock; | ||
|
@@ -153,6 +172,7 @@ void SPIClass::endTransaction() | |
if(_inTransaction){ | ||
_inTransaction = false; | ||
spiEndTransaction(_spi); | ||
SPI_PARAM_UNLOCK(); | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible bug _LOCK() changed to _UNLOCK(). I will do a more in depth study of the code this weekend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should be LOCK as that is another way to start transaction