Unverified Commit db7b3495 authored by Mirco Pizzichini's avatar Mirco Pizzichini Committed by GitHub

Add lock to protect concurrent i2c transactions performed by different tasks (#8127)

Co-authored-by: default avatarMe No Dev <me-no-dev@users.noreply.github.com>
parent e99437c8
......@@ -52,7 +52,7 @@ TwoWire::TwoWire(uint8_t bus_num)
,_timeOutMillis(50)
,nonStop(false)
#if !CONFIG_DISABLE_HAL_LOCKS
,nonStopTask(NULL)
,currentTaskHandle(NULL)
,lock(NULL)
#endif
#if SOC_I2C_SUPPORT_SLAVE
......@@ -433,15 +433,15 @@ void TwoWire::beginTransmission(uint16_t address)
}
#endif /* SOC_I2C_SUPPORT_SLAVE */
#if !CONFIG_DISABLE_HAL_LOCKS
if(nonStop && nonStopTask == xTaskGetCurrentTaskHandle()){
log_e("Unfinished Repeated Start transaction! Expected requestFrom, not beginTransmission! Clearing...");
//release lock
xSemaphoreGive(lock);
}
//acquire lock
if(lock == NULL || xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE){
log_e("could not acquire lock");
return;
TaskHandle_t task = xTaskGetCurrentTaskHandle();
if (currentTaskHandle != task)
{
//acquire lock
if(lock == NULL || xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE){
log_e("could not acquire lock");
return;
}
currentTaskHandle = task;
}
#endif
nonStop = false;
......@@ -475,15 +475,13 @@ uint8_t TwoWire::endTransmission(bool sendStop)
if(sendStop){
err = i2cWrite(num, txAddress, txBuffer, txLength, _timeOutMillis);
#if !CONFIG_DISABLE_HAL_LOCKS
currentTaskHandle = NULL;
//release lock
xSemaphoreGive(lock);
#endif
} else {
//mark as non-stop
nonStop = true;
#if !CONFIG_DISABLE_HAL_LOCKS
nonStopTask = xTaskGetCurrentTaskHandle();
#endif
}
switch(err){
case ESP_OK: return 0;
......@@ -507,13 +505,26 @@ size_t TwoWire::requestFrom(uint16_t address, size_t size, bool sendStop)
return 0;
}
esp_err_t err = ESP_OK;
if(nonStop
#if !CONFIG_DISABLE_HAL_LOCKS
&& nonStopTask == xTaskGetCurrentTaskHandle()
#endif
){
TaskHandle_t task = xTaskGetCurrentTaskHandle();
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){
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;
}
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);
}
} 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;
rxLength = 0;
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
currentTaskHandle = NULL;
//release lock
xSemaphoreGive(lock);
#endif
......
......@@ -69,7 +69,7 @@ protected:
uint32_t _timeOutMillis;
bool nonStop;
#if !CONFIG_DISABLE_HAL_LOCKS
TaskHandle_t nonStopTask;
TaskHandle_t currentTaskHandle;
SemaphoreHandle_t lock;
#endif
private:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment