Add lock to protect concurrent i2c transactions performed by different tasks (#8127)
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
This commit is contained in:
parent
e99437c850
commit
db7b3495d5
2 changed files with 30 additions and 25 deletions
|
|
@ -52,7 +52,7 @@ TwoWire::TwoWire(uint8_t bus_num)
|
||||||
,_timeOutMillis(50)
|
,_timeOutMillis(50)
|
||||||
,nonStop(false)
|
,nonStop(false)
|
||||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||||
,nonStopTask(NULL)
|
,currentTaskHandle(NULL)
|
||||||
,lock(NULL)
|
,lock(NULL)
|
||||||
#endif
|
#endif
|
||||||
#if SOC_I2C_SUPPORT_SLAVE
|
#if SOC_I2C_SUPPORT_SLAVE
|
||||||
|
|
@ -433,15 +433,15 @@ void TwoWire::beginTransmission(uint16_t address)
|
||||||
}
|
}
|
||||||
#endif /* SOC_I2C_SUPPORT_SLAVE */
|
#endif /* SOC_I2C_SUPPORT_SLAVE */
|
||||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||||
if(nonStop && nonStopTask == xTaskGetCurrentTaskHandle()){
|
TaskHandle_t task = xTaskGetCurrentTaskHandle();
|
||||||
log_e("Unfinished Repeated Start transaction! Expected requestFrom, not beginTransmission! Clearing...");
|
if (currentTaskHandle != task)
|
||||||
//release lock
|
{
|
||||||
xSemaphoreGive(lock);
|
//acquire lock
|
||||||
}
|
if(lock == NULL || xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE){
|
||||||
//acquire lock
|
log_e("could not acquire lock");
|
||||||
if(lock == NULL || xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE){
|
return;
|
||||||
log_e("could not acquire lock");
|
}
|
||||||
return;
|
currentTaskHandle = task;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
nonStop = false;
|
nonStop = false;
|
||||||
|
|
@ -475,15 +475,13 @@ uint8_t TwoWire::endTransmission(bool sendStop)
|
||||||
if(sendStop){
|
if(sendStop){
|
||||||
err = i2cWrite(num, txAddress, txBuffer, txLength, _timeOutMillis);
|
err = i2cWrite(num, txAddress, txBuffer, txLength, _timeOutMillis);
|
||||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||||
|
currentTaskHandle = NULL;
|
||||||
//release lock
|
//release lock
|
||||||
xSemaphoreGive(lock);
|
xSemaphoreGive(lock);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
//mark as non-stop
|
//mark as non-stop
|
||||||
nonStop = true;
|
nonStop = true;
|
||||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
|
||||||
nonStopTask = xTaskGetCurrentTaskHandle();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
switch(err){
|
switch(err){
|
||||||
case ESP_OK: return 0;
|
case ESP_OK: return 0;
|
||||||
|
|
@ -507,13 +505,26 @@ size_t TwoWire::requestFrom(uint16_t address, size_t size, bool sendStop)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
esp_err_t err = ESP_OK;
|
esp_err_t err = ESP_OK;
|
||||||
if(nonStop
|
|
||||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||||
&& nonStopTask == xTaskGetCurrentTaskHandle()
|
TaskHandle_t task = xTaskGetCurrentTaskHandle();
|
||||||
#endif
|
if (currentTaskHandle != task)
|
||||||
){
|
{
|
||||||
|
//acquire lock
|
||||||
|
if(lock == NULL || xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE){
|
||||||
|
log_e("could not acquire lock");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
currentTaskHandle = task;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(nonStop){
|
||||||
if(address != txAddress){
|
if(address != txAddress){
|
||||||
log_e("Unfinished Repeated Start transaction! Expected address do not match! %u != %u", address, txAddress);
|
log_e("Unfinished Repeated Start transaction! Expected address do not match! %u != %u", address, txAddress);
|
||||||
|
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||||
|
currentTaskHandle = NULL;
|
||||||
|
//release lock
|
||||||
|
xSemaphoreGive(lock);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
nonStop = false;
|
nonStop = false;
|
||||||
|
|
@ -524,13 +535,6 @@ size_t TwoWire::requestFrom(uint16_t address, size_t size, bool sendStop)
|
||||||
log_e("i2cWriteReadNonStop returned Error %d", err);
|
log_e("i2cWriteReadNonStop returned Error %d", err);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
|
||||||
//acquire lock
|
|
||||||
if(lock == NULL || xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE){
|
|
||||||
log_e("could not acquire lock");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
rxIndex = 0;
|
rxIndex = 0;
|
||||||
rxLength = 0;
|
rxLength = 0;
|
||||||
err = i2cRead(num, address, rxBuffer, size, _timeOutMillis, &rxLength);
|
err = i2cRead(num, address, rxBuffer, size, _timeOutMillis, &rxLength);
|
||||||
|
|
@ -539,6 +543,7 @@ size_t TwoWire::requestFrom(uint16_t address, size_t size, bool sendStop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||||
|
currentTaskHandle = NULL;
|
||||||
//release lock
|
//release lock
|
||||||
xSemaphoreGive(lock);
|
xSemaphoreGive(lock);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ protected:
|
||||||
uint32_t _timeOutMillis;
|
uint32_t _timeOutMillis;
|
||||||
bool nonStop;
|
bool nonStop;
|
||||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||||
TaskHandle_t nonStopTask;
|
TaskHandle_t currentTaskHandle;
|
||||||
SemaphoreHandle_t lock;
|
SemaphoreHandle_t lock;
|
||||||
#endif
|
#endif
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue