Linux i2c_driver probe被调用的流程分析(linux4.1.15)

2023-05-16

  1. linux4.1.15 i2c_driver probe被调用流程
**/*linux4.1.15 i2c_driver probe被调用的流程分析*/**
i2c_add_driver(&ap3216c_driver);					//ap3216c.c中调用
	i2c_register_driver(THIS_MODULE, driver)		//drivers\i2c\i2c-core.c
		driver_register(&driver->driver);		    //drivers\base\driver.c
			bus_add_driver(drv);					//drivers\base\bus.c
				if (drv->bus->p->drivers_autoprobe) 
					driver_attach(drv);		//drivers\base\dd.c
					driver_attach(struct device_driver *drv)	//drivers\base\dd.c
						bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); //drivers\base\bus.c

					int bus_for_each_dev(struct bus_type *bus, struct device *start,
								         void *data, int (*fn)(struct device *, void *))
							error = fn(dev, data);
								fn 既:__driver_attach(struct device *dev, void *data)  //drivers\base\dd.c
										driver_match_device(drv, dev)					//drivers\base\dd.c
										|   // 调用i2c核心i2c-core.c中的总线的match匹配函数    
										|	return drv->bus->match ? drv->bus->match(dev, drv) : 1; //drivers\base\base.h
										|   .match	= i2c_device_match				//drivers\i2c\i2c-core.c
										|		if (of_driver_match_device(dev, drv))   //drivers\i2c\i2c-core.c
										|			of_match_device(drv->of_match_table, dev) //drivers\of\device.c
										|				of_match_node(matches, dev->of_node); //drivers\of\base.c
										|					__of_match_node(matches, node);   //drivers\of\base.c
										|						__of_device_is_compatible(node, matches->compatible,
										|									matches->type, matches->name); //drivers\of\base.c
										|							__of_find_property(device, "compatible", NULL);
										|
										if (!dev->driver)
											driver_probe_device(drv, dev);					//drivers\base\dd.c
												 really_probe(dev, drv);					//drivers\base\dd.c
													if (dev->bus->probe) {
														ret = dev->bus->probe(dev);	//设备的probe,在i2c核心层drivers\i2c\i2c-core.c
													}
													即:.probe = i2c_device_probe			//drivers\i2c\i2c-core.c
														//调用用户设备驱动中的probe
														status = driver->probe(client, i2c_match_id(driver->id_table, client));
														static int ap3216c_probe(struct i2c_client *client, 
																				const struct i2c_device_id *id)
														{
															...															
														}

  1. 涉及到的文件说明
I2C-core.c 核心以及/proc/bus/i2c 接口
	i2c_register_driver(THIS_MODULE, driver)
	调用 of_driver_match_device(dev, drv)
		struct bus_type i2c_bus_type = {
		.name		= "i2c",
		.match		= i2c_device_match,
		.probe		= i2c_device_probe,
	};

drivers\base\driver.c 常规驱动 API,负责驱动的操作
	driver_register(&driver->driver);

/* 主要实现的是驱动和设备的绑定,解除,以及驱动的自动探测等功能 */ 
/* 系统一启动就会自动执行 buses_init 来注册总线子系统(bus_subsys)*/ 
drivers\base\bus.c
	bus_add_driver(drv);			//将驱动关联到总线上
	bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);

/* 负责实现驱动与设备的关联与释放操作的 */ 
drivers\base\dd.c 
	driver_attach(struct device_driver *drv) //同device_attach,区别是遍历的是drv->bus,即查找驱动
											 //所在的总线,将总线上的设备尝试关联成drv驱动
	__driver_attach(struct device *dev, void *data)
	driver_match_device(drv, dev)	
	driver_probe_device(drv, dev);	//驱动的绑定
	really_probe(dev, drv);			//调用really_probe函数进行绑定, 对dev创建link,实现dev和drive文件夹的链接,
									//调用dev->bus->probe或drv->probe进行探测
									//探测成功则driver_bound(dev)完成绑定

drivers\of\device.c 设备树相关,匹配设备
	of_match_device(drv->of_match_table, dev) 

drivers\of\base.c  设备树相关,匹配DTS节点
	of_match_node(matches, dev->of_node);
	__of_match_node(matches, node);  
  1. 架构(参考自网络)
