linux iic设备中断,Linux I2C框架总结:(基于S5PV210 平台) 完结

Linux I2C相对来说稍微复杂了些,当时听课时,理解了大半,后来因为没有及时复习,导致渐渐遗忘。

现在重新拾起,写一份详细的笔记,以备后期复习,也供大家学习之用。

I2C我就不解释了。有兴趣看笔记的自然也知道什么是I2C。

先来个实用的,说说一般我们是怎么利用I2C框架操作I2C驱动设备的。

如果我们需要在产品中增加一个保存一些少量数据的功能,那么可以在硬件上增加一个E2prom(at24c08)芯片,

该芯片是用I2C协议通信的,我们就以这个例子来说说。

设备、资源准备(完成I2C硬件设备的添加):

1、首先将24c08焊接到S5PV210的I2C0控制器引脚上,调整其A0\A1\A2引脚的高低电平 来设置其器件地址(0xA0)。

2、将24c08的器件地址以及设备名加入到 __i2c_board_list 链表

1、在Mach-smdkv210.c文件中的 i2c_board_info smdkv210_i2c_devs0 增加:

static struct i2c_board_info smdkv210_i2c_devs0[] __initdata = {

...

{ I2C_BOARD_INFO("24c08", 0x50), },     /* Samsung S524AD0XD1 */

...

...

};

(注意,这里的24c08的真实器件地址是0xA0,因为还有个读写位,所以需要将0xA0右移动一位 0xA0>>1 = 0x50 )

在使用I2C子系统的时候,需要将 i2c-dev.c  i2c-core.c  i2c-s3c2410.c 编译进内核( make zImage/uImage)

1、首先看源码所在目录下的Makefile    ~/linux_source/linux-3.0.8/drivers/i2c/Makefile

1、i2c-dev.c 驱动层  i2c-core.c 核心层

9e0080a38a8e5636ea675dffb2984cbf.png

2、i2c-s3c2410.c 总线 ~/linux_source/linux-3.0.8/drivers/i2c/busses/Makefile

e070b5d04765216dc25ac55314036639.png

2、针对Makefile中的 CONFIG_I2C->I2C、CONFIG_I2C_SMBUS 在Kconfig中寻找

d71e7d45ed7cfd03938fbbf158262a9b.png

1ee9ecaca033b224ff1a5263c2aec836.png

ffc127c3cbcf789f87a43f49d8f235c1.png

3、在Kconfig中找到 I2C_support、I2C_device interface,然后配置内核 make menuconfig

主界面 ---> Device Drivers  --->   I2C_support --->   I2C_device_interface

d576cb0c1c5933273bf8701ab244e425.png

14b3d0394fcedaebb5c415a248430fea.png

3c6950e4da6156d1f2f091338cf58d64.png

eca2960887cc8229df15d5656b751aeb.png

应用层利用Linux I2C框架来读写I2C设备有两种方式(大概流程-后面会有详细实现代码):

1、利用I2C适配器设备文件的方式(需要指定I2C设备的器件地址)

直接可以编写应用层代码即可。

步骤:(以E2prom为例子,它挂在第0个I2C控制器)

1、打开I2C设备I2C控制器0

fd = open("/dev/i2c-0", O_RDWR);

2、发送E2prom的I2C器件地址 addr = 0x50

ioctl(fd, I2C_SLAVE, addr)

3、读数据 需要先写入要读取的起始地址(E2prom里的地址)

write(fd, &chip_addr, 1);

read(fd, rbuf, 8);

4、写数据 需要先写入要写入的起始地址(E2prom里的地址)

wbuf[0] = 0x0;       // 指定要从 0 地址开始写

strncpy(tmp+1, data, strlen(data));

write(fd, wbuf, 9);

5、关闭

close(fd);

2、自己写驱动,为指定I2C设备创建一个设备文件供应用层直接打开操作(只需要提供设备名即可)

需要自己写一个ko驱动,然后应用层打开由这个ko文件创建的设备文件,进行操作

步骤:(以E2prom为例子,它的设备名为 24c08)

1、编写ko驱动流程

1、构建struct i2c_driver,实现 .probe       .remove       成员

2、实现.probe()、.remove() 函数

1、获取Client

2、申请设备号、关联操作方法(即 fops)

3、创建设备类、设备节点文件(如 e2prom) 供上层操作

4、实现fops各函数,如read、write 等。。。

3、i2c_add_driver(&e2prom_drv);

当注册I2C驱动后,i2c核心层会将此驱动的id_table与设备链表中的I2C_Client的

名字进行匹配,匹配成功后会执行.probe()函数

2、编写上层应用

fd =open("/dev/e2prom",O_RDWR);

读写方式与上面一样,只是不需要再利用ioctl发送器件地址。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------

好了,用是知道怎么用,那么实现原理是什么呢。这里涉及到平台驱动的知识,因为I2C需要通过平台驱动来初始化I2C控制器,

不懂的童鞋请先搞懂平台驱动。

首先要了解I2C驱动的工作的大致流程,抓住这个大致流程后,再具体分析代码时就会轻松很多:

第一步,就是我们准备的资源了:

1、所有I2C设备的板级信息,如E2prom的设备名和器件地址

~/linux_source/linux-3.0.8/arch/arm/mach-s5pv210/mach-smdkv210.c

static struct i2c_board_info smdkv210_i2c_devs0[] __initdata = {

{ I2C_BOARD_INFO("24c08", 0x50), },     /* Samsung S524AD0XD1 */

{ I2C_BOARD_INFO("wm8580", 0x1b), },

};

static struct i2c_board_info smdkv210_i2c_devs1[] __initdata = {};

static struct i2c_board_info smdkv210_i2c_devs2[] __initdata = {};

(这里的I2C设备资源会在mach-smdkv210.c 里面被加入了 __i2c_board_list 链表)

2、每个I2C控制器的平台设备资源,主要是控制器的硬件资源(如相关寄存器、中断)(S5PV210 平台有三个I2C控制器)

~/linux_source/linux-3.0.8/arch/arm/plat-samsung/dev-i2c0.c -> struct platform_device s3c_device_i2c0 = {}

static struct resource s3c_i2c_resource[] = {

[0] = {

.start  = S3C_PA_IIC,

.end        = S3C_PA_IIC + SZ_4K - 1,

.flags        = IORESOURCE_MEM,                                // 内存资源 即寄存器地址

},

[1] = {

.start        = IRQ_IIC,

.end        = IRQ_IIC,

.flags        = IORESOURCE_IRQ,                                // 中断资源

},

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值