I2C设备驱动挂载

news2024/9/25 7:19:16

image2021-9-18_10-56-22.png

一、 概述:

image2021-9-18_10-56-22.png

I2C工作原理:

        I2C总线标准的两根传输线,SDA是数据线,Scl是时钟线,当SCL为高,SDA由高到低时,发送启动信息,发送9个脉冲,1-7是地址,8是读写控制位,9是ACK应答位,所以挂在I2C上的被控设备都接受所发送的信息,并把接收到的7位地址与自己的地址进行比较,如果相同ACK就会反馈应答。当SCL为低,SDA由低-à高,则发送停止信号。

Linux的I2C构架分为三个部分:

1)I2C core框架

        提供了核心数据结构的定义和相关接口函数,用来实现I2C适配器

        驱动和设备驱动的注册、注销管理,以及I2C通信方法上层的、与具体适配器无关的代码,为系统中每个I2C总线增加相应的读写方法。

2) I2C总线驱动

        定义描述具体I2C总线适配器的i2c_adapter数据结构、实现在具体I2C适配器上的I2C总线通信方法,并由i2c_algorithm数据结构进行描述。 经过I2C总线驱动的的代码,可以为我们控制I2C产生开始位、停止位、读写周期以及从设备的读写、产生ACK等。

3) I2C 设备驱动

        是对具体I2C硬件驱动的实现。I2C 设备驱动通过I2C适配器与CPU通信。其中主要包含i2c_driver和i2c_client数据结构,i2c_driver结构对应一套具体的驱动方法,例如:probe、remove、suspend等,需要自己申明。i2c_client数据结构由内核根据具体的设备注册信息自动生成,设备驱动根据硬件具体情况填充。

编写具体的I2C驱动时,工程师需要处理的主要工作如下:
 
  1).提供I2C适配器的硬件驱动,探测,初始化I2C适配器(如申请I2C的I/O地址和中断号),驱动CPU控制的I2C适配器从硬件上产生。
  2).提供I2C控制的algorithm, 用具体适配器的xxx_xfer()函数填充i2c_algorithm的master_xfer指针,并把i2c_algorithm指针赋给i2c_adapter的algo指针。
  3).实现I2C设备驱动中的i2c_driver接口,用具体yyy的yyy_probe(),yyy_remove(),yyy_suspend(),yyy_resume()函数指针和i2c_device_id设备ID表赋给i2c_driver的probe,remove,suspend,resume和id_table指针。
  4).实现I2C设备所对应类型的具体 ,i2c_driver只是实现设备与总线的挂接。
  

二、下面详细描述I2C设备驱动如何挂载到总线。

  下面以GPIO模拟i2c总线的驱动为例,来介绍实现I2C设备驱动如何挂载到总线上

1)  i2c-gpio总线和i2c设备驱动设备树

首先要添加 i2c-gpio总线和i2c设备驱动设备树节点,总线设备树节点无需添加,只需在添加设备驱动时,将对应的的I2C总线打开,添加节点内容在不同平台所相对应的设备树dts文件里,做法如下:

&i2c4 {

    status = "okay";

    <name>[@<unit_address>]@{    //其中name就是设备名,最长可以是31个字符长度。unit_address一般是设备地址,用来唯一标识一个节点

        compatible = "name2";    //需要与name_ids的 .compatible一致,不然注册不成功

        reg = <unit_address>;

        irq_gpio = <&gpio7 GPIO_B2 IRQ_TYPE_LEVEL_LOW>;//中断脚GPIO

        reset_gpio = <&gpio7 GPIO_B1 GPIO_ACTIVE_HIGH>;  //复位脚GPIO



    };

}

2)  i2c-gpio总线和i2c设备驱动注册

i2c总线注册无需自己注册,把i2c设备驱动注册到i2c-gpio总线。做法如下,

I2C设备树
做法如下。首先定义设备ID:
 
