当前位置: 首页 > news >正文

I2c、SPI、USB驱动架构类比

一、        概述

特性I2C驱动架构SPI驱动架构USB驱动架构
总线类型同步半双工,两线制(SCL+SDA)同步全双工,四线制(SCLK+MOSI+MISO+CS)异步全双工,差分信号(D+/D-)
热插拔支持不支持,需静态绑定设备(设备树或板级描述)不支持,需静态绑定设备支持,动态枚举设备
驱动分层1. 控制器驱动(platform_driver)
2. 设备驱动(i2c_driver)
1. 控制器驱动(spi_master)
2. 设备驱动(spi_driver)
1. 主机控制器驱动(HCD)
2. 设备驱动(usb_driver)
设备枚举方式通过设备树或i2c_board_info静态注册通过设备树或spi_board_info静态注册动态探测(通过USB协议栈自动识别)
总线控制器注册由platform总线枚举(如SoC内部的I2C控制器)由platform总线枚举(如SoC内部的SPI控制器)由PCI/PCIe或platform总线枚举(如xHCI控制器)
数据传输模式主从模式,基于地址寻址(7/10位)主从模式,基于硬件片选(CS)主机-设备模式,基于端点(Endpoint)和管道(Pipe)
典型应用场景低速传感器、EEPROM(100kbps~3.4Mbps)高速外设(Flash、ADC,可达数十Mbps)通用外设(键盘、存储设备,480Mbps~20Gbps)
Linux内核实现drivers/i2c/(核心层)
drivers/i2c/busses/(控制器驱动)
drivers/spi/(核心层)
drivers/spi/spi-xxx.c(控制器驱动)
drivers/usb/(核心层)
drivers/usb/host/(主机驱动)

关键差异说明‌:

  1. 静态vs动态配置‌:I2C/SPI需预先定义设备连接(设备树或板级代码),而USB通过协议栈动态识别设备。

  2. 拓扑结构‌:I2C支持多主多从(需仲裁),SPI为单主多从(硬件片选),USB为主从星型拓扑。

  3. 协议复杂度‌:USB协议栈最复杂(包含设备描述符、配置描述符等),I2C/SPI协议更轻量

二、        I2C、SPI、USB驱动架构

        根据下图linux 设备驱动都主机、外设驱动分离,Linux倾向于将主机端都驱动与外设端都驱动分离,而通过一个核心层将某种总线的协议进行抽象,外设端的驱动调用核心API间接过渡对主机驱动传输函数的调用。对于I2c、SPI这类这类具体热插拔能力的总线而言,一般在arch/arm/mach-xxx或者arch/arm/boot/dts中会有相应的板级描述信息,描述外设与主机的连接情况。

         

        Linux的各个子系统都呈现为相同都特点,下图类比了I2C、SPI、USB驱动架构都类比    

        对于USB、PCI等总线而言,由于它们具有热插拔能力,所以实际不存在类似I2c、SPI这样都板级描述信息。换句话,即便是有这类信息,其实也没有什么用,因为通过写了板子上有个U盘,但实际上没有,其实反而是制造了麻烦;相反,如果没有写,U盘一旦插入,Linux USB系统自动探测到一个U盘。

        同时我注意到,I2C、SPI、USB控制器虽然给别人提供了总线,但是其实自己也是由它自身依附都总线枚举出来都。比如,对于Soc而言,这些控制器一般是直接集成在芯片内部,通过内存指令来访问,因此它们自身通过platform_driver、platform_device这种模型枚举出来都。

三、        I2C主机和外设眼里的Linux世界

        I2c控制器所在驱动的platform_driver与arch/arm/match-xxx中的platform_driver(设备树中的节点)通过platform总线的match()函数匹配导致platform_driver.probe()执行,从而完成I2C控制器的注册;而I2C上面的触摸屏依附I2C_driver与arch/arm/match-xxx中的i2C_board_info指向的设备(或者设备树的节点)通过I2C总线的match函数匹配导致i2c_driver.probe()执行,从而使触摸屏展开。

        下图虚线上方部分是i2c_adapater眼里的linux 世界;下方部分是i2c_clinet眼里的linux世界。其实,Linux中每一个设备通过它依附的总线被枚举出来,尽管它自身可能给别人提供总线。

         

http://www.lryc.cn/news/619417.html

相关文章:

  • 2025年,Javascript后端应该用 Bun、Node.js 还是 Deno?
  • 欧姆龙E6B2-CWZ6C旋转编码器参数说明+示例代码
  • SQL详细语法教程(二)--DML(数据操作语言)和DQL(数据查询语言)
  • PostgreSQL——索引
  • 【Unity3D】Spine黑线(预乘问题)、贴图边缘裁剪问题
  • django request.data.get 的值修改
  • 基于Tensorflow2.15的图像分类系统
  • C++中的`auto`与`std::any`:功能、区别与选择建议
  • Android 在 2020-2025 都做哪些更新?
  • 从0开始跟小甲鱼C语言视频使用linux一步步学习C语言(持续更新)8.13
  • 数据治理之元数据管理
  • TensorFlow实现回归分析详解
  • PyTorch基础(使用TensorFlow架构)
  • CSS counter-reset 与 counter-increment:用 CSS 实现自动编号的黑科技
  • 【贪心算法】加油站
  • TensorFlow深度学习实战(31)——强化学习仿真库Gymnasium
  • 【IntelliJ IDEA】如何在pom.xml中去除maven中未使用的依赖
  • 七大排序算法全解析:从入门到精通
  • 各种排序算法(一)
  • Java开发环境搭建(WIN+IDEA+Maven)
  • STM32的UART奇偶校验注意
  • C# xml UI格式化字符串
  • IDEA创建一个VUE项目
  • 基于人工智能和物联网融合跌倒监控系统(LW+源码+讲解+部署)
  • CW32L011电机开发板控制教程
  • 分布式与微服务宝典
  • js:13KB或者xxxkb、xxxMB\xxxtb\xxb等多种情况怎么获取后面的单位
  • FluxSelectMultiple 技术设计文档
  • 飞算JavaAI的中间件风暴:Redis + Kafka 全链路实战
  • docker network 与host的区别