I2C相关结构体讲解:i2c_adapter、i2c_algorithm、i2c_msg

news2025/1/15 6:47:07

往期内容

I2C子系统专栏:

  1. I2C(IIC)协议讲解
  2. SMBus 协议详解

总线和设备树专栏:

  1. 专栏地址
  2. 导航篇 – 专栏未篇

1.框图

画板

建议右击图片在新标签页打开预览

i2c_transfer函数就是读取i2c设备的信息或者输出信息给i2c设备的函数

比如发送app发送数据给i2c设备,i2c设备的驱动程序会调用到i2c_transfer函数,将信息发送给i2c控制器,I2C控制器就能根据协议调用内部i2c_adapter定义的传输函数(比如master_xfer和smbus_xfer)向设备发送数据

又比如想要读取i2c设备的数据,通过i2c_transfer来读取,会告诉i2c控制器调用相关的读函数来读取到i2c设备的数据(比如读取到Buf中,将buf传送回app)

结构体刚开始的话,看到这其实已经差不多了,当然,有兴趣深究的可以继续往下看:

2. struct i2c_adapter

代表着一个I2C 控制器,同时也标识着物理的I2C总线,并且有着一套访问I2C设备的算法,其实也就是协议类型:I2C/SMbus协议等

\Linux-4.9.88\include\linux\i2c.h:
/*
 * 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	*/
	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 */

	int nr;
	char name[48];  // 表示 I2C 适配器的名字
	struct completion dev_released;  //用于同步释放控制器资源的完成机制

	struct mutex userspace_clients_lock; //用于保护用户空间 I2C 客户端的并发访问
	struct list_head userspace_clients;  //维护一个用户空间 I2C 客户端的链表。通过这个链表,适配器可以跟踪注册到它的用户空间客户端

	struct i2c_bus_recovery_info *bus_recovery_info;//当 I2C 总线发生错误或死锁时,可以尝试通过 bus_recovery_info 中定义的方法进行总线恢复,例如通过 GPIO 拉低总线或者其他恢复手段
	const struct i2c_adapter_quirks *quirks;//定义适配器的某些特殊行为或限制
};

struct module *owner: 用于指向当前拥有这个 I2C 控制器的模块。这个成员确保了模块在其设备未完全释放时不会被卸载。典型情况下会使用 THIS_MODULE 来指向当前模块。

unsigned int class: 用于表示该 I2C 适配器支持的设备类型(类)。 class 字段用于限制能够自动挂载到这个适配器上的设备类型 :

  • I2C_CLASS_HWMON:支持硬件监控设备。
  • I2C_CLASS_DDC:用于显示设备的 DDC 通道。
  • I2C_CLASS_SPD:支持 SPD 存储设备。
  • I2C_CLASS_DEPRECATED:表示不再支持的设备类型。

const struct i2c_algorithm *algo**:**下一点中再细讲

void *algo_data 用于存储算法(algo)相关的私有数据。 允许驱动在适配器与其使用的算法之间共享特定于适配器的上下文数据。

const struct i2c_lock_operations *lock_ops 如果某些适配器需要特殊的锁定行为,可以在这里定义自定义的锁操作,以确保在并发访问总线时保持正确的同步。

struct rt_mutex bus_lock 多设备可能同时尝试访问 I2C 总线,这里用 rt_mutex 互斥锁来保护总线,确保不会发生并发访问问题。

struct rt_mutex mux_lockbus_lock 类似,保护 I2C 总线多路复用器(mux)的同步访问。 在某些情况下,一个 I2C 控制器可能连接多个 I2C 总线,通过一个多路复用器进行选择,mux_lock 保护对该复用器的访问。

int timeoutint retries 定义 I2C 传输的超时时间,单位是 jiffies; 定义 I2C 传输失败后的重试次数。

struct device dev:I2C framework将I2C adapter当做了I2C bus中的一类特殊的设备,因此dev变量是它在设备模型中的体现。

int nr 控制器的编号(ID),在 /sys/bus/i2c/devices/i2c-n 中表示该总线。

剩下的就直接注释在代码中了。

3. struct i2c_algorithm

用于定义一个 I2C 控制器器(i2c_adapter)的传输方法(I2C 或 SMBus)。它主要用于描述控制器器的操作方式,并为设备驱动提供传输功能接口

