I2C总线(一)核心

news2024/11/26 14:35:13

基于linux-3.14.16

一、简介

硬件上,i2c总线由,i2c控制器、i2c总线、i2c设备组成。
在这里插入图片描述
驱动代码将通过设置i2c寄存器,从而在总线上产生数据信息,来和i2c设备通信(读/写)。

i2c核心,主要的功能包括:
1、注册i2c总线类型(Linux设备驱动模型(二)总线,总线驱动和总线设备,有讲到),及定义其附属接口,比如注册i2c设备,注册i2c总线,等等。。。

2、定义i2c总线软件上的规范,

二、注册i2c总线

i2c核心在内核启动,将会执行 i2c_init,做的事情,主要是
注册 i2c总线
注册一个i2c驱动 dummy_driver
在这里插入图片描述

看下i2c总线的定义,注意有,match,probe
设备驱动模型,我们了解到,当有新的驱动或者设备添加,将会调用match,和probe。
在这里插入图片描述

记录一下,同时注册的i2c驱动,目前还不了解,具体用处
仅仅记录一下
在这里插入图片描述

至此,就能在内核中添加i2c驱动和i2c设备了。。。

三、重要接口

1、注册i2c控制器设备

调用 i2c_add_numbered_adapter 注册 i2c 控制器/适配器,
在这里插入图片描述

nr在之前就被复制为pdev->id,所以会走__i2c_add_numbered_adapter,但不管走哪个,最终都会调用i2c_register_adapter,,直接看 i2c_register_adapter 干了啥。
在这里插入图片描述

static int i2c_register_adapter(struct i2c_adapter *adap)
{
	int res = 0;

	// 这里做了一些判断,,我们不必关心
	/* Can't register until after driver model init */
	if (unlikely(WARN_ON(!i2c_bus_type.p))) {
		res = -EAGAIN;
		goto out_list;
	}

	/* Sanity checks */
	if (unlikely(adap->name[0] == '\0')) {
		pr_err("i2c-core: Attempt to register an adapter with "
		       "no name!\n");
		return -EINVAL;
	}
	if (unlikely(!adap->algo)) {
		pr_err("i2c-core: Attempt to register adapter '%s' with "
		       "no algo!\n", adap->name);
		return -EINVAL;
	}

	rt_mutex_init(&adap->bus_lock);
	mutex_init(&adap->userspace_clients_lock);
	INIT_LIST_HEAD(&adap->userspace_clients);

	/* Set default timeout to 1 second if not already set */
	if (adap->timeout == 0)
		adap->timeout = HZ;

	// 下面是注册 i2c 控制器过程
	// 1、根据i2c 控制器的标号,对 i2c_adapter 的设备命名,,
	//    这里可以看出来,这里注册的适配器,其实在i2c总线中是以,设备存在
	dev_set_name(&adap->dev, "i2c-%d", adap->nr);
	// 2、设置设备所属的总线,这里是i2c,前面开机注册的
	adap->dev.bus = &i2c_bus_type;
	// 3、对设备设置文件属性,将会在sysfs中的i2c-1中看到
	adap->dev.type = &i2c_adapter_type;
	// 4、向总线注册设备
	res = device_register(&adap->dev);
	if (res)
		goto out_list;


	dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);

#ifdef CONFIG_I2C_COMPAT
	res = class_compat_create_link(i2c_adapter_compat_class, &adap->dev,
				       adap->dev.parent);
	if (res)
		dev_warn(&adap->dev,
			 "Failed to create compatibility class link\n");
#endif

	/* bus recovery specific initialization */
	if (adap->bus_recovery_info) {
		struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;

		if (!bri->recover_bus) {
			dev_err(&adap->dev, "No recover_bus() found, not using recovery\n");
			adap->bus_recovery_info = NULL;
			goto exit_recovery;
		}

		/* Generic GPIO recovery */
		if (bri->recover_bus == i2c_generic_gpio_recovery) {
			if (!gpio_is_valid(bri->scl_gpio)) {
				dev_err(&adap->dev, "Invalid SCL gpio, not using recovery\n");
				adap->bus_recovery_info = NULL;
				goto exit_recovery;
			}

			if (gpio_is_valid(bri->sda_gpio))
				bri->get_sda = get_sda_gpio_value;
			else
				bri->get_sda = NULL;

			bri->get_scl = get_scl_gpio_value;
			bri->set_scl = set_scl_gpio_value;
		} else if (!bri->set_scl || !bri->get_scl) {
			/* Generic SCL recovery */
			dev_err(&adap->dev, "No {get|set}_gpio() found, not using recovery\n");
			adap->bus_recovery_info = NULL;
		}
	}