static const struct i2c_device_id name_id[] = {
 
                     { "name1", 0 },//设备名和设备是有数据长度
 
                     { }
 
};
设备树名称:
static struct of_device_id name_ids[] = {
    { .compatible = "name2" },//需要与设备树compatible一致,不然注册不成功
    { }
};
 
然后声明i2c_driver结构:
 
static struct i2c_driver name_driver = {
 
               .probe     = name_probe, 
 
               .remove        = name_remove,
 
               .suspend   = name_suspend,
 
               .resume        = name_resume,//上面4个函数根据具体情况取舍
 
               .id_table = name_id,
 
               .driver        = {
 
                     .name    = "name1",  //需要与name_id里的设备名一致
               .of_match_table = of_match_ptr(name_ids),
                },
 
};
最后调用static inline int i2c_add_driver(struct i2c_driver *driver)注册name驱动到I2C总线,如下:
 
static int __init name_init(void)
 
{
 
         return i2c_add_driver(&name_driver);//注册name_driver
 
};
 
module_init(name_init);

3) 实现设备与总线的挂接

i2c_driver实现设备与总线的挂接。用具体yyy的yyy_probe(),yyy_remove(),yyy_suspend(),yyy_resume()函数指针和i2c_device_id设备ID表赋给i2c_driver的probe,remove,suspend,resume和id_table指针。其中.probe指针所对应的yyy_probe()函数指针则判断上电时序、I2C是否读取正确,返回值正确才能够实现I2C驱动设备的使用。

yyy_probe()函数指针判断大致流程如下,以上面缩写的设备树为例:

第一步;从设备数获取指定GPIO属性信息
    irq_gpio = of_get_named_gpio(np, "irq_gpio",0);
    reset_gpio = of_get_named_gpio(np, "irq_gpio", 0);
第二步:申请GPIO管脚
    ret = gpio_request(reset_gpio, "touch_gpio_reset");
    ret += gpio_request(irq_gpio, "touch_gpio_irq");
第三步:判断上电时序
不同设备有不同的上电时序,根绝供应商所提供的资料编写
第四步:读取I2C
s32 name_i2c_read(struct i2c_client *client, u8 *buf, s32 len)
{
    struct i2c_msg msgs[2];
    s32 ret=-1;
    s32 retries = 0;
 
    GTP_DEBUG_FUNC();
 
    msgs[0].flags = !I2C_M_RD;
    msgs[0].addr  = client->addr;
    msgs[0].len   = GTP_ADDR_LENGTH;
    msgs[0].buf   = &buf[0];
#ifdef CONFIG_I2C_ROCKCHIP_COMPAT
    msgs[0].scl_rate=200 * 1000;
    //msgs[0].scl_rate = 300 * 1000;    // for Rockchip, etc.
#endif
    msgs[1].flags = I2C_M_RD;
    msgs[1].addr  = client->addr;
    msgs[1].len   = len - GTP_ADDR_LENGTH;
    msgs[1].buf   = &buf[GTP_ADDR_LENGTH];
#ifdef CONFIG_I2C_ROCKCHIP_COMPAT
    msgs[1].scl_rate=200 * 1000;
    //msgs[1].scl_rate = 300 * 1000;    // for Rockchip, etc.
#endif
 
 
    while(retries < 5)
    {
        ret = i2c_transfer(client->adapter, msgs, 2);
        if(ret == 2)break;
        retries++;
    }
    if((retries >= 5))
    {
     
        printk("I2C Read: 0x%04X, %d bytes failed, errcode: %d! Process reset.", (((u16)(buf[0] << 8)) | buf[1]), len-2, ret);
    }
    return ret;
}
第五步:读取到正确的I2C,将GPIO管脚释放
        gpio_free(reset_gpio);
        gpio_free(irq_gpio);

