I2C是广泛应用于计算机中的串行总线,用于处理器和其外设之间的通信。 I2C硬件基本概念 I2C总线由两根传递数据的双向信号线与一根地线组成,半双工、主从方式通信。...总线速度有三种模式 标准模式 100kbps 快速模式 400kbps 高速模式 3.4Mbps I2C子系统框架 I2C设备驱动层:drivers/i2c/i2c-dev.c (通用型) 或者为特定设备定制的设备驱动...笔者会大体上对I2C子系统的源码进行分析,如若分析的有出入,还望指出。 I2C核心层 I2C核心层的实现位于drivers/i2c/i2c-core.c中,笔者从i2c_init函数开始分析。...核心层分析可知,I2C总线是根据id_table进行匹配,所以这里并不会按照常规的Linux驱动模型进行match后probe,况且这个驱动里也没有probe方法。...); 把关注点放在初始化I2C控制器的s3c24xx_i2c_init函数和申请IRQ上。
比较 I2C 设备节点的 compatible 属性和 of_device_id 中的 compatible 属性是否相等,如果相当的话就表示 I2C 设备和驱动匹配。...比较 I2C 设备名字和 i2c_device_id 的 name 字段是否相等,相等的话就说明 I2C 设备和驱动匹配。...其中,Linux 内核将 SOC 的 I2C 适配器(控制器)抽象成 i2c_adapter。...当 I2C 设备和驱动匹配以后,probe 函数就会执行。...因此,对于 Linux 来讲,不区分 I2C 控制器和 I2C 从机设备,用的都是同一套东西,即【总线、设备、驱动】框架,都有 probe 函数。
I2C spec 和 I3C spec 已经写完了(5+2=7篇),现在来写 I2C Driver 部分。...】由普通驱动工程师负责,【i2c 核心层】由 Linux 提供,【i2c 核心层】以下由芯片原厂负责。...I2C 子系统通过 i2c-core 将 i2c 设备驱动和 i2c 总线驱动进行了分离,从而使得 i2c 设备驱动中不用关心 i2c 总线传输细节,专注于 i2c 设备逻辑的实现。...抽象如下: I2C 总线驱动重点是 I2C 适配器(控制器)驱动,这里用到两个重要的数据结构:i2c_adapter 和 i2c_algorithm。...在 Linux 系统中有如下节点: 2、I2C Data Structure 我们要搞懂一个 Linux 子系统,必须研究它的数据结构,搞懂每个结构体存储了什么东西,才能梳理清楚该子系统的架构。
3、I2C Transfer Definition of timing 想要深入探讨 I2C 协议,必须深刻理解各种时间的定义(F/S-mode) 标识符 定义 tf 信号下降时间 tr 信号上升时间...tLOW 信号低电平时间 tHIGH 信号高电平时间 tHD;DAT 数据保持时间 tSU;DAT 数据建立时间 tSP 输入滤波器必须抑制的毛刺脉宽 tBUF 启动和停止条件的空闲时间 tHD;STA...SDA 在 SCL 是低电平期间变换数据,不可以在 SCL 高电平期间变换数据,否则会认为是 起始和停止条件。...不支持从设备在 SCL 和 SDA 总线上发起一个中断,通知主设备来读数据。...I3C 则不存在这种问题,I3C 允许从设备在 SCL 和SDA 上发起中断,叫“带内中断”,I3C 后面会讲。
I2C 常见有两种错误:I2C ACK error、I2C timeout 1、I2C ACK error 在应该收到 ACK 信号的时候没有收到 ACK 信号,i2c controller 就会产生一个...1、检查 device 是否存在,i2c bus number 和 device address 是否正确。...I2C 模式 GPIO 是否有内部上拉电阻 GPIO 默认电平状态 2、排查 slave 顺序 log 中第一个发生 timeout 的 slave 有 power 控制和 reset 控制的 slave...2)隐藏的 i2c address,即外设存在多个 i2c addr 或外设 HW bug,导致 i2c 通讯异常。...此毛刺不会影响 I2C 总线读写时序,无需处理。 即 slave 和 master 控制总线切换间隔,没有人控制总线,带来的毛刺。
I2C 系列文章主要分为两个部分来写: 1、I2C spec:研究 I2C 协议本身,研究它的协议规范、传输机制。 2、I2C driver:研究 Linux I2C 驱动。...I2C 的速度 I2C 是一种低速、串行总线,有 SDA(串行数据线) 和 SCL(串行时钟线) 两条信号线,半双工通信。...slaver 端通过设备地址区分,有 7bits 和 10 bits 等地址,还有一种 8bits 地址,实际上是 7bits + 读写位。...但是 I2C 协议规定,总线上的电容不可以超过 400pF。管脚都是有输入电容的,PCB上也会有寄生电容,所以会有一个限制。 实际设计中经验值大概是不超过 8 个器件。...总线之所以规定电容大小,是因为 I2C 使用的 GPIO 为开漏结构,要求外部有电阻上拉,电阻和总线电容产生了一个 RC 延时效应,电容越大信号的边沿就越缓,有可能带来信号质量风险(方波变三角波)。
4、I2C Synchronization And Arbitration 本文讲解三个重要的 I2C 概念:时钟延展、同步、仲裁 Data and ACK/NACK 正常情况 主接收机必须向从机发送传输结束的信号...这也是 I2C 通信系统中,从机唯一能控制总线的时候! 关键是很多 I2C 主机不支持 clock stretching 功能,所以,无法和带有 clock stretching 功能的从机通信!...总线上有多个节点,它们都有自己的寻址地址,可以作为从节点被别的节点访问,同时它们都可以作为主节点向其他的节点发送控制字节和传送数据。...要解决这种冲突,就要进行仲裁的判决,这就是 I2C 总线上的仲裁。 I2C 总线上的仲裁分两部分:SCL 线的同步和 SDA 线的仲裁,这两部分没有先后关系,同时进行。...再次提醒:SDA仲裁和SCL时钟同步处理过程没有先后关系,而是同时进行的。
i2c_master_send 和 i2c_master_recv 都是对 i2c_transfer 的封装。因此我们重点研究 i2c_transfer。...该函数和芯片底层强相关,是最底层的实现,一般情况下不会修改。重要的地方博主放了注释。...); return -ENXIO; } return 0; } mtk_i2c_irq:中断处理函数,在 I2C 传输 ACKERR 和传输 STOP 时触发。...msg_complete); } return IRQ_HANDLED; } 优先级翻转与优先级继承 优先级翻转在可剥夺内核中是非常常见的,例子如下(H:High、M:Middle、L:Low) 任务 H 和任务...Linux 用 rt_mutex 来解决该问题,rt_mutex 是带优先级继承的互斥锁。
5、I2C Hs-mode HS mode 为什么单独讲解?因为高速模式和其他模式有很多不一样的地方。 速度高达 3.4MHz。...减轻了SDAH 和 SCLH 线的电容负载,使上升和下降时间更快。 Hs 模式从机器件与 F/S 从机器件的唯一差别是它们工作的速度。Hs 模式从机在 SCLH 和 SDAH输出有开漏输出的缓冲器。...如果快速模式器件的电源电压被关断,SDA 和 SCL 的 I/O 管脚必须悬空,不能阻塞总线。 连接到总线的外部上拉器件必须调整以适应快速模式 I2C 总线更短的最大允许上升时间。...的总线,每条总线的上拉器件可以是一个电阻;对于负载在 200pF~400pF 之间的总线,上拉器件可以是一个电流源(最大值 3mA)或者是一个开关电阻电路,如下图: 只有 Hs 模式器件的系统的物理 I2C...总线配置 (可选)串联电阻器 Rs 保护 I2C 总线设备的 I/O 免受总线上的高压尖峰影响,并将振铃和干扰降至最低。
2、I2C Architecture I2C 采用的 GPIO 一般为开漏模式,支持线与功能,但是开漏模式无法输出高电平,所以需要外部上拉。...所以开漏输出的外部上拉电阻要兼顾速度和功耗。上拉电阻小,信号边沿陡峭,信号好,但是功耗高。...计算上拉电阻的阻值,有明确计算公式: 最大电阻和上升沿时间 tr 、总线电容 Cb 、标准上升沿时间 0.8473 有关。...最小电阻和电源Vdd电压、GPIO口自己最大输出电压 Vol、 GPIO口自己最大电流 Vol 有关。...采用合适的电源电压和合适的上拉电阻,才会让你的 I2C 传输信号最优。上拉电阻选小了,会使得总线电流大,端口输出的低电平会变大(一般低电平不允许超过0.4V)。
对于 Linux 常用版本,kernel-4.14 和 kernel-4.19 并没有提供 I3C 驱动,kernel-5.10 有提供 I3C 驱动(从 kernel-5.0开始提供的) 如下可以在线查看...Linux 源码,目录/drivers/i3c/... https://elixir.bootlin.com/linux/latest/source Bus configuration I3C 不仅支持多个从设备...Role of I3C Slave 在分配动态地址之前,I3C从设备应作为I2C设备运行 I3C START 和 STOP 在信号方面与 I2C START 和 STOP 相同,但在时序上可能不同。...SDR 很多 I3C 主控和设备支持,HDR 很多设备不支持,所以最常用的是 12.5MHz。...传统 i2c、spi、uart 设备接口中。 camera、touch panel。 i3c 向下兼容 i2c,可与传统 i2c 接口器件一起使用。
dev); error = handler->connect(handler, dev, id); 注册input_dev或input_handler时,会两两比较左边的input_dev和右边的...dev->h_list, d_node) if (handle->open) handle->handler->event(handle, type, code, value); 怎么写符合输入子系统框架的驱动程序.../module.h> #include #include #include #include #include #include #include #include #include #include #include #include <linux
所以需要使用输入子系统, 使应用程序无需打开多个不同的驱动设备便能实现 1.输入子系统简介 同样的输入子系统也需要输入驱动的框架,好来辨认应用程序要打开的是哪个输入驱动 比如: 鼠标、键盘、游戏手柄等等这些都属于输入设备...;这些输入设备的驱动都是通过输入子系统来实现的(当然,这些设备也依赖于usb子系统) 这些输入设备都各有不同,那么输入子系统也就只能实现他们的共性,差异性则由设备驱动来实现。...对于我们写驱动的人来说在设备驱动中就只要使用输入子系统提供的工具(也就是函数)来完成这些“差异”就行了,其他的则是输入子系统的工作。...这个思想不仅存在于输入子系统,其他子系统也是一样(比如:usb子系统、video子系统等) 所以我们先来分析下输入子系统input.c的代码,然后怎么来使用输入子系统(在内核中以input来形容输入子系统...只有一个.open函数,显然输入子系统就是通过这个函数来实现输入设备的驱动,接下来我们以按键驱动为例来分析这个函数。
因为没有统一的方法来连接物理传感器,设计师面临的数字接口碎片包括 I2C、SPI 和 UART 等。 除了主接口,还可能需要其他信号,例如专用中断、芯片选择信号(SPI),启用和睡眠信号。...翻译一下: 是否需要额外中断线(通知主控来读数据) I2C 和 I3C 主要区别如下: I2C 虽然也是两条线,但是很多时候传感器需要一条额外的中断线,来告诉主控数据已经准备好。...I2C 和 I3C 关于功耗和传输速率的对比: I3C 使用推挽功能的双线串行接口,速度可达 12.5 MHz I3C 同一总线上共存的传统 I2C 设备(有一些限制) I3C 动态寻址,同时支持传统...在程序和条件方面与 I2C 协议【NXP01】非常相似,因此 I3C 设备和许多传统 I2C 从设备(但不是 I2C 主设备)可以在同一 I3C 总线上共存。...对于 I3C 与 I2C 共享的程序和条件,SDR 模式严格遵循 I2C 规范中的定义。
/*输入子系统分析 input.c*/ /*1. 为什么需要输入子系统? 由于我们平时用的输入设备比较杂乱,比较多。 比如: 鼠标,键盘, 触摸屏等。...这样的好处是对所有的设备进行一个统一和抽象处理。形成一个统一的接口。方便驱动的编写等。 这种机制就是输入子系统。...*/ /*搜索工程,发现是各式各样的输入设备。 比如键盘, 鼠标, 游戏句柄等。...同理: 当注册input_handler时,会去input_dev的链表中, (省略, 和上面的操作几乎一样) */ /*那还有几个问题? 当应用程序read时, 我们的驱动程序应该干些什么?..., d_node) if (handle->open) handle->handler->event(handle, type, code, value); } /* 总结:如何写一个符合输入子系统的驱动程序
一文搞懂 | Linux 时钟子系统 Clock 时钟就是 SoC 中的脉搏,由它来控制各个部件按各自的节奏跳动。比如,CPU主频设置,串口的波特率设置,I2S的采样率设置,I2C的速率设置等等。...叶节点是使用 clock 做为输入的、有具体功能的 HW block。...dev_name(dev) : NULL; struct clk *clk; if (dev) { //通过扫描所有“clock-names”中的值,和传入的name比较,如果相同,获得它的index...inline int clk_enable(struct clk *clk) static inline void clk_disable(struct clk *clk) //clock频率的获取和设置...将clk_disable和clk_unprepare组合起来,一起调用 static inline int clk_prepare_enable(struct clk *clk) static inline
学习 I2C 和 SPI 驱动的时候,针对 I2C 和 SPI 设备寄存器的操作都是通过相关的 API 函数进行操作的。...这样 Linux 内核中就会充斥着大量的重复、冗余代码,但是这些本质上都是对寄存器的操作,所以为了方便内核开发人员统一访问 I2C/SPI 设备的时候,为此引入了 Regmap 子系统。...1、什么是 Regmap Linux 下大部分设备的驱动开发都是操作其内部寄存器,比如 I2C/SPI 设备的本质都是一样的,通过 I2C/SPI 接口读写芯片内部寄存器。...Linux 下使用 i2c_transfer 来读写 I2C 设备中的寄存器,SPI 接口的话使用 spi_write/spi_read等。...I2C/SPI 芯片又非常的多,因此 Linux 内核里面就会充斥了大量的 i2c_transfer 这类的冗余代码,再者,代码的复用性也会降低。
工业场合里面也有大量的模拟量和数字量之间的转换,也就是我们常说的 ADC 和 DAC。而且随着手机、物联网、工业物联网和可穿戴设备的爆发,传感器的需求只持续增强。...Linux 内核为了管理这些日益增多的 ADC 类传感器,特地推出了 IIO 子系统,我们学习如何使用 IIO 子系统来编写 ADC 类传感器驱动。...1、iio_dev 结构体 IIO 子系统使用结构体 iio_dev 来描述一个具体 IIO 设备,此设备结构体定义在include/linux/iio/iio.h 文件中 2、iio_dev 申请与释放...sizeof_priv:私有数据内存空间大小,一般我们会将自己定义的设备结构体变量作为 iio_dev 的私有数据,这样可以直接通过 iio_device_alloc 函数同时完成 iio_dev 和设备结构体变量的内存申请...Linux 内核使用 iio_chan_spec 结构体来描述通道,定义在 include/linux/iio/iio.h 文件中。
rtc 一般负责系统关机后计时、闹钟等,Linux 内核提供了一个 rtc 子系统,来支持所有的 rtc 设备。...rtc 设备本质上是一个字符设备,rtc 子系统在字符设备的基础上抽象与硬件无关的部分,并在这个基础上拓展 sysfs 和 proc 文件系统下的访问。...主要是设置时间、获取时间、设置闹钟、读闹钟,以及 rtc 中断处理函数和闹钟中断处理函数。...rx8010_set_alarm rx8010_set_time 软件逻辑就不在这里赘述了,大家可以参考下面链接 https://jasper1024.com/jasper/c089e4b/ 大家多看几个 Linux...子系统就会发现,基本上每个子系统都差不多,Linux 都会封装上中下 3 层,然后给你一些数据结构让你填充,就可以将这个子系统用起来了。
2、概述 led 子系统驱动框架: 所有 led 共性: 有和用户通信的设备节点 亮和灭 不同点: 有的 led 可能是接在 gpio 管脚上,不同的 led 有不同的 gpio 来控制 有的 led...可能由其他的芯片来控制(节约 cpu 的 pin,或者为了控制 led 的电流等) 可以设置亮度 可以闪烁 所以 Linux led 子系统把所有 led 的共性给实现了,把不同的地方留给驱动工程师去做...led 子系统核心文件: driver/leds/led-class.c driver/leds/led-core.c driver/leds/led-triggers.c include/linux/...led 子系统是一个简单的 Linux 子系统 ,在目录 /sys/class/leds 下展示该子系统设备,每个设备都有自己的属性: brightness:设置 LED 亮度,范围 0 ~ max_brightness...触发方式,如 heartbeat、mmc0、backlight、gpio delay_off、delay_on:trigger为timer时,LED亮灭的时间,单位ms kernel/include/linux
领取专属 10元无门槛券
手把手带您无忧上云