Linux的I2C构架分为三个部分:
1)I2C core框架
	提供了核心数据结构的定义和相关接口函数,用来实现I2C适配器驱动和设备驱动的注册、注销管理,以及I2C通信方法上层的、与具体
	适配器无关的代码,为系统中每个I2C总线增加相应的读写方法。具体实现在/drivers/i2c目录下的i2c-core.c和i2c-dev.c。

 2) I2C总线驱动
	定义描述具体I2C总线适配器的i2c_adapter数据结构、实现在具体I2C适配器上的I2C总线通信方法,并由i2c_algorithm数据结构进行
	描述。经过I2C总线驱动的的代码,可以为我们控制I2C产生开始位、停止位、读写周期以及从设备的读写、产生ACK等。总线驱动具体实
	现在/drivers/i2c目录下busses文件夹中,例如Linux I2C GPIO总线驱动为i2c_gpio.c。总线算法在/drivers/i2c目录下algos文
	件夹中, 例如Linux I2C GPIO总线驱动算法实现为i2c_algo_bit.c。

 3) I2C 设备驱动
	是对具体I2C硬件驱动的实现。I2C 设备驱动通过I2C适配器与CPU通信。其中主要包含i2c_driver和 i2c_client数据结构,
	i2c_driver结构对应一套具体的驱动方法,例如:probe、remove、suspend等,需要自己申明。 i2c_client数据结构由内核根据具
	体的设备注册信息自动生成,设备驱动根据硬件具体情况填充。设备驱动具体实现放在/drivers/i2c目录下chips文件夹中。
  1. 驱动的编写
如何编写自己的i2c相关的驱动,参考方案:
(1)提供 I2C 适配器的硬件驱动,探测、初始化 I2C 适配器(如申请 I2C 的 I/O 地址和中断号)、驱动 CPU 控制的 I2C 适配器从硬
	件上产生各种信号以及处理 I2C 中断等。
(2)提供 I2C 适配器的 algorithm ,用具体适配器的 xxx_xfer() 函数填充 i2c_algorithm 的 master_xfer 指针,并把 
	i2c_algorithm 指针赋值给 i2c_adapter 的 algo 指针。
(3)实现 I2C 设备驱动与 i2c_driver 接口,用具体设备 yyy 的 yyy_attach_adapter() 函数指针、 yyy_detach_client() 函数指
	针和 yyy_command() 函数指针的赋值给 i2c_driver 的 attach_adapter 、 detach_adapter 和 detach_client 指针。
