linux 下 I2C 设备驱动 实现 总结 s3c2440

来源:互联网 发布:win10系统改mac地址 编辑:程序博客网 时间:2024/05/16 13:49

参考连接:

http://blog.chinaunix.net/uid-27041925-id-3630192.html

http://www.cnblogs.com/liugf05/archive/2012/12/04/2801951.html

http://blog.csdn.net/ypoflyer/article/details/6376545

http://blog.csdn.net/yyplc/article/details/7448174

http://blog.chinaunix.net/uid-26743670-id-3235955.html

http://www.linuxidc.com/Linux/2014-05/101648.htm


I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL ,使用SCL,SDA这两根信号线就实现了设备之间的数据交互,它方便了工程师的布线。

 

Linux I2C驱动架构


结构体:

Driver --> struct i2c_driver驱动方法proberemovesuspendresume

Client --> struct i2c_client只有Client与应用程序,对应真实的物理设备芯片地址,设备名称,设备使用的中断号,设备所依附的控制器,设备所依附的驱动等内容

Algorithm -->struct i2c_algorithm(算法通信方法

Adapter --> struct i2c_adapter控制器控制器名称,algorithm数据,控制器设备等

 

i2c-core承上启下

linux-2.6.22.6/drivers/i2c/i2c-core.c

*增加/删除i2c控制器的函数

int i2c_add_adapter(struct i2c_adapter *adapter)

int i2c_del_adapter(struct i2c_adapter *adap)

*增加/删除设备驱动的函数

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

void i2c_del_driver(struct i2c_driver *driver)

*增加/删除i2c设备的函数

struct i2c_client * i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)

void i2c_unregister_device(struct i2c_client *client) 

                                                            

read()系统调用的流程

 适配器的驱动

linux-2.6.22.6/drivers/i2c/busses/i2c-s3c2410.c :

platform_driver_register

static struct platform_driver s3c2410_i2c_driver = {

.probe = s3c24xx_i2c_probe,

};

s3c24xx_i2c_init

i2c_add_adapter -> i2c_register_adapter

  

当适配器加载到内核后,接下来的工作就要针对具体的设备编写设备驱动了。

设备驱动 :I2C子系统下有两种模式 用户模式 、普通的设备驱动

用户模式设备驱动依赖I2C子系统中的i2c-dev这个驱动我们需要在应用程序去封装数据,这需要应用程序的开发人员具备相当的硬件基础

I2c-dev驱动是系统自带的一个通用客户驱动它不是针对某一个I2C设备(即没有自己驱动设备id-table)

linux-2.6.22.6/drivers/i2c/i2c-dev.c :

i2c_dev_init -> register_chrdev ->i2cdev_fops 

i2c_dev_class

i2c_add_driver->i2cdev_attach_adapter->device_create

 

普通的设备驱动


                                              

                                                                                                                         代码调用层次图

platform_device和platform_driver的匹配方式有两种:

1)直接根据名字来进行匹配

2)通过id_talbe来实现,这种实现的最终还是通过名字对应来匹配,但是匹配的名字被列在一个表中,platform_devicename和这个表中的每一个值进行比较,知道找到相同的那一个

platform_device_registerplatform_driver_register应该先调用哪一个理论上讲是先调用device然后driver,但其实是无所谓的,最后都会调用device_attach()probe


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

#insmod i2c-core.ko

#insmod i2c_algo_bit.ko

#insmod i2c_s3c2410.ko

#insmod i2c_dev.ko

 

#lsmod

Module                  Size  Used by    Not tainted

i2c_dev                 6148  0

i2c_s3c2410             7680  0

i2c_algo_bit            5828  0

i2c_core               20176  3 i2c_dev,i2c_s3c2410,i2c_algo_bit

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

 首先想系统注册的是platform_device型的设备和对应的驱动platform_driver(其中platform_device中包含adapter的相关信息),然后配对成功调用probe函数,最后在probe函数中利用platform_device中包含adapter信息

 结合vmlinux.ldsMakefile,可确定i2c初始化函数的执行顺序如下:

1. /dricer/i2c/i2c-core.c中的函数:i2c_init()  postcore_initcall级别

2./arch/arm/mach-s3c2440/mach-smdk2440.c中的函数:

smdk2440_machine_init()  arch_initcall级别

3.driver/i2c/buses/i2c-s3c2410.c中的函数:

i2c_adap_s3c_init()  subsys_initcall级别                    

4./driver/i2c/i2c-dev.c中的函数:

i2c_dev_init()  module_init级别


0 0
原创粉丝点击