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

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.xdnf.cn/news/17669.html

相关文章:

  • 管理变量和事实
  • 【Unity3D】Spine黑线(预乘问题)、贴图边缘裁剪问题
  • @系统管理 - Ansible 补丁管理方案(Windows Linux)
  • 飞算JavaAI的“盾牌”计划:手撕Spring Security + JWT认证链
  • CNN卷积神经网络预测手写数字的Pytorch实现
  • C++ 优选算法 力扣 209.长度最小的子数组 滑动窗口 (同向双指针)优化 每日一题 详细题解
  • [系统架构设计师]架构设计专业知识(二)
  • python与JavaScript的区别
  • 三方相机问题分析六:【没用相机,诡异的手电筒不可使用】下拉状态栏,手电筒置灰,无法打开,提提示相机正在使用
  • 模型驱动的自动驾驶AI系统全生命周期安全保障
  • 论文Review 激光SLAM VoxelMap | RAL 2022 港大MARS出品!| 经典平面特征体素激光SLAM
  • .NET 应用程序 Linux下守护进程脚本编写
  • 基于.Net Framework4.5 Web API 引用Swagger
  • JavaWeb核心:HttpServletRequest与HttpServletResponse详解
  • mac环境下安装git并配置密钥等
  • 从行业场景到视觉呈现:3ds Max 与 C4D 效果图的本质分野
  • Pycharm现有conda环境有对应env,但是添加后没反应
  • 学习嵌入式的第十九天——Linux——文件编程
  • Spring Boot 使用 @NotBlank + @Validated 优雅校验参数
  • 疯狂星期四文案网第38天运营日记
  • TorchDynamo - API
  • 互联网大厂Java求职面试实录:Spring Boot到微服务与AI的技术问答
  • 【Unity开发】Unity核心学习(一)
  • 如何在 Ubuntu 24.04 LTS Noble Linux 上安装 FileZilla Server
  • MyBatis 中 XML 与 DAO 接口的位置关系及扫描机制详解
  • react与vue的对比,来实现标签内部类似v-for循环,v-if等功能
  • 万字详解C++11列表初始化与移动语义
  • 如何把ubuntu 22.04下安装的mysql 8 的 数据目录迁移到另一个磁盘目录
  • 基于深度学习的苹果品质智能检测算法研究
  • Kubernetes(K8S)中,kubectl describe node与kubectl top pod命令显示POD资源的核心区别