Linux設备驱动之I2C架构分析.docxVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Linux設备驱动之I2C架构分析

?Linux设备驱动之I2C架构分析一:前言I2c是philips提出的外设总线.I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL.正因为这样,它方便了工程人员 的布线.另外,I2C是一种多主机控制总线.它和USB总线不同,USB是基于master-slave机制,任何设备的通信必须由主机发起才可以.而 I2C 是基于multi master机制.一同总线上可允许多个master.关于I2C协议的知识,这里不再赘述.可自行下载spec阅读即可.二:I2C架构概述在linux中,I2C驱动架构如下所示:如 上图所示,每一条I2C对应一个adapter.在kernel中,每一个adapter提供了一个描述的结构(struct i2c_adapter),也定义了adapter支持的操作(struct i2c_adapter).再通过i2c core层将i2c设备与i2c adapter关联起来.这个图只是提供了一个大概的框架.在下面的代码分析中,从下至上的来分析这个框架图.以下的代码分析是基于linux 2.6.26.分析的代码基本位于: linux-/drivers/i2c/位置.三:adapter注册在 kernel中提供了两个adapter注册接口,分别为i2c_add_adapter()和 i2c_add_numbered_adapter().由于在系统中可能存在多个adapter,因为将每一条I2C总线对应一个编号,下文中称为 I2C总线号.这个总线号的PCI中的总线号不同.它和硬件无关,只是软件上便于区分而已.对于i2c_add_adapter()而言,它使用的是动态总线号,即由系统给其分析一个总线号,而i2c_add_numbered_adapter()则是自己指定总线号,如果这个总线号非法或者是被占用,就会注册失败.分别来看一下这两个函数的代码:int i2c_add_adapter(struct i2c_adapter *adapter){ int id, res = 0;retry: if (idr_pre_get(i2c_adapter_idr, GFP_KERNEL) == 0) return -ENOMEM; mutex_lock(core_lock); /* above here means above or equal to, sigh */ res = idr_get_new_above(i2c_adapter_idr, adapter, __i2c_first_dynamic_bus_num, id); mutex_unlock(core_lock); if (res 0) { if (res == -EAGAIN) goto retry; return res; } adapter-nr = id; return i2c_register_adapter(adapter);}在 这里涉及到一个idr结构.idr结构本来是为了配合page cache中的radix tree而设计的.在这里我们只需要知道,它是一种高效的搜索树,且这个树预先存放了一些内存.避免在内存不够的时候出现问题.所在,在往idr中插入结 构的时候,首先要调用idr_pre_get()为它预留足够的空闲内存,然后再调用idr_get_new_above()将结构插入idr中,该函数 以参数的形式返回一个id.以后凭这个id就可以在idr中找到相对应的结构了.对这个数据结构操作不太理解的可以查阅本站 linux文件系统之文件的读写中有关radix tree的分析.注意一下 idr_get_new_above(i2c_adapter_idr, adapter,__i2c_first_dynamic_bus_num, id)的参数的含义,它是将adapter结构插入到i2c_adapter_idr中,存放位置的id必须要大于或者等于 __i2c_first_dynamic_bus_num,然后将对应的id号存放在adapter-nr中.调用i2c_register_adapter(adapter)对这个adapter进行进一步注册.看一下另外一人注册函数: i2c_add_numbered_adapter( ),如下所示:int i2c_add_numbered_adapter(struct i2c_adapter *adap){ int id; int status; if (adap-nr ~MAX_ID_MASK) return -EINVAL;retry: if (idr_pre_get(i2c_adapter_idr, GFP_KERNEL) == 0) return -ENOMEM; mutex_lock(c

文档评论(0)

sd47f8cI + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档