linux驱动之i2c学习

  最近在研究linux的i2c驱动,从最底层i2c控制器初始化到应用层与i2c设备交互基本打通了。

  一、linux的i2c架构可以用下图表示:

  IIC适配器对应一条i2c总线,linux里面用i2c_adapter结构表示。总线下的i2c设备用i2c_client结构表示。algorithm是i2c的通信协议,IIC核心层负责注册/注销i2c_adapter、注册/注销i2c_client、注册i2c总线等操作。i2c-dev对应的是i2c-dev.c,它负责将总线实例化为一个i2c_client,应用层可以通过操作对应设备节点来与总线下的任意设备进行通信。IIC设备驱动是i2c总线下的具体设备的驱动方法。

  其中具体的IIC控制器操作与algorithm由IIC控制器驱动实现,常见的不同处理器的i2c总线驱动在内核源码/driver/i2c/buses/目录下。具体的i2c设备驱动内核源码并没有实现,需要自己提供。

  以下摘抄宋宝华老师写的书《linux设备驱动开发详解》中说作为一个工程师要实现的主要工作:

    I2C总线驱动:

    (1)提供I2C适配器的硬件驱动,探测、初始化I2C适配器(如申请I2C的I/O地址和中断号)、驱动CPU控制的I2C适配器从硬件上产生各种信号以及处理I2C中断等。

    (2)提供I2C适配器的Algorithm,用具体适配器的xxx_xfer()函数填充i2c_algorithm的master_xfer指针,并把i2c_algorithm指针赋值给i2c_adapter的algo指针。

    I2C设备驱动:

    (1):实现I2C设备驱动中的i2c_driver接口,用具体设备yyy的yyy_probe()、yyy_remove()、yyy_suspend()、yyy_resume()函数指针和i2c_device_id设备ID表赋值给i2c_driver的probe、remove、suspend、和id_table指针。

    (2):实现I2C设备所对应类型的具体驱动,i2c_driver只是实现设备与总线的挂接,而挂接在总线上的设备千差万别。例如,如果是字符设备,就实现文件操作接口,即实现设备yyy的yyy_read()、yyy_write()和yyy_ioctl()函数等;如果是声卡,就实现ALSA驱动。

  二、I2C核心

  (1)增加/删除i2c_adapter

    int i2c_add_adapter(struct i2c_adapter *adapter);

    int i2c_del_adapter(struct i2c_adapter *adap);

  (2)增加/删除i2c_driver

    int i2c_register_driver(struct module *owner, struct i2c_driver *driver);

    void i2c_del_driver(struct i2c_driver *driver);

    static inline int i2c_add_driver(struct i2c_driver *driver)
    {
      return i2c_register_driver(THIS_MODULE, driver);
    }

  (3)I2C传输、发送和接收

    int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);

    int i2c_master_send(const struct i2c_client *client, const char *buf, int count);

    int i2c_master_recv(const struct i2c_client *client, char *buf, int count);

时间: 2024-10-12 04:29:24

linux驱动之i2c学习的相关文章

linux驱动之I2C

