嵌入式Linux驱动开发(I2C专题)(七)

2023-09-18 16:16:10

使用GPIO操作I2C设备_IMX6ULL

参考资料:

  • Linux文档
    • Linux-5.4\Documentation\devicetree\bindings\i2c\i2c-gpio.yaml
    • Linux-4.9.88\Documentation\devicetree\bindings\i2c\i2c-gpio.txt
  • Linux驱动源码
    • Linux-5.4\drivers\i2c\busses\i2c-gpio.c
    • Linux-4.9.88\drivers\i2c\busses\i2c-gpio.c

1. 硬件连接

  • IMX6ULL:把I2C模块接到GPIO
    在这里插入图片描述

2. 根据原理图编写设备树

2.1 原理图

在这里插入图片描述

2.2 编写设备树
i2c_gpio_100ask {
	compatible = "i2c-gpio";
	gpios = <&gpio4 20 0 /* sda */
		     &gpio4 21 0 /* scl */
		    >;
	i2c-gpio,delay-us = <5>;	/* ~100 kHz */
	#address-cells = <1>;
	#size-cells = <0>;
};

把上述代码,放入arch/arm/boot/dts/100ask_imx6ull-14x14.dts的根节点下面。

3. 确认内核已经配置了I2C-GPIO

查看内核目录下的.config,如果未设置CONFIG_I2C_GPIO,上机实验时需要配置内核、编译I2C-GPIO驱动。

4. 上机实验

4.1 设置工具链
  • IMX6ULL

    export ARCH=arm
    export CROSS_COMPILE=arm-linux-gnueabihf-
    export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin
    
4.2 编译、替换设备树
  • 编译设备树:
    在Ubuntu的IMX6ULL内核目录下执行如下命令,
    得到设备树文件:arch/arm/boot/dts/100ask_imx6ull-14x14.dtb

    make dtbs
    
  • 复制到NFS目录:

    $ cp arch/arm/boot/dts/100ask_imx6ull-14x14.dtb ~/nfs_rootfs/
    
  • 开发板上挂载NFS文件系统

    • vmware使用NAT(假设windowsIP为192.168.1.100)

      [root@100ask:~]# mount -t nfs -o nolock,vers=3,port=2049,mountport=9999 
      192.168.1.100:/home/book/nfs_rootfs /mnt
      
    • vmware使用桥接,或者不使用vmware而是直接使用服务器:假设Ubuntu IP为192.168.1.137

      [root@100ask:~]#  mount -t nfs -o nolock,vers=3 192.168.1.137:/home/book/nfs_rootfs /mnt
      
  • 更新设备树

    [root@100ask:~]# cp /mnt/100ask_imx6ull-14x14.dtb /boot
    [root@100ask:~]# sync
    
  • 重启开发板

4.3 编译I2C-GPIO驱动
1. 配置内核

在IMX6ULL内核源码目录下执行make menuconfig命令,如下配置内核:

Device Drivers  --->
    I2C support  --->
        I2C Hardware Bus support  --->
            <M> GPIO-based bitbanging I2C      // 输入M,编译为模块        
2. 编译模块

设置工具链后,在内核目录下执行:

make modules   // 得到 drivers/i2c/busses/i2c-gpio.ko
5. 测试

在开发板上执行:

[root@100ask:~]# i2cdetect -l    // 加载i2c-gpio.ko前只看到2条I2C BUS
i2c-1   i2c             21a4000.i2c                             I2C adapter
i2c-0   i2c             21a0000.i2c                             I2C adapter
[root@100ask:~]#
[root@100ask:~]# insmod /mnt/i2c-gpio.ko   
[   45.067602] i2c-gpio i2c_gpio_100ask: using pins 116 (SDA) and 117 (SCL)
[root@100ask:~]# i2cdetect -l     // 加载i2c-gpio.ko后看到3条I2C BUS
i2c-1   i2c             21a4000.i2c                             I2C adapter
i2c-4   i2c             i2c_gpio_100ask                         I2C adapter
i2c-0   i2c             21a0000.i2c                             I2C adapter
[root@100ask:~]#
[root@100ask:~]# i2cdetect -y 4     // 检测到0x50的设备
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
[root@100ask:~]#
[root@100ask:~]# i2cset -f -y 4 0x50 0 0x55   // 往0地址写入0x55
[root@100ask:~]# i2cget -f -y 4 0x50 0        // 读0地址
0x55

