i2c
来源:互联网 发布:数据库程序设计 编辑:程序博客网 时间:2024/04/30 06:20
在介绍I2C总线结构之前。要搞清楚两个概念:I2C总线控制器和I2C设备。I2C总线控制器为微控制器或微处理器提供控制I2C总线的接口,它控制所有I2C总线的特殊序列、协议、仲裁、时序,这里指MPC8250提供的I2C总线控制接口。I2C设备是指通过I2C总线与微控制器或微处理器相连的设备,如EEPROM、LCD驱动器等,这里指EEPROM。 在一个串行数据通道中.I2C总线控制器可以配置成主模式或从模式。开发过程中,MPC8250的I2C总线控制器工作在主模式,作为主设备;与总线相连的I2C设备为AT24C01A型EEPROM,作为从设备。主设备和从设备都可以工作于接收和发送状态。总线必须由主设备控制,主设备产生串行时钟控制总线的传输方向,并产生起始和停止条件。
i2c adapter是软件上抽象出来的i2c总线控制器接口物理上一条i2c总线可以挂接多个硬件设备(slave),一个CPU可以挂接多条i2c总线(想象一下PCI总线)i2c总线控制器就是CPU访问I2C总线的硬件接口,也就是你说的那几个寄存器。
看看i2c_device_match函数是怎么匹配的简单点了, 你的开发板上有几个I2C接口,就有几个adapter , 也就是有几条I2C bus, I2C CLIENT 对应的就是你的外围I2C 设备,有几个就有几个CLIENT ,
把这些设备插入开发板, 对应其中的一条BUS, 那么相应的就对应了其中的一个ADAPTER , 接下来的就是 CLIENT 与 ADAPTER 勾搭成对了, 后面就是做该做的事了。
数据在主机与从机间同步于SCL时钟线,在SDA数据线上一字节一字节的传输,每个字节为8位长度,一个SCL时钟脉冲传输一个数据位,数据由最高位MSB首先传输,每个传输字节后跟随一个应答位,每个位在SCL为高电平期间采样;因此,SDA线只有在SCL为低时才可以改变,在SCL为高时SDA必须保持稳定。当SCL为高时,SDA线上的跳变视为一个命令(START 或 STOP),当SDA从低到高时为停止位,当从高到低时位起始位。
I2c_driver: 是子设备的struct device_driveri2c_client :是子设备对应的 struct devicei2c_adapter :是总线对应的设备struct device_driver总线驱动调用i2c_add_adapter 或者i2c_add_numbered_adapter 来注册一个总线设备到内核 流程是:i2c_register_adapter() ->device_register()注册住设备到内核 ->i2c_scan_static_board_info()->i2c_new_device()->device_register(&client->dev) /*到此处已经构建了i2c_client且把板级子设备注册进了内核。*/ 板级子设备信息是通过i2c_register_board_info()函数注册的。I2c_register_board_info函数会把I2C从设备硬件特性信息注册到全局链表__i2c_board_list,在调用i2c_add_adapter函数时,会遍历__i2c_board_list获得从设备信息来构造i2c_client。i2c_add_driver用来注册子设备驱动到内核。会先注册i2c_driver到I2C总线上,然后调用I2C BUS注册的match函数进行匹配,如果匹配成功,则先调用I2C BUS中注册的probe函数,在调用i2c_driver中实现的probe函数,完成相应的工作。i2c_add_driver->i2c_register_driver->driver_register 接下来重点看driver_register是怎样的逻辑int driver_register(struct device_driver * drv){ klist_init(&drv->klist_devices, klist_devices_get, klist_devices_put); init_completion(&drv->unloaded); return bus_add_driver(drv);}主要跳转到bus_add_driverbus_add_driver() -> driver_attach() ->bus_for_each_dev(drv->bus, NULL, drv, __driver_attach)bus_for_each_dev遍历该总线上所有的device,执行一次__driver_attach(),看能不能将驱动关联(attach)到某个设备上去。_driver_attach() ->drv->bus->match(dev, drv), /* 调用bus的match函数,看device和driver匹不匹配。实际调用的是i2c_bus_type里的i2c_device_match来匹配*/ ->driver_probe_device() ->really_probe() /*如果驱动有注册probe函数就直接调用到了。*/
i2c_device_match{ driver = to_i2c_driver(drv); if (driver->id_table) return i2c_match_id(driver->id_table, client) != NULL;}static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id, const struct i2c_client *client){ while (id->name[0]) { if (strcmp(client->name, id->name) == 0) return id; id++; } return NULL;}可以看出其实比较的就是id_table里的名字。
每个bus都有一个drivers_autoprobe变量,用于控制是否在device或者driver注册时,自动probe。该变量默认为1(即自动probe).在device_register函数里也会调用
bus_probe_device来对设备和驱动进行匹配,逻辑和上面类似。
0 0
- I2C
- I2C
- i2c
- I2C
- I2C
- i2c
- i2c
- I2C
- I2C
- I2c
- I2C
- I2C
- I2C
- I2C
- I2C
- i2c
- I2C
- i2c
- 黑马程序员_NSArray
- 黑马程序员 使用通配符和使用泛型变量
- Template template parameter(模板参数) example
- Silverlight中定义布局面板
- 树状数组基本操作
- i2c
- 一个测试SQL2005连接的Java程序
- 石子合并问题(动态规划)
- python的弱引用
- POJ 3259 Wormholes (Bellman)
- OpenGL绘图的基本过程是:清除缓冲区,设置当前颜色,绘制几何图元,输出图形。
- DHCP协议和dhcpcd源码分析
- 聚类算法K-Means, K-Medoids, GMM, Spectral clustering,Ncut
- NOJ [1015] 一个简单的问题