• linux内核中的I2C


    0、说明

            介绍I2C基本协议,以及在linux内核中I2C驱动程序框架。

            I2C驱动基于标准了总线设备驱动模型,因此本文仅示意分析I2C驱动框架,驱动实现细节按照总线设备驱动模型来实现,不做过多分析。

    1、I2C基础

            只有两脚

    • SCK
    • SDA

            根据引脚可以推断,一个数据脚为半双工,且数据脚方向为双向。没有片选信号,因此数据通信需要带有地址信息。

    开始和结束信号

            时钟为高电平期间,数据线从高变低是开始,从低变高是结束。

    数据信号

            时钟为高器件,数据线不允许变化,变化就是开始和结束。时钟为低电平器件,数据bit进行变化传输。

     ACK

            通信完成一个字节后,从设备或者主设备主动将SDA拉低从而产生一个ACK信号给对方,默认情况下被外部上拉置位高电平。

    读写时序

     2、内核中的I2C驱动

    架构

            遵循总线设备驱动模型。总线驱动在设置config支持i2c后在内核启动阶段被注册。与SPI总线类似,设备树中描述控制器及其下的设备,被转换为控制器及i2c_client设备。并注册不同类型的设备驱动,完成匹配。

            i2c_bus_type(总线)、i2c_adpater(控制器)、i2c_client(设备)、驱动(i2c_driver)

    设备树控制器描述

    1. i2c1: i2c@021a0000 {
    2. #address-cells = <1>;
    3. #size-cells = <0>;
    4. compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";
    5. reg = <0x021a0000 0x4000>;
    6. interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
    7. clocks = <&clks IMX6UL_CLK_I2C1>;
    8. status = "disabled";
    9. };
    10. &i2c1 {
    11. clock-frequency = <100000>;
    12. pinctrl-names = "default";
    13. pinctrl-0 = <&pinctrl_i2c1>;
    14. status = "okay";
    15. mag3110@0e {
    16. compatible = "fsl,mag3110";
    17. reg = <0x0e>;
    18. position = <2>;
    19. };
    20. fxls8471@1e {
    21. compatible = "fsl,fxls8471";
    22. reg = <0x1e>;
    23. position = <0>;
    24. interrupt-parent = <&gpio5>;
    25. interrupts = <0 8>;
    26. };
    27. };

    总线驱动

     

     控制器驱动

     

     设备驱动

    总结

            与SPI驱动类似,I2C完全符合总线设备驱动模型。I2C通信只有2根型号,可产生开始信号,停止信号,数据传输,ACK反馈等。

  • 相关阅读:
    【实战】Spring Cloud Stream 3.1+整合Kafka
    2023年上半年上午易错题(软件设计师考试)
    C++入门
    H12-821_146
    javaee thymeleaf简介
    全方位监控基础设施,坚实守护您的业务稳定!
    米尔MYD-JX8MPQ yocto
    力扣:1592. 重新排列单词间的空格
    李沐63_束搜索——自学笔记
    应急响应-Linux常用应急溯源命令
  • 原文地址:https://blog.csdn.net/fengyuwuzu0519/article/details/126677056