include/linux/i2c.h struct i2c_msg;struct i2c_algorithm;struct i2c_adapter;struct i2c_client;struct i2c_driver;union i2c_smbus_data; I2C驱动主要包含三部分:I2C核心.I2C总线驱动.I2C设备驱动,它们主要的数据结构在目录:/include/linux/i2c.h struct i2c_driver 1 /* 2 * A driver is capable o

linux驱动之i2c子系统device注册driver注册简单分析

Linux 驱动设计主要是根据分层分离思想,i2c子系统分为i2cocre.adapter.及device_driver层,其实adapter也是个device,只不过是我们主控芯片的I2C控制接口而已,我们的主控芯片有几个I2C接口就有几个adapter; i2ccore这一层linux已经帮我们实现,主要的工做是类似platform总线的作用,负责drvier及设备的注册,相比platform多了个adapter的注册管理工作,以及i2c的数据发送接收等等算法,说算法有点夸大,其实就是按照i

Linux驱动LCD driver学习总结

这篇文章写于13年11月,这里仅记录一下曾经涉猎了这方面的知识,可能对以后的一些知识了解有所帮助 关于platform总线模型,可以参考之前的一篇文章Linux驱动Platform总线模型,这对frameBuffer的驱动注册可能有所帮助 一.LCD硬件框架 二.LCD软件框架 三.LCD初始化流程 四.LCD on与off的流程 五.LCD数据流 六.驱动程序framebuffer 所在文件 /android/kernel/drivers/video/fbmem.c /android/kern

linux驱动之i2c子系统mpu6050设备驱动

以下是mpu6050简单的驱动实现,mpu6050是I2C接口的6轴传感器,可以作为字符设备注册到内核,本代码运行环境是3.4.2内核,4.3.2版本的编译链,12.04版本的Ubuntu,硬件环境是jz2440开发板: 按照之前分析的I2C驱动框架,mpu6050驱动主要是实现外设端的驱动,主要是注册外设到I2C总线,而外设端注册到I2C总线包括device及driver两个部分注册到I2C总线,采用分离的设计思想,详情见代码: device注册到I2C总线: #include <linux/

linux驱动之i2c总线驱动调用分析【基于linux4.4】

平台:RK3399 使用设备树描述板级资源: 框架: linux i2c框架同样采用分层.分离的模式设计:从上到下分为  app调用层.i2c core层.驱动层:驱动层又分为 cpu平台 i2c控制器相关的驱动层以及 i2c总线上挂接的设备驱动程序:而分离的思想则体现在板级相关的信息放在设备树上实现,而通用的读写.初始化流程.操作流程等则放到驱动里面实现(类似platform总线驱动): 具体分析: 1. cpu i2c控制器驱动(adpter) static struct platform_

linux驱动开发学习路线

这篇文章是和大四学弟交流的文章,贴出来,和大家学习讨论 需要掌握的基本技能: C/C++/ python shell makefile linux基本操作 以android手机为例,我通俗的介绍下市场上产品的软件结构. 手机---> 硬件:cpu(arm架构单片机)+各种传感器(显示屏.距离传感器.温度传感器.gms模块 gprs模块等等).本质上手机就是一个单片机加上一堆传感器,单片机控制各个传感器与人进行负责的交互.(驱动工程师就是在linux底层让传感器可以工作,然后提供控制硬件的接口交给

Linux内核(17) - 高效学习Linux驱动开发

这本<Linux内核修炼之道>已经开卖(网上的链接为: 卓越.当当.china-pub ),虽然是严肃文学,但为了保证流畅性,大部分文字我还都是斟词灼句,反复的念几遍才写上去的,尽量考虑到写上去的每段话能够让读者产生什么疑惑,然后也都会紧接着尽量的去进行解释清楚,中间的很多概念也有反复纠结过怎么解释能够更容易的理解,力求即使对于初学者也可以有很少阻碍的一气读完.同时我也把书中一部分自己的感悟抽出来整理了精华版,share出来.当然水平有限,错漏之处有发现而修订时遗漏的,也有尚没有发现的.这本书

Linux内核调用I2C驱动_以MPU6050为例

Linux内核调用I2C驱动_以MPU6050为例 0. 导语 最近一段时间都在恶补数据结构和C++,加上导师的事情比较多,Linux内核驱动的学习进程总是被阻碍.不过,十一假期终于没有人打扰,有这个奢侈的大块时间,可以一个人安安静静的在教研室看看Linux内核驱动的东西.按照Linux嵌入式学习的进程,SPI驱动搞完了之后就进入到I2C驱动的学习当中,十一还算是比较顺利,I2C的Linux驱动完成了. 为了测试I2C是否好用,选择一个常用的I2C传感器,手头有个MPU6050,刚好作为I2C的

Linux驱动学习步骤(转载)

1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, lsmod, rmmod. 在驱动的init函数里打印hello world, insmod后应该能够通过dmesg看到输出. 5. 写一完整驱动, 加上read, write, ioctl, polling等各种函数的驱动实现. 在ioctl里完成从用户空间向内核空间传递结构体的实现. 6. 写一bl