文章目录
- 一、I2C适配器锁
- 二、可能出现的竞态情况
一、I2C适配器锁
I2C子系统为每个I2C适配器(i2c_adapter)使用锁机制(自旋锁),确保同一时间只有一个线程可以访问某个适配器。
每个I2C适配器(i2c_adapter)在注册时会初始化一个互斥锁bus_lock
struct i2c_adapter {
struct rt_mutex bus_lock;
};
//struct rt_mutex结构体
struct rt_mutex {
raw_spinlock_t wait_lock;
struct rb_root_cached waiters;
struct task_struct *owner;
};
- 补:I2C适配器是SOC上I2C控制器的一个软件层面的抽象。
- 在硬件层面,它是I2C设备硬件连接器件;
- 在软件层面,它是I2C驱动和I2C设备间通信所需要使用的一个结构体。
每个I2C传输操作(如i2c_transfer、i2c_smbus_read)内部都会加锁来保护传输过程。
即当一个任务调用i2c_transfer时,I2C子系统会确保在该传输操作完成之前,其他任务无法访问同一个I2C总线。
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
int ret;
ret = __i2c_lock_bus_helper(adap);
if (ret)
return ret;
ret = __i2c_transfer(adap, msgs, num);
i2c_unlock_bus(adap, I2C_LOCK_SEGMENT);
return ret;
}
static inline void i2c_lock_bus(struct i2c_adapter *adapter, unsigned int flags)
{
adapter->lock_ops->lock_bus(adapter, flags);
}
即相当于,i2c_transfer函数内部会有类似以下的流程:
mutex_lock(adapter->bus_lock);
... //传输操作
mutex_unlock(adapter->bus_lock);
二、可能出现的竞态情况
- 多线程同时访问同一个I2C设备
I2C子系统为每个I2C适配器使用锁机制
同一时间只有一个线程可以访问某个适配器 - 多任务同时请求I2C传输
- 中断和进程上下文竞争