ImageVerifierCode 换一换
格式:DOCX , 页数:10 ,大小:112.17KB ,
资源ID:17864483      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/17864483.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Linux I2C总线分析主要是probe的方式Word文档下载推荐.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Linux I2C总线分析主要是probe的方式Word文档下载推荐.docx

1、是该i2c主设备传输数据的一种算法,或者说是在i2c总线上完成主从设备间数据通信的一种能力。Linux的i2c子系统新、旧架构并存。主要分为旧架构(Legacy)也有人称之为adapter方式,和新的架构new-style的方式。这俩者的区别主要在于设备注册和驱动注册的不同。对于Legacy的设备注册是在驱动运行的时候动态的创建,而新式的new-style则是采用静态定义的方式。注:MTK在Android2.1版上用的是Legacy的架构,而在Android2.2版上用的是new-style的架构。(在这里我就只说明Android2.2的new-style的实现方法)要完成I2C设备的驱动,我

2、们可以分三步走:第一步:完成适配器的注册(总线);第二步:完成I2C client的设备注册(设备);第三步:完成I2C client驱动的注册(驱动);我们分别给予介绍:(I2C-mt6516.c)就总线而言,其本质只需要我们填充俩个结构体就可以了:i2c_adapter;i2c_algorithm;i2c_add_adapter(i2c-adap); 往总线上添加对应的适配器;struct i2c_adapter struct module *owner;unsigned int id;unsigned int class; /* classes to allow probing for

3、*/const struct i2c_algorithm *algo; /* the algorithm to access the bus */void *algo_data;/* - administration stuff. */int (*client_register)(struct i2c_client *);int (*client_unregister)(struct i2c_client *);/* data fields that are valid for all devices */u8 level; /* nesting level for lockdep */str

4、uct mutex bus_lock;struct mutex clist_lock;int timeout; /* in jiffies */int retries;struct device dev; /* the adapter device */int nr; /*该成员描述了总线号*/struct list_head clients; /* i2c_client结构链表,该结构包含device,driver和 adapter结构*/char name48;struct completion dev_released;static struct i2c_algorithm mt6516

5、_i2c_algorithm = .master_xfer = mt6516_i2c_transfer, .smbus_xfer = NULL, .functionality = mt6516_i2c_functionality,2、设备注册记得以前的i2c设备驱动,设备部分喜欢驱动运行的时候动态创建,新式的驱动倾向于向传统的linux下设备驱动看齐,采用静态定义的方式来注册设备,使用接口为:int _init i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len) int sta

6、tus; mutex_lock(&_i2c_board_lock); /* dynamic bus numbers will be assigned after the last static one */ if (busnum = _i2c_first_dynamic_bus_num) _i2c_first_dynamic_bus_num = busnum + 1; for (status = 0; len; len-, info+) struct i2c_devinfo *devinfo; devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);/申

