04_iic子系统

news2025/1/17 14:05:25

总结

iic_client和iic_driver 加入iic总线的思想和paltform总线的玩法一样
把iic设备和驱动注册到iic总线中 构造出字符设备驱动和设备节点供app进行操作
但是iic硬件设备是挂在iic控制器下面的 所以iic控制器也会有自己的驱动和设备树节点 厂家一般都会帮做好
我们写的iic_driver驱动程序 控制iic硬件的时候 使用iic总线提供的api 来控制iic硬件设备
在这里插入图片描述
详细介绍分两部分 一个是iic设备驱动程序 一个是iic控制器驱动介绍

iic控制器驱动

芯片的iic控制器抽象成 一个iic_adapter (一般这个控制器的驱动和设备节点芯片厂商都帮创建好了)
iic_algotithm 也构建好了

linux 上电注册iic总线 drivers/i2c/i2c-core-base.c


static int __init i2c_init(void)
	bus_register(&i2c_bus_type); //很熟悉的总线注册
IIC总线匹配规则 也就是看总线上的.match函数
 - of_driver_match_device:设备树匹配方式
  - 比较 I2C 设备节点的 compatible 属性和 of_device_id 中的 compatible 属性

- acpi_driver_match_device : ACPI 匹配方式
- i2c_match_id:i2c总线传统匹配方式
  - 比较 I2C设备名字和 i2c驱动的id_table->name 字段是否相等

构造iic_适配器设备树节点

下面用IIC1控制器来举例子
i2c1: i2c@21a0000 {
				#address-cells = <1>;
				#size-cells = <0>;
				compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";
				reg = <0x21a0000 0x4000>;  //reg属性记录了IIC寄存器组的地址
				interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
				clocks = <&clks IMX6UL_CLK_I2C1>;
				status = "disabled";
			};  

适配器的驱动与之匹配

这个就是厂商写的适配器驱动 但只是在和设备树匹配后
应该是存了个什么东西给 适配器万能驱动调用

plantform_driver.probe
	struct resource *res;
	void __iomem *base;
	of_device_id *of_id = of_match_device(i2c_imx_dt_ids,&pdev->dev);
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);//获取resource资源,放到设备树就是reg = <0x21a0000 0x4000>;
	base = devm_ioremap_resource(&pdev->dev, res);//对resource物理地址和虚拟地址映射,此时base记录了虚拟地址
	phy_addr = (dma_addr_t)res->start;//这里记录物理地址,直接从resource->start拿取
	i2c_imx = devm_kzalloc(&pdev->dev, sizeof(*i2c_imx), GFP_KERNEL);//分配内存
	i2c_imx->adapter.algo		= &i2c_imx_algo;//初始化运算器,用于直接操作硬件的代码
	ret = i2c_add_numbered_adapter(&i2c_imx->adapter);//在linux注册一个i2c_adap
	
static const struct i2c_algorithm i2c_imx_algo = {  //运算器结构体
	.master_xfer	= i2c_imx_xfer,//产生IIC通讯时序,负责数据收发
	.functionality	= i2c_imx_func,//查询iic通信协议类型,iic通讯协议有一大类
};
	
	
.master_xfer
	result = i2c_imx_start(i2c_imx);//发送IIC的启动信号
	...
	for (i = 0; i < num; i++) {  //在for循环里面发送数据
		if (i == num - 1)
			is_lastmsg = true;
	result = i2c_imx_bus_busy(i2c_imx, 1);//判断当前iic总线是否忙
	if (msgs[i].flags & I2C_M_RD) //不忙判断当前信息需要读还是写
			result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg);//这里真正控制IIC的寄存器进行发送读取
		else {
			if (i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD)
				result = i2c_imx_dma_write(i2c_imx, &msgs[i]);
			else
				result = i2c_imx_write(i2c_imx, &msgs[i]);
		}	

IIC核心函数和万能驱动!!! i2c-dev.c

iic设备驱动程序

struct i2c_client
struct device dev; 继承了 struct device 符合linux驱动设备模型
linux根据IIC设备节点自动生成i2c_client节点

struct i2c_client {
	unsigned short flags;		/* div., see below		*/
	unsigned short addr;		/* 7位地址	*/