exit_recovery:
	/* create pre-declared device nodes */
	of_i2c_register_devices(adap);
	acpi_i2c_register_devices(adap);

	// 按条件扫描 board_info,这个board_info 我们知道,写驱动的时候就是注册的 i2c_board_info
	// 关于注册 i2c_board_info 的接口,后面分析,印证。。。。
	if (adap->nr < __i2c_first_dynamic_bus_num)
		i2c_scan_static_board_info(adap);

	// 遍历 i2c 总线上的驱动,以驱动和适配器为参数,执行 __process_new_adapter,
	// __process_new_adapter 做了什么,稍后分析...
	/* Notify drivers */
	mutex_lock(&core_lock);
	bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
	mutex_unlock(&core_lock);

	return 0;

out_list:
	mutex_lock(&core_lock);
	idr_remove(&i2c_adapter_idr, adap->nr);
	mutex_unlock(&core_lock);
	return res;
}

注册适配后,会遍历全局链表,__i2c_board_list ,对属于该适配器的设备,创建一个新的 i2c 设备
在这里插入图片描述

关于 __process_new_adapter 做的事情,,
1、
2、如果
在这里插入图片描述

i2c_adapter

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

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

相关文章

spring boot 配置多数据源 踩坑 BindingException: Invalid bound statement (not found)

在上一篇&#xff1a;《【已解决】Spring Boot多数据源的时候&#xff0c;mybatis报错提示&#xff1a;Invalid bound statement (not found)》 凯哥(凯哥Java) 已经接受了&#xff0c;在Spring Boot配置多数据源时候&#xff0c;因为自己马虎&#xff0c;导致的一个坑。下面&a…

【操作系统】实验一 熟悉LINUX环境和命令

实验名称&#xff1a; 实验一 熟悉LINUX环境和命令 实验目的&#xff1a; 1. 了解UNIX/LINUX的命令及使用格式。 2.熟悉UNIX/LINUX的常用基本命令。 3. 练习并掌握LINUX提供的vi编辑器来编译C程序 4. 学会利用gcc、gdb编译、调试C程序 实验内容&#xff1a; 熟悉UNIX/LINUX的…

YOLOv5改进 | 卷积篇 | SPD-Conv空间深度转换卷积(高效空间编码技术)

一、本文介绍 本文给大家带来的改进内容是SPD-Conv&#xff08;空间深度转换卷积&#xff09;技术。SPD-Conv是一种创新的空间编码技术&#xff0c;它通过更有效地处理图像数据来改善深度学习模型的表现。SPD-Conv的基本概念&#xff1a;它是一种将图像空间信息转换为深度信息…

Java_Lambda表达式JDK8新特性(方法引用)

一、Lambda表达式 接下来&#xff0c;我们学习一个JDK8新增的一种语法形式&#xff0c;叫做Lambda表达式。作用&#xff1a;用于简化匿名内部类代码的书写。 1.1 Lambda表达式基本使用 怎么去简化呢&#xff1f;Lamdba是有特有的格式的&#xff0c;按照下面的格式来编写Lamd…

如何用Python向图像中加入噪声

我们在做机器视觉项目的过程中&#xff0c;有的时候需要向图像中加入噪声。Pytorch本身不支持类似的功能&#xff0c;如果自己写的话&#xff0c;不但麻烦&#xff0c;而且容易出错。好在skimage支持这个功能。代码如下&#xff1a; import skimage import matplotlib.pyplot …

Web安全漏洞分析—文件包含

在当今数字化时代&#xff0c;随着Web应用程序的广泛应用&#xff0c;网络安全问题愈加凸显。其中&#xff0c;文件包含漏洞作为一种常见但危险的安全隐患&#xff0c;为恶意攻击者提供了可乘之机。在这篇博客中&#xff0c;我们将深入探讨文件包含漏洞的本质、攻击手法以及应对…

信息收集 - 域名

1、Whois查询: Whois 是一个用来查询域名是否已经被注册以及相关详细信息的数据库(如:域名所有人、域名注册商、域名注册日期和过期日期等)。通过访问 Whois 服务器,你可以查询域名的归属者联系方式和注册时间。 你可以在 域名Whois查询 - 站长之家 上进行在线查询。 2、…

python提取图片型pdf中的文字(提取pdf扫描件文字)

前言 文字型pdf提取&#xff0c;python的库一大堆&#xff0c;但是图片型pdf和pdf扫描件提取&#xff0c;还是有些难度的&#xff0c;我们需要用到OCR&#xff08;光学字符识别&#xff09;功能。 一、准备 1、安装OCR&#xff08;光学字符识别&#xff09;支持库 首先要安…

详解git pull和git fetch的区别