\Linux-4.9.88\include\uapi\linux\i2c.h
/**
 * struct i2c_algorithm - represent I2C transfer method
 * @master_xfer: Issue a set of i2c transactions to the given I2C adapter
 *   defined by the msgs array, with num messages available to transfer via
 *   the adapter specified by adap.
 * @smbus_xfer: Issue smbus transactions to the given I2C adapter. If this
 *   is not present, then the bus layer will try and convert the SMBus calls
 *   into I2C transfers instead.
 * @functionality: Return the flags that this algorithm/adapter pair supports
 *   from the I2C_FUNC_* flags.
 * @reg_slave: Register given client to I2C slave mode of this adapter
 * @unreg_slave: Unregister given client from I2C slave mode of this adapter
 *
 * The following structs are for those who like to implement new bus drivers:
 * i2c_algorithm is the interface to a class of hardware solutions which can
 * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584
 * to name two of the most common.
 *
 * The return codes from the @master_xfer field should indicate the type of
 * error code that occurred during the transfer, as documented in the kernel
 * Documentation file Documentation/i2c/fault-codes.
 */
struct i2c_algorithm {
	/* If an adapter algorithm can't do I2C-level access, set master_xfer
	   to NULL. If an adapter algorithm can do SMBus access, set
	   smbus_xfer. If set to NULL, the SMBus protocol is simulated
	   using common I2C messages */
	/* master_xfer should return the number of messages successfully
	   processed, or a negative value on error */
	int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
			   int num);  
    //---------------(A)
        
	int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
			   unsigned short flags, char read_write,
			   u8 command, int size, union i2c_smbus_data *data);
    //---------------(B)
	/* To determine what the adapter supports */
	u32 (*functionality) (struct i2c_adapter *);
    //---------------(C)
    
#if IS_ENABLED(CONFIG_I2C_SLAVE)
	int (*reg_slave)(struct i2c_client *client);
	int (*unreg_slave)(struct i2c_client *client);
#endif
};

(A)master_xfer 是控制器执行 I2C 传输的核心函数,里面有一个关键的参数就是 struct i2c_msg *msgs, 驱动程序会通过该函数与 I2C 设备通信,具体的讲解下文会单独讲;参三num是指该msgs数据的长度。

(B)smbus_xferSMBUS有关的数据传输接口,如果为NULL,I2C core会尝试使用master_xfer模拟

(C)functionality该函数返回适配器支持的功能标志,用于描述适配器能够支持哪些类型的 I2C 或 SMBus 操作:

  • I2C_FUNC_I2C: 适配器支持基本的 I2C 功能。
  • I2C_FUNC_10BIT_ADDR: 支持 10 位地址的 I2C 设备。
  • I2C_FUNC_PROTOCOL_MANGLING: 支持非标准协议行为(如时序微调等)。
  • I2C_FUNC_NOSTART: 支持不需要发送 START 信号的 I2C 传输。
  • I2C_FUNC_SMBUS_*: 支持 SMBus 协议的各种操作,如字节传输、块传输等。

4.struct i2c_msg

用于描述 I2C 传输过程中一次消息(msg)的内容。I2C 通信通常以消息为单位进行操作,一个 i2c_msg 结构体对应 I2C 总线上的一次传输,无论是主机向从机发送数据,还是主机从从机读取数据

\Linux-4.9.88\include\uapi\linux\i2c.h
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_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			*/
};

(1)addr,I2C slave device的地址。

(2)flags,数据传输可携带的flag,下面讲解

(3)len,数据传输的长度,单位为byte。

(4)buf,数据buf。

正常写:

S Addr Wr [A] Data [A] Data [A] ... [A] Data [A] P
  • 主设备发送 START 信号,接着发送从设备地址(写操作标志位 Wr),等待应答 A,然后发送数据,直到发送完成并收到应答 A,最后发送 STOP 信号。

正常读:

S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
  • 主设备发送 START 信号,接着发送从设备地址(读操作标志位 Rd),等待应答 A,然后从从设备读取数据,直到读取完成并返回 NACK(表示没有更多数据可读),然后发送 STOP 信号。

读写混合操作:

  • 读写混合操作通常出现在需要连续传输的场景中。比如先从设备读取数据,再发送某些写入命令:
S Addr Rd [A] [Data] NA S Addr Wr [A] Data [A] P