	char name[I2C_NAME_SIZE];
	struct i2c_adapter *adapter;	/* the adapter we sit on	*/
	struct device dev;		/* 继承了 struct device 符合linux驱动设备模型		*/
	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
};

struct i2c_driver {
	unsigned int class;

	/* Standard driver model interfaces */
	int (*probe)(struct i2c_client *, const struct i2c_device_id *);
	int (*remove)(struct i2c_client *);
	...
	struct device_driver driver;
	const struct i2c_device_id *id_table;
	...
}

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

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

相关文章

离散系统的数字PID控制仿真-2

设计离散PID控制器&#xff0c;各信号的跟踪结果如图所示&#xff0c;其中S代表输入指令信号的类型。通过取余指令 mod实现三角波和锯齿波。当S1时为三角波&#xff0c;S2时为锯齿波&#xff0c;S3时为随机信号。在仿真过程中&#xff0c;如果 D1&#xff0c;则通过 pause命令实…

Prometheus学习整理-Prometheus-operator

Prometheus中的promQL语句: Prometheus提供的一种promQL语法,用来处理接口数据,然后方便用户对数据进行处理加工,它是Prometheus专门提供的一个函数表达式语言,可以实时的查询和聚合时间序列的数据,通过HTTPApi的方式提供给外部使用,PromQL主要分为下面的几种类型数据: 这里面的…

【老卫搞机】136期:华为开发者联盟社区2022年度战码先锋2期开源贡献之星

首先祝大家兔年大吉&#xff0c;身体安康&#xff0c;钱兔似锦&#xff01;接上次的“2022年牛人之星”&#xff08; https://developer.huawei.com/consumer/cn/forum/topic/0203109930647268095&#xff09;&#xff0c;今天咱们来开箱另外一件特殊的奖品&#xff0c;来自华为…

MySQL内外连接

文章目录MySQL内外连接内连接外连接左外连接右外连接简单案例MySQL内外连接 表的连接分为内连接和外连接。 内连接 内连接 内连接的SQL如下&#xff1a; SELECT ... FROM t1 INNER JOIN t2 ON 连接条件 [INNER JOIN t3 ON 连接条件] ... AND 其他条件;说明一下&#xff1a; …

零基础学JavaWeb开发(二十三)之 springmvc入门到精通(3)

5、springspringmvcmybatis整合 5.1、项目技术需求分析 1.使用ssmlayui技术开发 对用户表数据实现增删改查 采用前后端分离架构模式 5.2、SSM环境的整合之提供增删改查 整合数据库表结构 CREATE TABLE mayikt_users (id int NOT NULL AUTO_INCREMENT,name varchar(255) CH…

Mysql入门技能树-使用数据库

创建和删除数据库 Joe 在开发机上创建了一个名为 goods 的数据库&#xff0c;做了一些练习&#xff0c;现在他需要删除这个数据库&#xff0c;重建一个 goods。那么他需要的步骤是&#xff1a; 答案是&#xff1a;A 创建数据库的语法格式如下&#xff1a; CREATE DATABASE d…

client-go实战之九:手写一个kubernetes的controller

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)&#xff1a;https://github.com/zq2599/blog_demos 系列文章链接 client-go实战之一&#xff1a;准备工作client-go实战之二:RESTClientclient-go实战之三&#xff1a;Clientsetclient-go实战之四&#xff1a;…

Java IO流之字符集总结

ASCII字符集、GBK字符集、Unicode字符集 这里我直接上总结了&#xff0c;关于这三种字符集的基本介绍大家可以百度一下。 在计算机中&#xff0c;任意数据都是以二进制的形式来存储的计算机中最小的存储单元是一个字节ASCII字符集中&#xff0c;一个英文占一个字节简体中文版Wi…

CQF量化金融职业指南

✏️写作&#xff1a;个人博客&#xff0c;InfoQ&#xff0c;掘金&#xff0c;知乎&#xff0c;CSDN &#x1f4e7;公众号&#xff1a;进击的Matrix &#x1f6ab;特别声明&#xff1a;原创不易&#xff0c;未经授权不得转载或抄袭&#xff0c;如需转载可联系小编授权。 概述 …

二分查找算法的实现以及解决整数溢出问题