git pull和git fetch的区别, 网上人云亦云胡说八道的实在是太多了&#xff0c;误导我很久。 今天看到一个说得好的&#xff0c;记录一下。 前言 在我们使用git的时候用的更新代码是git fetch&#xff0c;git pull这两条指令。但是有没有小伙伴去思考过这两者的区别呢&#xff…

vue3引入Echarts图表

说明&#xff1a;echarts是父组件&#xff0c;stack是子组件&#xff0c;将stack引入到echarts文件中 查看echarts.vue时可看到stack.vue中的图表 # # # 引入方式 第一步 Echarts官网&#xff1a;快速上手 - 使用手册 - Apache ECharts 第二步 在控制台安装Echarts模块…

8.完成任务实现的SDK封装及插件式加载

1.设计 任务的实现目前完成了Modbus RTU、Modbus TCP、Virtule。任务实现应该是任意的&#xff0c;比如打印一段话&#xff0c;执行一句SQL等&#xff0c;所以系统内部的必然要做到可扩展。 要做到可扩展&#xff0c;首先第一步就是定义标准&#xff0c;所以我们首先需要封装…

nodejs+vue+微信小程序+python+PHP基于大数据的银行信用卡用户的数仓系统的设计与实现-计算机毕业设计推荐

银行信用卡用户的数仓系统综合网络空间开发设计要求。目的是将银行信用卡用户的数仓系统从传统管理方式转换为在网上管理&#xff0c;完成银行信用卡用户的数仓管理的方便快捷、安全性高、交易规范做了保障&#xff0c;目标明确。银行信用卡用户的数仓系统可以将功能划分为管理…

从文字下乡到人人学英语

从建国到改革开放&#xff0c;从恢复高考到新式教育改革&#xff0c;中国飞速发展&#xff0c;文字需求也在不断增大&#xff0c;在“地球村”的时代下&#xff0c;我们要“习文字之变&#xff0c;顺时代发展。” 古言道&#xff1a;“仓颉作书&#xff0c;后稷作稼”&#xff…

【Spark面试】Spark面试题答案

目录 1、spark的有几种部署模式&#xff0c;每种模式特点&#xff1f;&#xff08;☆☆☆☆☆&#xff09; 2、Spark为什么比MapReduce块&#xff1f;&#xff08;☆☆☆☆☆&#xff09; 3、简单说一下hadoop和spark的shuffle相同和差异&#xff1f;&#xff08;☆☆☆☆☆…

Linux学习教程(第十三章 Linux数据备份与恢复)

第十三章 Linux数据备份与恢复 不知道大家有没有丢失过重要的数据呢&#xff1f; 丢失数据的理由是多种多样的&#xff0c;有人是因为重装系统时&#xff0c;没有把加密文件的密钥导出&#xff0c;重装系统后密钥丢失&#xff0c;导致所有的加密数据不能解密&#xff1b;也有人…

实验记录:深度学习模型收敛速度慢有哪些原因

深度学习模型收敛速度慢有哪些原因&#xff1f; 学习率设置不当&#xff1a; 学习率是算法中一个重要的超参数&#xff0c;它控制模型参数在每次迭代中的更新幅度。如果学习率过大&#xff0c;可能会导致模型在训练过程中的振荡&#xff0c;进而影响到收敛速度&#xff1b;如果…

字符设备驱动框架的编写

一. 简介 我们在学习裸机或者 STM32 的时候关于驱动的开发就是初始化相应的外设寄存器&#xff0c;在 Linux 驱动开发中&#xff0c;肯定也是要初始化相应的外设寄存器。 只是在 Linux 驱动开发中&#xff0c; 我们需要按照其规定的框架来编写驱动&#xff0c;所以说学 …

【网络安全】网络防护之旅 - Java安全机制探秘与数字证书引爆网络防线

&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《网络安全之道 | 数字征程》⏰墨香寄清辞&#xff1a;千里传信如电光&#xff0c;密码奥妙似仙方。 挑战黑暗剑拔弩张&#xff0c;网络战场誓守长。 目录 &#x1f608;1. 初识网络安…

机场信息集成系统系列介绍(3):机场运行核心数据库(AODB)

目录 1、背景&#xff1a;什么是AODB 2、AODB包括哪些内容 3、AODB还应该适配哪些场景 4、一点点拓展 机场运行核心数据库&#xff08;AODB&#xff09;Airport Operation DataBase 1、背景&#xff1a;什么是AODB 在机场繁重的航班保障和旅客服务背后&#xff0c;庞大的…

centos安装了curl却报 -bash: curl: command not found

前因 我服务器上想用curl下载docker-compress&#xff0c;发现没有curl命令&#xff0c;就去下载安装&#xff0c;安装完成之后&#xff0c;报-bash: curl: command not found 解决方法 [rootcentos ~]# rpm -e --nodeps curl warning: file /usr/bin/curl: remove failed: …