(4)实现 I2C 设备驱动的文件操作接口,即实现具体设备 yyy 的 yyy_read()yyy_write()yyy_ioctl() 函数等。
      上述工作中 12 属于I2C总线驱动,34 属于I2C设备驱动,做完这些工作,系统会增加两个内核模块。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux i2c_driver probe被调用的流程分析(linux4.1.15) 的相关文章

  • 如何让“grep”从文件中读取模式?

    假设有一个很大的文本文件 我只想打印与某些模式不匹配的行 显然 我可以使用egrep v patter1 pattern2 pattern3 现在 如果所有这些模式都在一个文本文件中怎么办 最好的制作方法是什么egrep从文件中读取模式 g
  • 从多线程程序中调用 system()

    我们正在开发一个用 C 编写的多线程内存消耗应用程序 我们必须执行大量的 shellscript linux 命令 并获取返回码 读完之后article http www linuxprogrammingblog com threads a
  • Composer 安装要求

    我正在尝试将 Composer 安装到 Laravel 项目中 当我做的时候sudo composer install在项目目录中它显示了两个错误 Problem 1 Installation request for simplesoftw
  • 设置 Apache POI 的路径

    我想创建 Excel 文件并使用 java 程序在该文件中写入数据 That is here http www techbrainwave com p 554我在 java 文件所在的位置提取了 Apache POI 并将该路径包含在路径变
  • 如何使用 sed 仅删除双空行?

    我找到了这个问题和答案 https stackoverflow com questions 4651591 howto use sed to remove only triple empty lines关于如何删除三重空行 但是 我只需要对
  • 在主目录中安装库

    在 Linux Ubuntu 中 我尝试运行一个工具 但它显示错误 库丢失 我无权在系统中安装任何内容 或者根本无法从我的用户帐户执行 sudo 是否可以在我的主目录 没有 sudo 中安装缺少的库 在我的例子中为 libstdc so 6
  • arm-linux-gnueabi 编译器选项

    我在用 ARM Linux gnueabi gcc在 Linux 中为 ARM 处理器编译 C 程序 但是 我不确定它编译的默认 ARM 模式是什么 例如 对于 C 代码 test c unsigned int main return 0x
  • 信号处理程序有单独的堆栈吗?

    信号处理程序是否有单独的堆栈 就像每个线程都有单独的堆栈一样 这是在 Linux C 环境中 来自 Linux 手册页signal 7 http kernel org doc man pages online pages man7 sign
  • 在 Linux 上的 Python 中使用受密码保护的 Excel 工作表

    问题很简单 我每周都会收到一堆受密码保护的 Excel 文件 我必须解析它们并使用 Python 将某些部分写入新文件 我得到了文件的密码 当在 Windows 上完成此操作时 处理起来很简单 我只需导入 win32com 并使用 clie
  • 如何制作和应用SVN补丁?

    我想制作一个SVN类型的补丁文件httpd conf这样我就可以轻松地将其应用到其他主机上 If I do cd root diff Naur etc httpd conf httpd conf original etc httpd con
  • 在 Linux 中禁用历史记录 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 要在 Linux 环境中禁用历史记录 我执行了以下命令 export HISTFILESIZE 0 export HISTSIZE 0 u
  • 嵌入式Linux poll()不断返回

    我有一个特别的问题 当我知道没有什么可读时 民意调查不断返回 因此设置如下 我有 2 个文件描述符 它们构成fd设置民意调查监视 一种用于引脚从高到低的变化 GPIO 另一个用于代理输入 代理输入出现问题 处理的顺序是 启动main函数 然
  • 何时使用 pthread 条件变量?

    线程问题 看来 只有在其他线程调用 pthread cond notify 之前调用 pthread cond wait 时 条件变量才起作用 如果在等待之前发生通知 那么等待将被卡住 我的问题是 什么时候应该使用条件变量 调度程序可以抢占
  • 是否可以在Linux上将C转换为asm而不链接libc?

    测试平台为Linux 32位 但也欢迎 Windows 32 位上的某些解决方案 这是一个c代码片段 int a 0 printf d n a 如果我使用 gcc 生成汇编代码 gcc S test c 然后我会得到 movl 0 28 e
  • 通过特定分隔符删除字符串

    我的文件中有几列 其中第二列有 分隔符 我想删除第二列中的第一个 第三个和第四个字符串 并将第二个字符串留在该列中 但我有正常的分隔符空间 所以我不知道 input 22 16050075 A G 16050075 A G 22 16050
  • 使用 grep 查找包含所有搜索字符串的行

    我有一个文件 其中包含很多与此类似的行 id 2796 some model Profile message type MODEL SAVE fields account 14 address null modification times
  • 如何使用 xterm.js 创建基于 Web 的终端以 ssh 进入本地网络上的系统

    我偶然发现了这个很棒的图书馆xterm js https xtermjs org 这也是 Visual Studio Code 终端的基础 我有一个非常普遍的问题 我想通过基于网络的终端 不在网络中 可能位于 aws 服务器上 访问本地网络
  • Jenkins中找不到环境变量

    我想在詹金斯中设置很多变量 我试过把它们放进去 bashrc bash profile and profile of the jenkins用户 但 Jenkins 在构建发生时找不到它们 唯一有效的方法是将所有环境变量放入Jenkinsf
  • 如何根据 HTTP 请求使用 Python 和 Flask 执行 shell 命令并流输出?

    下列的这个帖子 https stackoverflow com questions 15092961 how to continuously display python output in a webpage 我能够tail f网页的日志
  • 如何在bash中使用jq从变量中包含的json中提取值

    我正在编写一个 bash 脚本 其中存储了一个 json 值 现在我想使用 Jq 提取该 json 中的值 使用的代码是 json val code lyz1To6ZTWClDHSiaeXyxg redirect to http examp

