该篇不属于原创,主要是最近解决了一个I2C的问题,期间看了很多大侠的博文,现在将这个子系统整理一下。
整个I2C framework, eric.xiao大侠做了很详尽的叙述,给了我很大帮助,在此表示感谢,好像也是成都的,有缘....
++++++++++++++++++++++++++++++++++++
这里用稍微“粗俗”一点的语言稍微记录一下,方便记忆即可,
i2c 驱动框架包含三层:
1,i2c core:提供通用的一些方法和通信算法供i2c bus操作使用,这是与具体硬件无关的一层。
2,i2c bus: 这是与具体i2c模块相关的一层,不同的cpu会有不同的实现,主要实现i2c驱动并注册。
3,i2c client:这是具体i2c设备的驱动。
完整的i2c框架会生成两个ko文件(如果你选择M模式的话),一个是bus的,一个是client设备的。
i2c core里面会向sys文件系统注册一个i2c总线并提供i2c总线方法。
i2c bus会使用platform的方式向内核注册device和driver,来完成i2c模块的初始化:通常在板级代码中arch/arm/mach-xxxx/devices.c中完成设备注册,platform_device_register(&xxx_i2c_device);drivers/i2c/busses/i2c-xxxx.c中完成驱动的注册,platform_driver_register(&xxxx_i2c_driver)
i2c client中使用i2c core中提供的方法进行设备和驱动的注册:通常在板级代码中进行设备的注册,这儿core提供的API比较特殊,是使用i2c_register_board_info来向系统注册设备信息,当然如果深入看代码的话,发现里面并没有构建i2c_client结构,但i2c core要使用i2c_client来和driver做匹配,从而绑定的,那它怎么在里面运作的呢?
当i2c bus platform设备注册时,bus的probe函数会被调用,紧接着i2c_add_numbered_adapter()->i2c_register_adapter()->i2c_scan_static_board_info()->i2c_new_device() 会构建i2c_client结构,i2c_attach_client()会将设备注册到系统。不知道为什么设计者要绕这么大一圈子,为了通用性?难道就没有更优美一点的方案?:( 内核设计者的心思你别猜,别猜,猜来猜去就会!^&@¥$
然后在设备的驱动代码里面注册驱动:i2c_add_driver()->i2c_register_driver()->driver_register()->bus_add_driver()->driver_attach()->bus_for_each_dev()->__driver_attach()->driver_probe_device()-> 调用i2c总线的match函数进行driver和device 信息的匹配(根据设备的不同,比较的内容不相同,有时候是name,有时候是id),如果匹配,调用really_probe()->driver的probe。 如果人的经脉,2个小周天后发功......
这里去除了很多内核其它的处理,为了方便理解,仅作为一个备忘录。