Linux i2c子系统

目录

一、i2c简介

二、操作方法

三、I2C子系统的框架

四、I2C适配器层

1.核心数据结构(名字)

2.相关函数或宏

2.1 i2c_add_adapter()

2.2 i2c_add_numbered_adapter()

2.3 i2c_del_adapter()

五、I2C从设备驱动层的i2c_client

1.核心数据结构

2.相关的函数或对应的宏

2.1 i2c_get_adapter()

2.2 i2c_new_device()

2.3 i2c_unregister_device()

3.​​​​​​​编写流程

六、​​​​​​​I2C从设备的驱动层的i2c_driver

1.​​​​​​​核心数据结构

2.​​​​​​​相关的函数与宏

2.1 i2c_add_driver()

2.2 i2c_del_driver()

2.3 i2c_master_send()

2.4 i2c_master_recv()

2.5 i2c_transfer()

3​​​​​​​.编写流程


一、i2c简介

IIC通信有两个线:

        一根数据线(SDA)  一根时钟(SCL)

总线物理拓扑:  

        电容按键--语音模块--AT24C02  符合IIC通信都可以I2C子系统  IIC--同步半双工

主机:

        芯片     

从机:

        外部设备

上拉电阻作用:

        1、保护器件   2、当SCL SDA空闲是高电平  3、阻抗(阻抗匹配)

 注意:

        1、只能由主机发起起始条件(启动数据传输)和停止条件(结束数据的传输)。时钟总线只能有主机控制。

        2、传输的基本单位是字节(1个字节),(MSB)高位在前,低位在后(LSB)。

        3、每当发送方传输一个字节的数据(8个位),接收方就会产生一个应答信号(ACK位低电平),如果接收方不想继续接收数据,则产生一个非应答信号(ACK位高电平)。

        4、每个从设备有唯一的I2C地址,分为两种:7位地址和10位地址(不常用),注意:同一条总线上从设备地址是不同的。

        5、主机向从机发起数据传输的请求,必须指定从机的I2C地址和数据传输方向(方向位),对于7位地址来说,I2C的地址在高7位,方向位是最低位,两者组成一个字节的数据。

        6、方向位为低电平(方向位为0的时候),表示主机向从机写数据,此时主机是发送方,从机接收方;方向是高电平(1),表示主机向从机读取数据,此时主机是接收方,从机是发送方。

二、操作方法

(1)主设备向从设备中写数据(主机发送数据给从机)。数据传输格式如下:(主机给从机发送数据)

(2)主设备向从设备读取数据(主机请求从机,从机发送数据给主机)。数据传输格式如下:(从机给主机发送数据)

(3)主设备向从设备中写数据,然后重启起始条件,紧接着向从设备中读取数据;或者主设备向从设备读数据,然后重启起始条件,紧接着主设备往从设备中写数据。数据传输格式如下:

补充注意事项:第三种在单个主设备系统中,重复的开启起始条件机制要比用STOP终止传输后又再次开启更有效率。

总结:

        1、一组I2C总线上只能有1个主机,第一个从机用不同的I2C地址(通常为7位)区分。

        2、主机可以读或写从机,用方向位区分读还是写。方向位默认为1表示读,方向位0表示写。

        3、一次传输8个比特,一个字节。

三、I2C子系统的框架

  3层的基本作用:

        (1)i2c设备驱动层:描述从机信息和驱动方式,注册字符设备,提供操作接口给应用层,与应用层交互数据,但是需要调用i2c_adapter层提供的I2C总线发送和接收数据的方法。

        (2)I2C核心层:将从机挂载到请求的主机总线上; 维护i2c driver和i2c client 链表 ,实现i2c_client和i2c_driver匹配。

        (3)I2C适配层:初始化I2C控制器(适配器),实现i2c时序,实现i2c总线发送和接收数据的方法。

四、I2C适配器层

1.核心数据结构(名字)

struct i2c_adapter{           //i2c适配器的抽象

        unsigned int class;  //设备分类

        const struct i2c_algorithm *algo;  //i2c总线发送和接收数据的方法(对数据线和时钟线的操作)

        void *algo_data;      //i2c总线发送和接收数据的方法可能用到的参数(某个对象的地址)--可以用来进行数据传递

         int nr;                //i2c物理总线的编号(如i2c0编号通常为0  i2c1编号1)

         .....

};

/*
 * i2c_adapter is the structure used to identify a physical i2c bus along
 * with the access algorithms necessary to access it.
 */
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	*/
	struct rt_mutex bus_lock;

	int timeout;			/* in jiffies */
	int retries;
	struct device dev;		/* the adapter device */

	int nr;   //总线的编号
}

2.相关函数或宏

2.1 i2c_add_adapter()

头文件:

        #include <linux/i2c.h>

原型:

        int  i2c_add_adapter(struct i2c_adapter *adap)

功能: 

        注册指定的i2c_adapter对象,动态分配该i2c_adapter的总线编号nr成员

参数:

        adap:已经定义好的i2c_adapter对象的地址

返回值:

        成功:0   

        失败:负数

内核源码的基本形式:
/**
 * i2c_add_adapter - declare i2c adapter, use dynamic bus number
 * @adapter: the adapter to add
 * Context: can sleep
 *
 * This routine is used to declare an I2C adapter when its bus number
 * doesn't matter or when its bus number is specified by an dt alias.
 * Examples of bases when the bus number doesn't matter: I2C adapters
 * dynamically added by USB links or PCI plugin cards.
 *
 * When this returns zero, a new bus number was allocated and stored
 * in adap->nr, and the specified adapter became available for clients.
 * Otherwise, a negative errno value is returned.
 */
int i2c_add_adapter(struct i2c_adapter *adapter)
{
	struct device *dev = &adapter->dev;
	int id;

	if (dev->of_node) {
		id = of_alias_get_id(dev->of_node, "i2c");
		if (id >= 0) {
			adapter->nr = id;
			return __i2c_add_numbered_adapter(adapter);
		}
	}

	mutex_lock(&core_lock);
	id = idr_alloc(&i2c_adapter_idr, adapter,
		 
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值