15

I'm writing a multithread C program in embedded Linux that accesses from userspace a number of I2C devices (slaves). Also, I access the same I2C device from multiple threads. I'm using SMBUS functions (i2c_smbus_write_byte_data, i2c_smbus_read_byte_data, i2c_smbus_read_i2c_block_data,...).

Is there any protection from concurrent access built in or do I need to add mutexes myself?

For instance: I have a Read function that read data from one sensor over I2C. But the same function can be called from another thread as well, resulting in possible concurrent access. Do I have to use some static mutex in that function or is it already in the I2C access functions?

asked May 9, 2013 at 17:36
1
  • From memory, I2C drivers are protected against concurrent access - but I would recommend having a look at the kernel source to be sure. This only holds of course if your access to the device retains arbitration or has no multi-transaction state. Commented May 14, 2013 at 15:15

2 Answers 2

19

I2C is a shared bus with multiple devices, which could be accessed from multiple processes as well as threads. So the Linux I2C driver code uses a mutex to manage access to each I2C bus.

For SMBus functions, see the Linux kernel function i2c_smbus_xfer() in i2c-core-smbus.c. It gets a lock for the I2C adapter before beginning a transfer (look at the source code, and see the call to __i2c_lock_bus_helper()). All SMBus transactions are based on that function.

For I2C functions, see the Linux kernel function i2c_transfer() in i2c-core-base.c. It gets a lock for the I2C adapter before beginning a transfer. All I2C transaction are based on that function.

So yes, there is protection from concurrent access built-in.

(links are for Linux kernel 5.13)

answered Nov 18, 2015 at 23:19
Sign up to request clarification or add additional context in comments.

5 Comments

If you follow the i2c_smbus_xfer path, you end up at struct i2c_lock_operations which seems to leave the implementation details of the locking mechanism to the i2c_adapter... Where is this mutex that you are referring to?
As I said, see the call to i2c_lock_adapter(adapter)... which in turn calls rt_mutex_lock(&adapter->bus_lock).
Could you be specific regarding which version of the kernel you are referring to and include the file and line number? Looking at the latest (5.7.1 at the time of writing) and as far as I can tell, the locking logic becomes implementation dependent after calling the lock_bus function specified in the i2c_lock_operations struct via adapter->lock_ops->lock_bus(adapter, flags);
I can see the struct rt_mutex bus_lock; member of struct i2c_adapter but nothing in include/linux/i2c.h touches it...
My concerns regarding the question: stackoverflow.com/questions/79793167/…
-1

Use a mutex in your program. The driver has no way to know the operations that each thread is going to do.

answered May 10, 2013 at 7:03

2 Comments

that's right but the I2C driver is the same for every operation on the I2C device so it could know when it is being used
No need to add mutex.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.