i2c子系统
linux内核的I2C驱动框架总览
(1)I2C驱动框架的主要目标是:让驱动开发者可以在内核中方便的添加自己的I2C设备的驱动程序,从而可以更容易的在linux下驱动自己的I2C接口硬件
(2)源码中I2C相关的驱动均位于:drivers/i2c目录下。linux系统提供2种I2C驱动实现方法:
第一种叫i2c-dev,对应drivers/i2c/i2c-dev.c,这种方法只是封装了主机(I2C master,一般是SoC中内置的I2C控制器)的I2C基本操作,并且向应用层提供相应的操作接口,应用层代码需要自己去实现对slave的控制和操作,所以这种I2C驱动相当于只是提供给应用层可以访问slave硬件设备的接口,本身并未对硬件做任何操作,应用需要实现对硬件的操作,因此写应用的人必须对硬件非常了解,其实相当于传统的驱动中干的活儿丢给应用去做了,所以这种I2C驱动又叫做“应用层驱动”,这种方式并不主流,它的优势是把差异化都放在应用中,这样在设备比较难缠(尤其是slave是非标准I2C时)时不用动驱动,而只需要修改应用就可以实现对各种设备的驱动。这种驱动在驱动层很简单(就是i2c-dev.c)我们就不分析了。
第二种I2C驱动是所有的代码都放在驱动层实现,直接向应用层提供最终结果。应用层甚至不需要知道这里面有I2C存在,譬如电容式触摸屏驱动,直接向应用层提供/dev/input/event1的操作接口,应用层编程的人根本不知道event1中涉及到了I2C。这种是我们后续分析的重点。
I2C子系统的4个关键结构体
(1)struct i2c_adapter I2C适配器,用来描述I2C控制器的
(2)struct i2c_algorithm I2C算法(时序)
(3)struct i2c_client I2C (从机)设备信息
(4)struct i2c_driver I2C (从机)设备驱动
关键文件
(1)i2c-core.c
(2)busses目录
(3)algos目录
i2c-core.c初步分析
(1)smbus代码略过
(2)模块加载和卸载:bus_register(&i2c_bus_type);
I2C总线的匹配机制
(1)match函数
(2)probe函数
总结:I2C总线上有2条分支:i2c_client链和i2c_driver链,当任何一个driver或者client去注册时,I2C总线都会调用match函数去对client.name和driver.id_table.name进行循环匹配。如果driver.id_table中所有的id都匹配不上则说明client并没有找到一个对应的driver,没了;如果匹配上了则标明client和driver是适用的,那么I2C总线会调用自身的probe函数,自身的probe函数又会调用driver中提供的probe函数,driver中的probe函数会对设备进行硬件初始化和后续工作。
核心层开放给其他部分的注册接口
(1)i2c_add_adapter/i2c_add_numbered_adapter 注册adapter的
(2)i2c_add_driver 注册driver的
(3)i2c_new_device 注册client的
adapter模块的注册(drivers/i2c/busses/i2c-s3c2410.c为例)
(1)平台总线方式注册
(2)找到driver和device,并且确认其配对过程
(3)probe函数
probe函数分析
(1)填充一个i2c_adapter结构体,并且调用接口去注册之
(2)从platform_device接收硬件信息,做必要的处理(request_mem_region & ioremap、request_irq等)
(3)对硬件做初始化(直接操作soc内部I2C控制器的寄存器)
i2c_algorithm
(1)i2c->adap.algo = &s3c24xx_i2c_algorithm;
(2)functionality
(3)s3c24xx_i2c_doxfer
i2c_driver的注册
(1)以gslX680的驱动为例
(2)i2c_driver的基本分析:name和probe
i2c_client从哪里来
(1)直接来源:i2c_register_board_info
smdkc110_machine_init
i2c_register_board_info
struct i2c_board_info {
char type[I2C_NAME_SIZE]; // 设备名
unsigned short flags; // 属性
unsigned short addr; // 设备从地址
void *platform_data; // 设备私有数据
struct dev_archdata *archdata;
#ifdef CONFIG_OF
struct device_node *of_node;
#endif
int irq; // 设备使用的IRQ号,对应CPU的EINT
};
(2)实现原理分析
内核维护一个链表 __i2c_board_list,这个链表上链接的是I2C总线上挂接的所有硬件设备的信息结构体。也就是说这个链表维护的是一个struct i2c_board_info结构体链表。
真正的需要的struct i2c_client在别的地方由__i2c_board_list链表中的各个节点内容来另外构建生成。
函数调用层次:
i2c_add_adapter/i2c_add_numbered_adapter
i2c_register_adapter
i2c_scan_static_board_info
i2c_new_device
device_register
总结:I2C总线的i2c_client的提供是内核通过i2c_add_adapter/i2c_add_numbered_adapter接口调用时自动生成的。
gslX680驱动的移植实践
初步移植实验
(1)源码获取
(2)源码加入内核中
(3)mach文件中添加board_info
(4)编译后内核去启动
在内核配置中添加CONFIG项
(1)定义一个宏名,譬如CONFIG_TOUCHSCREEN_GSLX680
(2)在代码中使用宏来条件编译
(3)在Makefile中使用宏来条件配置
(4)在Kconfig项目中添加宏的配置项
(5)make menuconfig并选择Y或者N
i2c子系统的更多相关文章
- 嵌入式Linux内核I2C子系统详解
1.1 I2C总线知识 1.1.1 I2C总线物理拓扑结构 I2C总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成.通信原理是通过对SCL和SDA线高 ...
- Linux驱动编程--基于I2C子系统的I2C驱动
代码中,我添加了很多注释,应该不难理解,有错误大家可以指出来,我再改正 #include <linux/kernel.h> #include <linux/module.h> ...
- Linux内核中SPI/I2c子系统剖析
Linux内核中,SPI和I2C两个子系统的软件架构是一致的,且Linux内核的驱动模型都以bus,driver,device三种抽象对象为基本元素构建起来.下文的分析将主要用这三种抽象对象的创建过程 ...
- Linux i2c子系统(一) _动手写一个i2c设备驱动
i2c总线是一种十分常见的板级总线,本文以linux3.14.0为参考, 讨论Linux中的i2c驱动模型并利用这个模型写一个mpu6050的驱动, 最后在应用层将mpu6050中的原始数据读取出来 ...
- 初探linux子系统集之i2c子系统(一)
I2c子系统在进公司来的时候就学习过了,可是那是还不是很熟悉linux中的i2c子系统,就没有细看.记得当初很想熟悉linux中的各种总线驱动,想专门写一个关于总线驱动的专集,后来发现好像就没有几个, ...
- I2C子系统驱动框架及应用 (转)
I2C子系统驱动框架: 应用程序层(app层) ——————————————————————————————————– i2c driver层: 从设备驱动层(TS Sensor等) 1. ...
- 十四、i2c子系统
由于之后的触摸屏驱动分析中使用到了GPIO子系统和i2c子系统,因此在分析触摸屏驱动之前我准备把这两个子系统进行简单分析. 在读者学习本章以及后续i2c相关章节之前,最好了解i2c通信方式,可以参考: ...
- 初探linux子系统集之i2c子系统(二)
大概也是前年了,一直没有把那个i2c的子系统讲解完,这里偷个懒,把以前整理的i2c相关的知识再梳理一下,做个了结,然后再去学习timer子系统. 先看下i2c在内核中的代码分布: obj-$(CONF ...
- I2C子系统之驱动SSD1306 OLED
理解I2C设备驱动框架,主要围绕四个结构体去分析就容易了. struct i2c_algorithm:提供I2C协议的实现的操作,如:master_xfer实现数据收发的最基本方法. struct i ...
随机推荐
- Bootstrap框架和inconfont、font-awesome使用
iconfont的使用:https://www.cnblogs.com/clschao/articles/10387580.html Bootstrap介绍 Bootstrap是Twitter开源的基 ...
- (C#) 多线程访问int, bool 等值类型变量
参考: https://stackoverflow.com/questions/154551/volatile-vs-interlocked-vs-lock/154803
- apk 反编译 - 最新版图文教程
apk 反编译 - 最新版图文教程 结合网上众多教程,整理一篇自己操作的,工具都是目前最新版 apk 反编译也就是将打包后的 apk 反编译为资源文件(图片).layout.样式.相关的实现代码等.( ...
- 对View的onMeasure()方法的进一步研究
在Android开发中,很多人对自定义View是望而生畏,但这又是向高级进阶的必经之路,主要是对View里面的很多方法不知道怎么理解,其中一个就是onMeasure()方法. 首先,我自定义一个MyV ...
- JS 日期与时间戳相互转化
1.日期格式转时间戳 function getTimestamp(time) { return Date.parse(new Date(time)); } 2.时间戳转日期格式 function tr ...
- 毕向东_Java基础视频教程第20天_IO流(5~6)
第20天-05-IO流(文件列表一) static File[] listRoots() List the available filesystem roots. String[] list() Re ...
- NexusFile(文件管理器)
NexusFile是一款来自于韩国的文件管理器,类似于TotalCommander,拥有两个并排的文件夹窗口. NexusFile软件的特性如下: 基本功能:复制/移动, 复制/剪切/粘贴, 删除/擦 ...
- Python学习---django下的cookie操作 180201
什么是Cookies 什么是Cookies cookies设置的原因: 1. http请求的无记忆性: 2.加快访问速度 3. 减少服务器压力 cookies特点: cookies保存在客户端浏览器 ...
- 在VisualStudio中远程调试IIS站点
如何在本地调试服务器上的站点? 如果要在本地调试服务器上的站点我们需要用到一个远程调试工具msvsmon.exe. 我们可以再VS安装目录中找到它 如:C:\Program Fil ...
- echo 与 od -x 与 %!xxd 命令
echo 与 od -x 与 %!xxd 命令 echo 命令 -n 选项 可以使其不带换行符od -x 命令可以查看文件的16进制表示%!xxd 可以在vim编辑器中dump成16进制表示