前言 从今天起我会开启一个专栏&#xff1a;Java面试八股文,记录一下我在网上学到的Java面试常考的一些内容&#xff0c;注意:本人暂无面试经验&#xff0c;只是在网上找视频学习到的❗❗❗ 二分查找 我们首先要学习的是二分查找&#xff0c;我相信很多人跟我一样&#xff0c;在…

MySQL - text字段

一、text属性 MySQL下的TEXT属性一种特殊的字符串&#xff0c;存储单位为字节&#xff0c;有四种类型 TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT 不同的是可以存储的字符串的长度以及空间占用大小 TINYTEXT最大存放长度为255个字符的字符串 TEXT最大存放长度为65535个字符的…

XlsReadWriteII EXCEL Cell 单元数据读写

XlsReadWriteII EXCEL Cell 单元数据读写 下面从编程的眼光&#xff0c;从XlsReadWriteII的角度&#xff0c;谈谈EXCEL的理解。回顾一下EXCEL发展史&#xff1a; 1982年&#xff1a;微软推出了它的第一款电子表格软件&#xff1a;Multiplan。 1985年&#xff1a;推出了…

Day06 C++STL入门基础知识三——String容器(下)比较-存取-插入-删除-子串获取【全面深度剖析+例题代码展示】

永远相信&#xff0c;美好的事情即将发生&#xff01; 文章目录1. 比较操作1.1 比较方式1.2 函数原型1.3 代码展示2. 字符读写2.1 字符读入/访问2.1.1 方式2.1.2 代码展示2.2 修改字符2.2.1 方式2.2.2 代码展示3. 插入和删除3.1 函数原型3.2 代码展示4. 截取子串(比较实用!!!)4…

蓝桥杯STM32G431RBT6学习——定时器输入捕获

蓝桥杯STM32G431RBT6学习——定时器输入捕获 前言 从省赛的题目来看&#xff0c;对于定时器输入捕获这块几乎不考&#xff0c;但是为了知识的完整性及避免万一&#xff0c;依旧有了解的必要。国信长天开发板上的定时器捕获主要针对于NE555波形发生器的方波进行频率、脉宽等测…

恶意代码分析实战 3 IDA Pro

利用IDA PRO分析Lab05-01.dll 实验目的 利用IDA Pro分析Lab05-01.dll中发现的恶意代码&#xff0c;回答以下问题&#xff1a; DLLMain的地址是什么&#xff1f; 可以空格转入反汇编查看DLLMain地址&#xff0c;或者 DLLMain的地址是.text:0x1000D02E。 使用Imports窗口并浏…

这几个步骤,让你的电脑避免卡顿~

C盘主要是系统运行的存储空间&#xff0c;如果C盘装满了东西&#xff0c;那就意味着电脑的存储空间小&#xff0c;电脑运行就会更慢。&#x1f62f; 另外&#xff0c;桌面上的文件也属于C盘&#xff0c;所以桌面也不要放太多东西。除装机时候的一些必要软件&#xff0c;后期装的…

SpringBoot切换数据源

基本使用添加依赖<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.3.0</version> </dependency>数据源配置spring:datasource:dynamic:primary: fir…

【多元统计分析】Python实现对应分析

&#xff08;一&#xff09;题目要求 数据集包含地区生产总值的四个相关指标&#xff1a;x1劳动者报酬&#xff0c;x2生产税净额&#xff0c;x3固定资产折旧&#xff0c;x4营业盈余。对各个地区生产总值进行对应分析&#xff0c;揭示不同地区的生产总值构成特征。要求&#xf…

对多线程中线程池的理解

一.概念理解何为线程池&#xff1f;线程池的释义正如它的命名&#xff1a;专门用来存放线程的池子&#xff08;集合类&#xff09;&#xff0c;也就是将线程存储于集合类&#xff0c;使用时从线程池中直接获取&#xff0c;使用结束后将线程放回集合类即可&#xff0c;这样就避免…

macOS Ventura 13.2 (22D49) Boot ISO 原版可引导镜像

本站下载的 macOS Ventura 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。 2023 年 1 月 23 日&#xff08;北京时间 24 日凌晨&#xff09;&#xff0c;m…