i2c_master_transmit seems like it is not thread safe

luftaquila
Posts: 1
Joined: Tue Jul 22, 2025 10:44 am

i2c_master_transmit seems like it is not thread safe

Postby luftaquila » Tue Jul 22, 2025 11:06 am

Hello,

I'm using ESP32-S3 with IDF 5.4 and I'm suffering from `ESP_ERR_INVALID_STATE` error returned by `i2c_master_transmit_receive()` function.

There are an RTC and a gyroscope on the I2C0 bus.

The main thread at Core 0 does:

1. `i2c_master_new_bus()` the bus i2c0.
2. `i2c_master_bus_add_device()` the RTC.
3. `i2c_master_transmit_receive()` some data to RTC.
4. `i2c_master_bus_rm()` the RTC.
5. Create gyroscope task pinned to Core 1.

Now, the created gyroscope task at Core 1 does:

1. `i2c_master_get_bus_handle()` the bus i2c0.
2. `i2c_master_bus_add_device()` the gyro.
3. `i2c_master_transmit()` some config to the gyro.
4. `i2c_master_transmit_receive()` to gyro **every 100 ms**

And a few moments later, when SNTP sync is done, the callback function does (not sure which core it is):

1. `i2c_master_get_bus_handle()` the bus i2c0.
2. `i2c_master_bus_add_device()` the RTC.
3. `i2c_master_transmit()` some data to RTC.
4. `i2c_master_bus_rm()` the RTC.

In this flow, any one of the `i2c_master_transmit()` or `i2c_master_transmit_receive()` calls randomly fails with `ESP_ERR_INVALID_STATE`.

Randomly means:
* Sometimes it's all ok.
* Sometimes, RTC transmit_receive at main thread fails
* Sometimes, gyro transmit_receive at the task fails, at the time of SNTP sync
* Sometimes, RTC transmit at SNTP callback fails

But in the *Thread Safety* section of the I2C reference manual (https://docs.espressif.com/projects/esp ... ead-safety), it says:
The factory function i2c_new_master_bus() and i2c_new_slave_device() are guaranteed to be thread safe by the driver, which means that the functions can be called from different RTOS tasks without protection by extra locks.

I2C master operation functions are also guaranteed to be thread safe by bus operation semaphore.

* i2c_master_transmit()
* i2c_master_multi_buffer_transmit()
* i2c_master_transmit_receive()
* i2c_master_receive()
* i2c_master_probe()
So it should be ok to call these functions from different cores concurrently. I cannot understand why invalid state error is occurring randomly.

Thank you for your help in advance!

Who is online

Users browsing this forum: No registered users and 3 guests