随机推荐

  • STLINK怎么与STM32单片机连接

    STLink是ST官方开发的单片机仿真工具 xff0c 可以烧写程序 在线仿真 xff0c 使用非常方便 STLink具有两种接口 xff0c 分别为 1 SWD模式 2 SWIM单总线模式 SWD模式主要针对STM32系列的单片机 xff
  • Ubuntu 18.04系统下创建新用户

    以下介绍在Ubuntu 18 04系统下创建新用户 目录 修改用户权限及删除用户的正确方法 在Ubuntu系统上创建新用户使用 sudo useradd 用户名 命令 xff0c 但只能创建用户 xff0c 不能在 home 中创建用户目录
  • 大数据面试题(一)

    一 hdfs写文件的步骤 答案 xff1a 1 client向NameNode申请上传 xxx txt文件 2 NN向client响应可以上传文件 3 Client向NameNode申请DataNode 4 NN向Client返回DN1 D
  • packages.xml和packages.list全解析

    更多干货 xff0c 欢迎关注微信公众号 tmac lover 今天给大家介绍一下Android系统中保存app信息的两个配置文件 xff0c packages xml和packages list 系统中所有安装的app的基本信息在这里都能
  • linux中vim: command not found

    bash vim command not found 1 查看系统是否安装完整vim 2 安装vim 3 我的解决过程 解决问题步骤 xff1a 1 查看系统是否安装完整vim 执行一下命令 xff1a rpm qa grep vim 如果
  • 【FreeRTOS】任务的创建

    启动流程 LiteOS 和 ucos 第一种和第二种都可以使用 xff0c 由用户选择 xff0c RT Thread 和 FreeRTOS 则默认 创建各个任务 xff0c 然后等待启动调度器创建一个起始任务 xff0c 任务都在这个起始
  • 【FreeRTOS】信号量和互斥量

    二值信号量 同步 xff0c 创建时为空 xff0c 任务1获取 xff08 空 xff09 进入阻塞 xff1b 任务2释放信号量 xff0c 于是任务1获取信号量得以进入就绪状态 资源被获取了 xff0c 信号量值就是 0 xff0c
  • 计算机网络笔记:TCP三次握手和四次挥手过程

    TCP是面向连接的协议 xff0c 连接的建立和释放是每一次面向连接的通信中必不可少的过程 TCP连接的管理就是使连接的建立和释放都能正常地进行 三次握手 TCP连接的建立 三次握手建立TCP连接 若主机A中运行了一个客户进程 xff0c
  • echarts与highcharts学习及区别

    1 echarts用法更广泛 xff0c highcharts更适合特定的某些需求 1 1 echarts和highcharts初始引用 xff0c import as echarts from echarts html要有一个容器 xff
  • 啥是驱动?

    Q amp A 什么是驱动 xff1f 驱动本质上是一个软件程序 xff0c 是内核与硬件之间通信的桥梁 xff0c 为应用程序屏蔽了硬件细节 内核可以通过驱动程序去初始化 释放设备 xff0c 内核可以通过驱动程序与设备做双向的数据交互
  • 基于STM32F1系列的OV7725摄像头初步使用(用于摄像头循迹)

    最近做项目需要用到OV7725 xff0c 于是花了些时间研究 由于OV7725对于工作频率的要求较高 xff0c 因此使用带FIFO的摄像头模块 代码参考自正点原子官方 OV7725资源 引脚说明 以下时关于十八个引脚的说明 xff08
  • CAS SSO单点登录实例

    1 因为是本地模拟sso环境 xff0c 而sso的环境测试需要域名 xff0c 所以需要虚拟几个域名出来 xff0c 步骤如下 xff1a 2 进入目录C Windows System32 drivers etc 3 修改hosts文件
  • Ubuntu屏幕录像软件推荐-Kazam

    由于工作的关系 xff0c 需要经常录制一些软件的操作步骤当做教程 xff0c 现在由于使用了Ubuntu单系统平台 xff0c 以前录制的教程均不能正常运行了 xff0c 需要切换到VM xp里面使用 xff0c 造成很大的不变 xff0
  • 图像畸变矫正——透视变换

    图像畸变矫正 透视变换 由于相机制造精度以及组装工艺的偏差引入的畸变 xff0c 或者由于照片拍摄时的角度 旋转 缩放等问题 xff0c 可能会导致原始图像的失真 xff0c 如果要修复这些失真 xff0c 我们可以通过透视变换 xff0c
  • 微信JSAPI支付,微信浏览器内支付,解决微信H5支付只能在微信外浏览器支付的问题

    一 设置支付目录 请确保实际支付时的请求目录与后台配置的目录一致 xff08 现在已经支持配置根目录 xff0c 配置后有一定的生效时间 xff0c 一般5分钟内生效 xff09 xff0c 否则将无法成功唤起微信支付 在微信商户平台 xf
  • 解决python3 与 ROS中使用python2冲突的问题(亲测有效)

    文章转载于 https zhuanlan zhihu com p 27011617 方法一 xff1a conda install setuptools pip install U rosdep rosinstall generator w
  • Radmin FAQ

    故障排除提示 xff0c 技术指南 xff0c 文章方法 xff0c 反馈表等 通过主机选项连接 1 此选项使您可以在没有与要管理的计算机的直接 TCP IP 连接时通过主机进行连接 xff0c 但中间主机与目标计算机 xff08 网关等
  • 关于相机内参与外参的浅读

    学习人脸3D重建的第一天 xff0c 在首次接触3D相关的内容 xff0c 必须要搞清楚相机的成像原理 xff0c 如何将真实三维空间中的三维点与显示器 屏幕和图像等二维成像的平面映射 xff0c 以及了解该过程的推导方式和相关坐标系的换算
  • 嵌入式以及嵌入式行业的基本信息

    从技术实现上讲 xff0c 嵌入式的产品分为两大类 xff1a 一类简单的 xff0c 没有操作系统支持的 一类复杂的 xff0c 有操作系统的 就目前发展方向看 xff0c 后一种是趋势 前一种从程序实现上可分为3层 xff1a 硬件层
  • Linux i2c_driver probe被调用的流程分析(linux4.1.15)

    linux4 1 15 i2c driver probe被调用流程 span class token operator span span class token operator span span class token comment