Skip to content

Commit db7b349

Browse files
mircopzme-no-dev
andauthored
Add lock to protect concurrent i2c transactions performed by different tasks (#8127)
Co-authored-by: Me No Dev <[email protected]>
1 parent e99437c commit db7b349

File tree

2 files changed

+30
-25
lines changed

2 files changed

+30
-25
lines changed

Diff for: libraries/Wire/src/Wire.cpp

+29-24
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ TwoWire::TwoWire(uint8_t bus_num)
5252
,_timeOutMillis(50)
5353
,nonStop(false)
5454
#if !CONFIG_DISABLE_HAL_LOCKS
55-
,nonStopTask(NULL)
55+
,currentTaskHandle(NULL)
5656
,lock(NULL)
5757
#endif
5858
#if SOC_I2C_SUPPORT_SLAVE
@@ -433,15 +433,15 @@ void TwoWire::beginTransmission(uint16_t address)
433433
}
434434
#endif /* SOC_I2C_SUPPORT_SLAVE */
435435
#if !CONFIG_DISABLE_HAL_LOCKS
436-
if(nonStop && nonStopTask == xTaskGetCurrentTaskHandle()){
437-
log_e("Unfinished Repeated Start transaction! Expected requestFrom, not beginTransmission! Clearing...");
438-
//release lock
439-
xSemaphoreGive(lock);
440-
}
441-
//acquire lock
442-
if(lock == NULL || xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE){
443-
log_e("could not acquire lock");
444-
return;
436+
TaskHandle_t task = xTaskGetCurrentTaskHandle();
437+
if (currentTaskHandle != task)
438+
{
439+
//acquire lock
440+
if(lock == NULL || xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE){
441+
log_e("could not acquire lock");
442+
return;
443+
}
444+
currentTaskHandle = task;
445445
}
446446
#endif
447447
nonStop = false;
@@ -475,15 +475,13 @@ uint8_t TwoWire::endTransmission(bool sendStop)
475475
if(sendStop){
476476
err = i2cWrite(num, txAddress, txBuffer, txLength, _timeOutMillis);
477477
#if !CONFIG_DISABLE_HAL_LOCKS
478+
currentTaskHandle = NULL;
478479
//release lock
479480
xSemaphoreGive(lock);
480481
#endif
481482
} else {
482483
//mark as non-stop
483484
nonStop = true;
484-
#if !CONFIG_DISABLE_HAL_LOCKS
485-
nonStopTask = xTaskGetCurrentTaskHandle();
486-
#endif
487485
}
488486
switch(err){
489487
case ESP_OK: return 0;
@@ -507,13 +505,26 @@ size_t TwoWire::requestFrom(uint16_t address, size_t size, bool sendStop)
507505
return 0;
508506
}
509507
esp_err_t err = ESP_OK;
510-
if(nonStop
511508
#if !CONFIG_DISABLE_HAL_LOCKS
512-
&& nonStopTask == xTaskGetCurrentTaskHandle()
513-
#endif
514-
){
509+
TaskHandle_t task = xTaskGetCurrentTaskHandle();
510+
if (currentTaskHandle != task)
511+
{
512+
//acquire lock
513+
if(lock == NULL || xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE){
514+
log_e("could not acquire lock");
515+
return 0;
516+
}
517+
currentTaskHandle = task;
518+
}
519+
#endif
520+
if(nonStop){
515521
if(address != txAddress){
516522
log_e("Unfinished Repeated Start transaction! Expected address do not match! %u != %u", address, txAddress);
523+
#if !CONFIG_DISABLE_HAL_LOCKS
524+
currentTaskHandle = NULL;
525+
//release lock
526+
xSemaphoreGive(lock);
527+
#endif
517528
return 0;
518529
}
519530
nonStop = false;
@@ -524,13 +535,6 @@ size_t TwoWire::requestFrom(uint16_t address, size_t size, bool sendStop)
524535
log_e("i2cWriteReadNonStop returned Error %d", err);
525536
}
526537
} else {
527-
#if !CONFIG_DISABLE_HAL_LOCKS
528-
//acquire lock
529-
if(lock == NULL || xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE){
530-
log_e("could not acquire lock");
531-
return 0;
532-
}
533-
#endif
534538
rxIndex = 0;
535539
rxLength = 0;
536540
err = i2cRead(num, address, rxBuffer, size, _timeOutMillis, &rxLength);
@@ -539,6 +543,7 @@ size_t TwoWire::requestFrom(uint16_t address, size_t size, bool sendStop)
539543
}
540544
}
541545
#if !CONFIG_DISABLE_HAL_LOCKS
546+
currentTaskHandle = NULL;
542547
//release lock
543548
xSemaphoreGive(lock);
544549
#endif

Diff for: libraries/Wire/src/Wire.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class TwoWire: public Stream
6969
uint32_t _timeOutMillis;
7070
bool nonStop;
7171
#if !CONFIG_DISABLE_HAL_LOCKS
72-
TaskHandle_t nonStopTask;
72+
TaskHandle_t currentTaskHandle;
7373
SemaphoreHandle_t lock;
7474
#endif
7575
private:

0 commit comments

Comments
 (0)