7、请表示i2c设备的结构体空间 if (!devinfo) pr_debug(i2c-core: cant register boardinfo!n); status = -ENOMEM; break; /* 填写i2c设备描述结构 */ devinfo-busnum = busnum;board_info = *info; list_add_tail(&devinfo-list, &_i2c_board_list);/添加到全局链表_i2c_board_list中 mutex_unlock(& return status;在系统初始化的过程中,我们可以通过 i2c_register_board

8、_info,将所需要的I2C从设备加入一个名为_i2c_board_list双向循环链表,系统在成功加载I2C主设备adapt后,就会对这张链表里所有I2C从设备逐一地完成 i2c_client的注册。 系统初始化的时候,会根据板级i2c设备配置信息,创建i2c客户端设备(i2c_client),添加到i2c子系统中:static void i2c_scan_static_board_info (struct i2c_adapter *adapter) list_for_each_entry(devinfo, &_i2c_board_list, list) /遍历全局链表_i2c_board_

9、list if (devinfo-busnum = adapter-nr & !i2c_new_device(adapter,board_info) printk(KERN_ERR t create i2c%d-%04xn, i2c_adapter_id(adapter),board_info.addr);struct i2c_client *i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) struct i2c_client *client; int status; client = kza

10、lloc(sizeof *client, GFP_KERNEL);client) return NULL; client-adapter = adap;dev.platform_data = info-platform_data; if (info-archdata) client-dev.archdata = *info-archdata;flags = info-flags;addr = info-addr;irq = info-irq; strlcpy(client-name, info-type, sizeof(client-name); /* Check for address bu

11、siness */ status = i2c_check_addr(adap, client-addr); if (status) goto out_err;dev.parent = &client-adapter-dev;dev.bus = &i2c_bus_type;dev.type = &i2c_client_type; dev_set_name(&dev, %d-%04x, i2c_adapter_id(adap), status = device_register(&dev); dev_dbg(&adap-client %s registered with bus id %snnam

12、e, dev_name(&dev); return client;out_err: dev_err(&Failed to register i2c client %s at 0x%02x (%d)n, client-name, client-addr, status); kfree(client); return NULL;IDR机制:完成的是设备ID和结构体的关联。_i2c_first_dynamic_bus_num:当前系统允许的动态总线的最大值。i2c_scan_static_board_info(adap);/*完成新类型i2c设备的注册,一般只在主板初始化时*/此函数为整个I2C子系

13、统的核心,它会去遍历一个由I2C从设备组成的双向循环链表,并完成所有I2C从设备的i2c_client的注册。struct i2c_devinfo *devinfo; /已经建立好了的I2C从设备链表status = i2c_check_addr(adap, client- 特别要提一下的是这个“i2c_check_addr”,引用里的话:“i2c 设备的7 位地址是就当前i2c 总线而言的,是“相对地址”。不同的i2c 总线上的设备可以使用相同的7 位地址,但是它们所在的i2c 总线不同。所以在系统中一个i2c 设备的“绝对地址”由二元组(i2c 适配器的ID 和设备在该总线上的7 位地址)

14、表示。”,所以这个函数的作用主要是排除同一i2c总线上出现多个地址相同的设备。3、I2C驱动注册:static inline int i2c_add_driver(struct i2c_driver *driver) return i2c_register_driver(THIS_MODULE, driver);int i2c_register_driver(struct module *owner, struct i2c_driver *driver) int res; /* Cant register until after driver model init */ if (unlikel

15、y(WARN_ON(!i2c_bus_type.p) return -EAGAIN; /* add the driver to the list of i2c drivers in the driver core */ driver-driver.owner = owner;driver.bus = & /* When registration returns, the driver core * will have called probe() for all matching-but-unbound devices. */ res = driver_register(&driver-dri

16、ver); if (res) return res; driver %s registeredn, driver-driver.name); INIT_LIST_HEAD(&clients); /* Walk the adapters that are already present */core_lock); bus_for_each_dev(&i2c_bus_type, NULL, driver, _attach_adapter); return 0;设备和驱动的关联过程:首先当I2C从设备和I2C驱动如果处于同一条总线上,那么其在设备和驱动注册之后,将会促使I2C_bus_type中的m

17、atch获得调用;()如下:struct bus_type i2c_bus_type = .name = i2c .match = i2c_device_match, .probe = i2c_device_probe, .remove = i2c_device_remove, .shutdown = i2c_device_shutdown, .suspend = i2c_device_suspend, .resume = i2c_device_resume,继续跟进i2c_device_match;i2c_match_id(driver-id_table, client) != NULL;我

18、们回到i2c_device_probe;这个函数的关键是:status = driver-probe(client, i2c_match_id(driver-id_table, client);它将函数的流程交回到了driver-probe的手中;流程图:过程分享:1、设备和驱动的关联大家知道,对于一个驱动程序有两个元素不可或缺,即设备和驱动,一般驱动都是通过设备名和驱动名的匹配建立关系的,最开始我从代码中只能发现驱动的注册,却不见设备注册的踪影,令人疑惑,跟踪发现,在i2c adapter注册时会遍历i2c_board_info这样一个结构,而这个结构在29以前或更早的内核里是不存在的,它会

19、完成驱动与设备的匹配问题, 2、名字匹配一个i2c驱动是可以有多个名字的,即一个驱动程序可以支持多个设备,该机制是通过 struct i2c_device_id实现的,驱动中建立这么一个结构体数组,i2c架构层便会扫描该数组,与设备名去匹配,匹配成功的都会进入相应probe函数。3、进入probe该过程困惑了我一段时间,其实要进入自己驱动的probe首先需要进入总线的probe,而进入总线probe的前提是与总线的match成功。待解决的困惑:1、I2C从设备名; Legacy 的相关知识:(一) Linux的I2C驱动框架中的主要数据结构及其关系 Linux的I2C驱动框架中的主要数据结构包

20、括:i2c_driver、i2c_client、i2c_adapter和i2c_algorithm。i2c_adapter对应于物理上的一个适配器,这个适配器是基于不同的平台的,一个I2C适配器需要i2c_algorithm中提供的通信函数来控制适配器,因此i2c_adapter中包含其使用的i2c_algorithm的指针。i2c_algorithm中的关键函数master_xfer()以i2c_msg为单位产生I2C访问需要的信号。不同的平台所对应的master_xfer()是不同的,开发人员需要根据所用平台的硬件特性实现自己的XXX_xfer()方法以填充i2c_algorithm的ma

21、ster_xfer指针。i2c_ driver对应一套驱动方法,不对应于任何的物理实体。i2c_client对应于真实的物理设备,每个I2C设备都需要一个i2c_client来描述。i2c_client依附于i2c_adpater,这与I2C硬件体系中适配器和设备的关系一致。i2c_driver提供了i2c-client与i2c-adapter产生联系的函数。当attach a_dapter()函数探测物理设备时,如果确定存在一个client,则把该client使用的i2c_client数据结构的adapter指针指向对应的i2e_ adapter,driver指针指向该i2c_driver,

22、并调用i2e_adapter的client_register()函数来注册此设备。相反的过程发生在i2c_ driver的detach_client()函数被调用的时候。(二) Linux的I2C体系结构中三个组成部分的作用 I2C核心提供了一组不依赖于硬件平台的接口函数,I2C总线驱动和设备驱动之间依赖于I2C核心作为纽带。I2C核心提供了i2c_adapter的增加和删除函数、i2c_driver的增加和删除函数、i2c_client的依附和脱离函数以及i2c传输、发送和接收函数。i2c传输函数i2c_transfer()用于进行I2C适配器和I2C设备之间的一组消息交互i2c_maste

23、r_send()函数和i2c_master_recv()函数内部会调用i2c_ transfer()函数分别完成一条写消息和一条读消息.I2C总线驱动包括I2C适配器驱动加载与卸载以及I2C总线通信方法。其中I2C适配器驱动加载(与卸载)要完成初始化(释放)I2C适配器所使用的硬件资源,申请I0地址、中断号、通过i2c_add_ adapter()添加i2c_adapter的数据结构(通过i2c_del_adapter()删除i2c_adapter的数据结构)的工作。12C总线通信方法主要对特定的I2C适配器实现i2c_algorithm的master_xfer()方法来实现i2c_ msg的

24、传输。不同的适配器对应的master_xfer()方法由其处理器的硬件特性决定。I2C设备驱动主要用于I2C设备驱动模块加载与卸载以及提供I2C设备驱动文件操作接口。I2C设备驱动的模块加载通用的方法遵循以下流程:首先通过register_chrdev()将I2C设备注册为一个字符设备,然后利用I2C核心中的i2c_add_a_dapter()添加i2c_driver。调用i2c_add_adapter()过程中会引发i2c_driver结构体中的YYY_attach_adapter()的执行,它通过调用I2C核心的i2e_probe()实现物理设备的探测。i2c_probe()会引发yyy_detect()的调用。yyy_detect()中会初始化i2c_ client,然后调用内核的i2e_attach_client()通知I2C核心此时系统中包含了一个新的I2C设备。之后会引发I2C设备驱动中yyy_init_client()来初始化设备。卸载过程执行相反的操作。I2C设备驱动模块加载与卸载的流程 如图2 所示。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1