关于IIC子系统竞态问题

时间:2024-10-23 07:42:11

文章目录

  • 一、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);

二、可能出现的竞态情况

  1. 多线程同时访问同一个I2C设备
    I2C子系统为每个I2C适配器使用锁机制
    同一时间只有一个线程可以访问某个适配器
  2. 多任务同时请求I2C传输
  3. 中断和进程上下文竞争