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?
-
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.marko– marko2013年05月14日 15:15:25 +00:00Commented May 14, 2013 at 15:15
2 Answers 2
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)
5 Comments
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?i2c_lock_adapter(adapter)... which in turn calls rt_mutex_lock(&adapter->bus_lock).lock_bus function specified in the i2c_lock_operations struct via adapter->lock_ops->lock_bus(adapter, flags); struct rt_mutex bus_lock; member of struct i2c_adapter but nothing in include/linux/i2c.h touches it...Use a mutex in your program. The driver has no way to know the operations that each thread is going to do.
2 Comments
Explore related questions
See similar questions with these tags.