flag:

  • I2C_M_RD(0x0001):表示这是一个读操作,数据流向是从从设备到主设备。默认情况下,没有这个标志时,消息是写操作(主设备向从设备发送数据)。
  • I2C_M_TEN(0x0010):表示从设备使用的是 10 位地址。默认情况下,I2C 使用 7 位地址。
  • I2C_M_RECV_LEN(0x0400): 表示读取的数据长度将由从设备通过第一个接收到的字节来指定。
  • I2C_M_NO_RD_ACK(0x0800):表示在读取过程中不需要确认(ACK)忽略所有的NACK/ACK信号。这个标志位常见于 SMBus(System Management Bus)设备。某些设备在 I2C 读操作的开始,会首先发送一个字节作为接下来的数据长度,然后再传输实际的数据。
  • I2C_M_IGNORE_NAK(0x1000):表示即使在收到非应答(NAK,No Acknowledgement)信号后,也要继续执行传输操作。 某些从设备设计不规范,在正常情况下可能会返回 NACK,即使仍然有数据可以读取。使用此标志时,主设备会继续读取数据,而不会因为 NACK 停止传输。例如,读取电视的 EDID 信息时,可能会遇到这样的设备。
  • I2C_M_REV_DIR_ADDR(0x2000): 反转读写方向,即在读操作时发送写信号,写操作时发送读信号。
  • I2C_M_NOSTART(0x4000): 如果消息的标志位中包含 I2C_M_NOSTART,则会跳过 START 信号的发送,直接传输数据。这种场景比较少见,可能在一些特定硬件或者协议优化中用到。例如, 有两个连续的消息
    • 正常情况下:
  S Addr Rd [A] [Data] NA S Addr Wr [A] Data [A] P 
  S Addr Rd [A] [Data] NA S Addr Wr [A] Data [A] P
-  使用 `I2C_M_NOSTART` 后:  
S Addr Rd [A] [Data] NA S Addr Wr [A] Data [A] P 
S Addr Rd [A] [Data] NA Data [A] P
  • I2C_M_STOP(0x8000):表示在本次传输结束时,需要发送一个停止信号(STOP 信号)。如果不设置此标志,可能会继续传输后续消息。仅支持 I2C_FUNC_PROTOCOL_MANGLING 的适配器能使用此标志。

至于i2c client结构体留到 consumer 角度讲一下i2c外设 专节再细讲,只需看框架图中的介绍就行了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2214995.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

信息安全工程师(49)网络物理隔离系统与类型

前言 网络物理隔离系统是指通过物理隔离技术,在不同的网络安全区域之间建立一个能够实现物理隔离、信息交换和可信控制的系统,以满足不同安全域的信息或数据交换需求。 一、网络物理隔离系统概述 网络物理隔离系统的核心在于通过物理方式将不同安全级别的…

SQL Injection | SQL 注入概述

关注这个漏洞的其他相关笔记:SQL 注入漏洞 - 学习手册-CSDN博客 0x01:SQL 注入漏洞介绍 SQL 注入就是指 Web 应用程序对用户输入数据的合法性没有判断,前端传入后端的参数是可控的,并且参数会带入到数据库中执行,导致…

【计算机网络篇】数据链路层 协议、介质访问控制

🧸安清h:个人主页 🎥个人专栏:【计算机网络】【Mybatis篇】 🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。 系列文章目录 【计算机网络篇】计算机网络概述 【…

[实时计算flink]CREATE DATABASE AS(CDAS)语句

CDAS支持整库级别的表结构和数据的实时同步,还支持表结构变更的同步。本文为您介绍CREATE DATABASE AS(CDAS)的使用方法,并提供了多种使用场景下的示例。 背景信息 CDAS是CTAS语法的一个语法糖,用于实现整库同步、多…

在 Unity 中创建模型动画的探索之旅

在 Unity 游戏开发或 3D 场景构建中,模型动画是赋予虚拟对象生命和个性的关键元素。它能够极大地增强用户体验,使场景更加生动和吸引人。本文将带您深入了解在 Unity 中创建模型动画的基本流程和方法。 一、准备工作 在开始创建动画之前,您…

空间大数据的数据变换与价值提炼