4) 实现I2C设备所对应类型的具体

        实现 I2C 设备驱动的文件操作接口,即实现具体设备 yyy 的 yyy_read() 、 yyy_write() 和 yyy_ioctl() 函数等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/921995.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GEE/PIE 遥感大数据处理与典型案例

查看原文>>>【399三天】GEE/PIE遥感大数据处理与典型案例实践 随着航空、航天、近地空间等多个遥感平台的不断发展&#xff0c;近年来遥感技术突飞猛进。由此&#xff0c;遥感数据的空间、时间、光谱分辨率不断提高&#xff0c;数据量也大幅增长&#xff0c;使其越来…

FPGA GTX全网最细讲解,aurora 8b/10b协议,OV5640摄像头视频传输,提供2套工程源码和技术支持

目录 1、前言免责声明 2、我这里已有的 GT 高速接口解决方案3、GTX 全网最细解读GTX 基本结构GTX 发送和接收处理流程GTX 的参考时钟GTX 发送接口GTX 接收接口GTX IP核调用和使用 4、设计思路框架视频源选择OV5640摄像头配置及采集动态彩条视频数据组包GTX aurora 8b/10b数据对…

深入Java中的观察者模式

观察者模式是软件开发中常用的一种设计模式&#xff0c;它通过定义一对多的依赖关系&#xff0c;使得一个对象&#xff08;主题&#xff09;的状态变化可以通知多个其他对象&#xff08;观察者&#xff09;。 这种模式的优点是解耦和增加扩展性&#xff0c;用于实现对象之间的…

iptables的使用规则

环境中为了安全要限制swagger的访问&#xff0c;最简单的方式是通过iptables防火墙设置规则限制。 在测试服务器中设置访问swagger-ui.html显示如下&#xff0c;区分大小写&#xff1a; iptables设置限制访问9783端口的swagger字段的请求&#xff1a; iptables -A INPUT -p t…

Spring 容器启动耗时统计

为了了解 Spring 为什么会启动那么久&#xff0c;于是看了看怎么统计一下加载 Bean 的耗时。 极简版 几行代码搞定。 import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor;import java.util.HashMap; imp…

【科研】-- 如何将Endnote中参考文献格式插入到Word?

文章目录 如何将Endnote中参考文献格式插入到Word&#xff1f; 如何将Endnote中参考文献格式插入到Word&#xff1f; 1、首先确保Endnote和Word安装正确&#xff0c;正常可以从学校官网中下载到正版软件&#xff0c;下载后在word栏目中会出现EndNote的标签&#xff1b; 2、可…

[CVPR 2023]PyramidFlow-训练并推理-附bug调试

CVPR2023-PyramidFlow-zero shot异常检测网络 代码调试记录 一.论文以及开源代码二.前期代码准备三.环境配置四.bug调试num_samples should be a positive integer value, but got num_samples0AttributeError: Cant pickle local object fix_randseed.<locals>.seed_wor…

C++信息学奥赛1136:密码翻译

#include <iostream> #include <string> using namespace std;int main() {string arr;getline(cin, arr); // 输入字符串&#xff0c;包括空格for (int i 0; i < arr.length(); i) {char a arr[i] 1; // 字符加1if (arr[i] z) {a a; // 如果当前字符是…

springboot 基于JAVA的动漫周边商城的设计与实现64n21

动漫周边商城分为二个模块&#xff0c;分别是管理员功能模块和用户功能模块。管理员功能模块包括&#xff1a;文章资讯、文章类型、动漫活动、动漫商品功能&#xff0c;用户功能模块包括&#xff1a;文章资讯、动漫活动、动漫商品、购物车&#xff0c;传统的管理方式对时间、地…

PyTorch深度学习实战(13)——可视化神经网络中间层输出

PyTorch深度学习实战&#xff08;13&#xff09;——可视化神经网络中间层输出 0. 前言1. 可视化特征学习的结果2. 可视化第一个卷积层的输出3. 可视化不同网络层的特征图小结系列链接 0. 前言 随着深度学习的快速发展&#xff0c;神经网络已成为解决各种复杂任务的重要工具。…