具体芯片的I2C_Adapter驱动分析

参考资料:

  • Linux内核真正的I2C控制器驱动程序
    • IMX6ULL: Linux-4.9.88\drivers\i2c\busses\i2c-imx.c
    • STM32MP157: Linux-5.4\drivers\i2c\busses\i2c-stm32f7.c

1. I2C控制器内部结构

1.1 通用的简化结构

在这里插入图片描述

1.2 IMX6ULL的I2C控制器内部结构

在这里插入图片描述

1.3 STM32MP157的I2C控制器内部结构

在这里插入图片描述

2. I2C控制器操作方法

  • 使能时钟、设置时钟
  • 发送数据:
    • 把数据写入tx_register,等待中断发生
    • 中断发生后,判断状态:是否发生错误、是否得到回应信号(ACK)
    • 把下一个数据写入tx_register,等待中断:如此循环
  • 接收数据:
    • 设置controller_register,进入接收模式,启动接收,等待中断发生
    • 中断发生后,判断状态,读取rx_register得到数据
    • 如此循环

3. 分析代码

3.1 设备树
  • IMX6ULL: arch/arm/boot/dts/imx6ull.dtsi

    i2c1: i2c@021a0000 {
    		#address-cells = <1>;
    		#size-cells = <0>;
    		compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";
    		reg = <0x021a0000 0x4000>;
    		interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
    		clocks = <&clks IMX6UL_CLK_I2C1>;
    		status = "disabled";   // 在100ask_imx6ull-14x14.dts把它改为了"okay"
    };
    
  • STM32MP157: arch/arm/boot/dts/stm32mp151.dtsi

    i2c1: i2c@40012000 {
    		compatible = "st,stm32mp15-i2c";
    		reg = <0x40012000 0x400>;
    		interrupt-names = "event", "error";
    		interrupts-extended = <&exti 21 IRQ_TYPE_LEVEL_HIGH>,
    							  <&intc GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
    		clocks = <&rcc I2C1_K>;
    		resets = <&rcc I2C1_R>;
    		#address-cells = <1>;
    		#size-cells = <0>;
    		dmas = <&dmamux1 33 0x400 0x80000001>,
    			   <&dmamux1 34 0x400 0x80000001>;
    		dma-names = "rx", "tx";
    		power-domains = <&pd_core>;
    		st,syscfg-fmp = <&syscfg 0x4 0x1>;
    		wakeup-source;
    		status = "disabled";   // 在stm32mp15xx-100ask.dtsi把它改为了"okay"
    };
    
3.2 驱动程序分析

读I2C数据时,要先发出设备地址,这是写操作,然后再发起读操作,涉及写、读操作。所以以读I2C数据为例讲解核心代码。

  • IMX6ULL:函数i2c_imx_xfer分析:
    在这里插入图片描述

  • STM32MP157:函数stm32f7_i2c_xfer分析
    这函数完全有驱动程序来驱动:启动传输后,就等待;在中断服务程序里传输下一个数据,知道传输完毕。

    • 启动传输
      在这里插入图片描述
    • 通过中断进行后续传输
      在这里插入图片描述
更多推荐

Appium混合页面点击方法tap的使用

原生应用开发,是在Android、IOS等移动平台上利用官方提供的开发语言、开发类库、开发工具进行App开发;HTML5(h5)应用开发,是利用Web技术进行的App开发。目前,市面上很多app都是原生和h5混合开发,这样做的好处在于:1)开发效率高,节约时间同一套代码Android和IOS基本都可用。2)更新和部署比

北大王选实验室 | 摘要已死?

深度学习自然语言处理原创作者:Winnie最新一篇研究里探索了大型语言模型(LLMs)在文本摘要这一领域的表现。他们设计了新的数据集,通过一系列人类评估实验评估LLMs在不同摘要任务中的表现。惊人的是,大多数人类评估者实际更倾向于选择LLM生成的摘要,甚至超过了参考摘要(人工编写)的标准。这个结果意味着,LLMs的介入

