linux IIC系统学习

linux IIC系统学习

IIC硬件框图

一般soc有多个iic 控制器,每个IIC总线有SCL SDA两个线完成,每条线上有一个3.3V的上拉电阻,设备挂在总线上。
在这里插入图片描述
驱动程序分为IIC总线控制程序、控制器驱动程序和设备驱动程序

IIC软件框架

软件分层结构如下:
APP :知道需要读写什么数据
IIC Device driver :知道怎么读写数据
IIC controller driver :负责传输数据

linux iic驱动分层如下:
在这里插入图片描述
内核支持使用控制器访问设备,也支持GPIO模拟IIC访问设备。

内核中的关键数据结构:

  1. i2c_adapter
    i2c_adapter 主要是抽象iic控制器,里面比较关键的成员有nr:表示控制器的编号,algo里面封装了一系列的iic操作函数。比如master_xfer
struct i2c_adapter {
	struct module *owner;
	unsigned int class;		  /* classes to allow probing for */
	const struct i2c_algorithm *algo; /* the algorithm to access the bus */
	void *algo_data;

	/* data fields that are valid for all devices	*/
	const struct i2c_lock_operations *lock_ops;
	struct rt_mutex bus_lock;
	struct rt_mutex mux_lock;

	int timeout;			/* in jiffies */
	int retries;
	struct device dev;		/* the adapter device */
	unsigned long locked_flags;	/* owned by the I2C core */
#define I2C_ALF_IS_SUSPENDED		0
#define I2C_ALF_SUSPEND_REPORTED	1

	int nr;
	char name[48];
	struct completion dev_released;

	struct mutex userspace_clients_lock;
	struct list_head userspace_clients;

	struct i2c_bus_recovery_info *bus_recovery_info;
	const struct i2c_adapter_quirks *quirks;

	struct irq_domain *host_notify_domain;
};
  1. i2c_client
    i2c_client里面主要的内容包括addr:设备地址, i2c_adapter:指向设备挂载的iic控制器下
struct i2c_client {
	unsigned short flags;		/* div., see below		*/
#define I2C_CLIENT_PEC		0x04	/* Use Packet Error Checking */
#define I2C_CLIENT_TEN		0x10	/* we have a ten bit chip address */
					/* Must equal I2C_M_TEN below */
#define I2C_CLIENT_SLAVE	0x20	/* we are the slave */
#define I2C_CLIENT_HOST_NOTIFY	0x40	/* We want to use I2C host notify */
#define I2C_CLIENT_WAKE		0x80	/* for board_info; true iff can wake */
#define I2C_CLIENT_SCCB		0x9000	/* Use Omnivision SCCB protocol */
					/* Must match I2C_M_STOP|IGNORE_NAK */

	unsigned short addr;		/* chip address - NOTE: 7bit	*/
					/* addresses are stored in the	*/
					/* _LOWER_ 7 bits		*/
	char name[I2C_NAME_SIZE];
	struct i2c_adapter *adapter;	/* the adapter we sit on	*/
	struct device dev;		/* the device structure		*/
	int init_irq;			/* irq set at initialization	*/
	int irq;			/* irq issued by device		*/
	struct list_head detected;
#if IS_ENABLED(CONFIG_I2C_SLAVE)
	i2c_slave_cb_t slave_cb;	/* callback for slave mode	*/
#endif
};
  1. i2c_msg
    i2c_msg 里面最主要的部分有msg的内容(buf),然后是设备地址(addr),读写标志(flag),数据的长度(len)
struct i2c_msg {
	__u16 addr;	/* slave address			*/
	__u16 flags;
#define I2C_M_RD		0x0001	/* read data, from slave to master */
					/* I2C_M_RD is guaranteed to be 0x0001! */
#define I2C_M_TEN		0x0010	/* this is a ten bit chip address */
#define I2C_M_DMA_SAFE		0x0200	/* the buffer of this message is DMA safe */
					/* makes only sense in kernelspace */
					/* userspace buffers are copied anyway */
#define I2C_M_RECV_LEN		0x0400	/* length will be first received byte */
#define I2C_M_NO_RD_ACK		0x0800	/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK	0x1000	/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_REV_DIR_ADDR	0x2000	/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NOSTART		0x4000	/* if I2C_FUNC_NOSTART */
#define I2C_M_STOP		0x8000	/* if I2C_FUNC_PROTOCOL_MANGLING */
	__u16 len;		/* msg length				*/
	__u8 *buf;		/* pointer to msg data			*/
};

驱动中最长使用i2c_transfer API来发送数据,可以一次发送多条msg,比如需要先发送寄存器地址再获取数据等就可以封装msg调用一次接口即可。

IIC Tools

app通过IIC Controler与device通信,使用iic tools也需要指定:

  1. 哪个iic控制器
  2. 设备地址
  3. 消息(读/写)

查看当前系统的iic总线:

i2cdetect -l

在这里插入图片描述

查看IIC 0总线下的设备挂载情况,UU代表当前内核已经有相关驱动,如果出现明确地址表示探测到IIC设备存在但是当前内核没有相关驱动。当前IIC0下面挂载了2个IIC设备,设备地址分别为0x22 0x3c

i2cdetect -y 0

在这里插入图片描述
读写寄存器:

向0号总线0x1e设备写入2个字节0 0x4

i2ctransfer -f -y 0 w2@0x1e 0 0x4

从0号总线0x1e设备0xc地址读取2个字节

i2ctransfer -f -y 0 w1@0x1e 0xc r2

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值