在数字化时代,空间大数据正成为推动社会经济发展的关键因素。空间大数据不仅体量巨大,而且具有高速流转、多样类型和真实性等特点,它们在获取、存储、管理、分析方面超出了传统数据库软件工具的能力范围。地理信息系统(GIS&#x…

淘宝详情API接口有什么用处?

淘宝详情API接口有什么用处?主要体现在以下几个方面: 电商数据分析:通过调用API接口获取商品详情数据,可以对商品的销售情况、价格变化、属性分布等进行深入分析。这些数据为电商运营提供了决策支持,帮助商家更好地了…

Redis哨兵模式部署(超详细)

哨兵模式特点 主从模式的弊端就是不具备高可用性,当master挂掉以后,Redis将不能再对外提供写入操作,因此sentinel模式应运而生。sentinel中文含义为哨兵,顾名思义,它的作用就是监控redis集群的运行状况,此…

使用gradle将java项目推送至maven中央仓库(最新版)

前言 maven中央仓库于2024年3月进行改版,下面介绍新的推送方式 一、将项目推送到github 过程略 二、注册sonatype账号 仓库地址:https://central.sonatype.com/ 这里选择使用github账号登录,不注册新的了 三、创建命名空间 这里会自动…

2012年国赛高教杯数学建模D题机器人避障问题解题全过程文档及程序

2012年国赛高教杯数学建模 D题 机器人避障问题 图1是一个800800的平面场景图,在原点O(0, 0)点处有一个机器人,它只能在该平面场景范围内活动。图中有12个不同形状的区域是机器人不能与之发生碰撞的障碍物,障碍物的数学描述如下表&#xff1a…

uniapp 整合 OpenLayers - 加载Geojson数据(在线、离线)

Geojson数据是矢量数据&#xff0c;主要是点、线、面数据集合 Geojson数据获取&#xff1a;DataV.GeoAtlas地理小工具系列 实现代码如下&#xff1a; <template><!-- 监听变量 operation 的变化&#xff0c;operation 发生改变时&#xff0c;调用 openlayers 模块的…

牛只行为及种类识别数据集18g牛只数据,适用于多种图像识别,目标检测,区域入侵检测等算法作为数据集。数据集中包括牛只行走,站立,进食,饮水等不同类型的数据

18g牛只数据&#xff0c;适用于多种图像识别&#xff0c;目标检测&#xff0c;区域入侵检测等算法作为数据集。 数据集中包括牛只行走&#xff0c;站立&#xff0c;进食&#xff0c;饮水等不同类型的数据&#xff0c;可以用于行为检测 数据集中包含多种不同种类的牛只&#xff…

Eking管理易 Html5Upload 前台任意文件上传漏洞复现

0x01 产品描述&#xff1a; ‌Eking管理易是一款专为广告制品制作企业量身定制的管理软件产品&#xff0c;旨在帮助企业实现规范化、科学化管理&#xff0c;提升运营效率和降低运营成本。‌ 该软件由广州易凯软件技术有限公司开发&#xff0c;基于JAVA企业版技术研发&#xff0…

CSS 入门

1. CSS 1.1 概念 CSS&#xff08;Cascading Style Sheet&#xff09;&#xff0c;层叠样式表&#xff0c;用于控制页面的样式 CSS 能够对网页中元素位置的排版进行像素级精确控制&#xff0c;实现美化页面的效果&#xff0c;能够做到页面的样式和结构分离&#xff08;类似于…

Wi-Fi数据帧类别

网络中传送的业务数据对服务质量&#xff08;QualityofService&#xff0c;QoS&#xff09;有不同的要求&#xff0c;例如语音业务需要实时被传送&#xff0c;它对时延的大小很敏感。当W-Fi MAC层在同时传输语音业务和普通业务的数据时&#xff0c;语音业务就需要被高优先级发送…

当下的时代?

我这两天刚接触一个人,错误之皇,每做一件小事的时候他都像救命稻草一样抓着,有一天我一看,嚯,好家伙,他抱着的是已经让我仰望的参天大树了! 这个时代需要我们从无限思维的视角和做法去努力&#xff1b;它不取决于我们现在有多少&#xff0c;而取决于我们未来的成长幅度是多少&a…

动态规划算法专题(七):两个数组的dp问题

目录 1、最长公共子序列 1.1 算法原理 1.2 算法代码 2、不相交的线 2.1 算法原理 2.2 算法代码 3、不同的子序列 3.1 算法原理 3.2 算法代码 4、通配符匹配&#xff08;hard ★★★&#xff09; 4.1 算法原理 4.2 算法代码 5、正则表达式匹配&#xff08;hard ★…

Vue-admin-box后台管理框架

文章目录 1、项目概述2、技术栈3、 特色功能4、基础模板5、 项目演示6、 源码地址7、 演示地址8、小结Vue-Admin-Box,一款精心打造的Vue.js后台管理模板,旨在为开发者提供高效、美观且易于扩展的后台解决方案。它集成了现代Web开发的最佳实践,包括响应式设计、模块化开发、丰…

服务器数据恢复—服务器宕机导致挂载的V7000存储文件系统损坏的数据恢复案例

服务器存储数据恢复环境&#xff1a; 一台挂载在Windows server服务器上的v7000存储。存储空间划分了一个分区&#xff0c;采用NTFS文件系统&#xff0c;存放oracle数据库。 服务器存储故障&#xff1a; 服务器在运行过程中宕机&#xff0c;于是管理员重启服务器。服务器进入系…

针对珠宝,手表等配饰的高保真虚拟试穿解决方案IDM-VTON

今天给大家介绍一种针对配饰的高保真虚拟试穿解决方案IDM-VTON&#xff0c;该方案旨在填补当前虚拟试穿技术在高端配饰&#xff08;如珠宝和手表&#xff09;领域的空白。现有的虚拟试穿模型主要集中在服装上&#xff0c;IDM-VTON结合了2D虚拟试穿技术与其他计算机视觉模型&…