《红警3》因计算机中丢失d3dx9_35.dll无法打开游戏怎么办?最新解决方法推荐

d3dx9_35.dll是DirectX9.0c的一部分,它是一个动态链接库(DLL),包含了许多用于支持DirectX9.0c功能的函数和类。DirectX是一种由微软开发的游戏和多媒体应用程序编程接口,它提供了许多功能,如3D图形、音频、输入等,以便开发人员能够更轻松地创建高质量的游戏和多媒体应用程序。1、d3dx

lambda

一个lambda表达式表示一个可调用的代码单元。可以将其理解为一个未命名的内联函数。与普通函数类似,一个lambda具有一个返回类型、一个参数列表和一个函数体。与普通函数不同的是,lambda可以定义在其他函数内部。一个lambda表达式具有如下形式:[capturelist](parameterlist)->retu

骨髓小游戏

欢迎来到程序小院骨髓玩法:骨髓推塔小游戏,敌方士兵进入到我方高塔会毁坏建筑,我方可派兵前去迎战,我方:骑兵、长枪兵、弓兵、敌法:骷髅骑兵、骷髅长枪兵、骷髅弓兵,快去消灭敌人吧^^。开始游戏https://www.ormcc.com/play/gameStart/184html<divid="game"></div>cs

【EI会议】第三届大数据、人工智能与风险管理国际学术会议 (ICBAR 2023)

第三届大数据、人工智能与风险管理国际学术会议(ICBAR2023)20233rdInternationalConferenceonBigData,ArtificialIntelligenceandRiskManagement第三届大数据、人工智能与风险管理国际学术会议(ICBAR2023)将于2023年11月24-26

华为云云服务器评测 [Vue3 博物馆管理系统] 使用Vue3、Element-plus菜单组件构建轮播图

系列文章目录华为云云服务器评测第一章[linux实战]华为云耀云服务器L实例Java、node环境配置华为云云服务器评测第二章[linux实战]Unbutnu添加SSHKey、启动Springboot项目华为云云服务器评测第三章[linux实战]使用Vue3、Element-plus菜单组件构建轮播图华为云云服务器评测

Windows10怎么清除运行框中历史记录?电脑中怎么清除活动历史记录?

Windows10怎么清除运行框中历史记录?电脑中怎么清除活动历史记录?Win10怎么清除运行框中历史记录?那小编就来给大家解答一下吧,希望可以帮助到大家吧。清除运行框中历史记录1、在Win10系统下,按住键盘的“Win+R”快捷组合键,打开“运行”对话狂。2、在打开的“运行”对话框中,输入“regedit”命令,然后

计算机IO原理

一、中断机制在IO处理中有2种思路,一种就是轮训(polling)机制,一种是中断(interrupt)机制,前置是一种同步的通信机制,不是计算机中IO采用的机制,我们重点来说明中断机制。CPU停下当前的工作任务,去处理其他事情,处理完后回来继续执行刚才的任务,这一过程便是中断。中断分为外部中断和内部中断。外部中断可屏

移动 Web 第一天

目标:使用位移、缩放、旋转、渐变效果丰富网页元素的呈现方式。文章目录01-平面转换简介平移定位居中案例-双开门旋转转换原点案例-时钟多重转换缩放案例-播放特效倾斜02-渐变线性渐变案例-产品展示径向渐变03-综合案例导航-频道箭头旋转频道列表渐变按钮搜索按钮登录按钮客户端按钮轮播图猜你喜欢01-平面转换简介作用:为元素

精益求精:Android应用体积优化的终极指南

精益求精:Android应用体积优化的终极指南1.介绍在当今移动应用生态系统中,Android应用的体积优化是开发者需要高度重视的关键方面之一。一个庞大的应用体积不仅会对用户体验造成负面影响,还会导致以下问题:下载速度延迟:用户需要等待更长时间来下载和安装应用程序,这可能导致用户流失。占用存储空间:较大的应用占用用户设

热文推荐