day 38 | ● 518. 零钱兑换 II ● 377. 组合总和 Ⅳ

518. 零钱兑换 II 这道题就是完全背包问题&#xff0c;因为可以选择的数量是无限的。所以第二层的遍历顺序就是从前往后。 因为是次数问题&#xff0c;递推公式是 的&#xff0c;初值应该设定为dp【0】 1&#xff0c;否则无法进行累加。 func change(amount int, coins []i…

Python编程基础-基本语法II

循环语句 for()语句 可以遍历任何序列的项目&#xff0c;如一个列表、元组或者一个字符串 格式&#xff1a; for 循环索引值 in 序列 循环体 #for循环把字符串中字符遍历出来 for letter in Python:print ( 当前字母 :, letter )#通过索引循环 fruits [banana, apple, m…

百度地图:设置复杂的自定义覆盖物,添加自定义覆盖物ComplexCustomOverlay

// 设置复杂的自定义覆盖物 setComplexCustomOverlay({coordinate,icon 1,label,contentHTML, }) {var mp this.map;let _BMAP this.data.type 3 ? BMapGL : BMap;// 自定义覆盖物----------------------------------------function ComplexCustomOverlay({point,icon,lab…

【全站最全】被苹果、谷歌和Microsoft停产的产品(一)

目录 ​编辑 2025 Skype for Business 2023 Cortana Google Domains Google Optimize Google Universal Analytics YouTube Stories Grasshopper Google Currents (2019) Google Stadia 2022 YouTube Originals Google OnHub Atom Google Surveys Apple Watc…

【3dsmax】练习——制作碗椅

目录 目标 步骤 一、制作主体部分 二、制作靠垫部分 三、制作支架部分 目标 制作如下图所示的碗椅 步骤 一、制作主体部分 1. 首先创建一个球体 2. 转换为可编辑多边形&#xff0c;然后切换到边层级&#xff0c;选中球体上部的所有边&#xff0c;然后删除 3. 通过“壳…

Linux下的系统编程——gdb调试工具

前言&#xff1a; 程序中除了一目了然的Bug之外都需要一定的调试手段来分析到底错在哪。到目前为止我们的调试手段只有一种∶根据程序执行时的出错现象假设错误原因﹐然后在代码中适当的位置插入printf﹐执行程序并分析打印结果﹐如果结果和预期的一样﹐就基本上证明了自己假设…

东风纳米首款车型纳米 01 亮相:纯电小车,固态电池 + 超级快充

根据近期发布的消息&#xff0c;东风纳米品牌推出的首款车型纳米 01 在全新发布会上正式亮相。这款车型采用东风量子架构 3 号平台&#xff0c;被寄予厚望将在国内市场迎来广泛的认可度。 作为一款小型纯电动车&#xff0c;纳米 01注重家庭出游、市区代步、个人通勤、接送孩子、…

“好声音”塌房、星空华文市值暴跌,两个交易日蒸发234亿港元

8月17日&#xff0c;因李玟生前录音事件&#xff0c;再次将《中国好声音》被舆论推至风口浪尖&#xff0c;引发社会对后者的质疑。 次日(8月18日)&#xff0c;《中国好声音》的IP运营商星空华文(06698.HK)股价大跌&#xff0c;其港股收盘股价跌幅达到23.4%&#xff0c;一天内市…

基于逻辑斯蒂回归的肿瘤预测案例

导入包 import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report,roc_a…

uniapp - 全平台兼容实现上传图片带进度条功能,用户上传图像到服务器时显示上传进度条效果功能(一键复制源码,开箱即用)

效果图 uniapp小程序/h5网页/app实现上传图片并监听上传进度,显示进度条完整功能示例代码 一键复制,改下样式即可。 全部代码 记得改下样式,或直接