学习韦东山视频心得(三)
I2C总线广泛的用于各种传感器中,仅仅通过SDA,SCL线实现了主机与设备之间的通信。Linux系统中I2C驱动较为庞大。Linux系统中可以采用两种方式实现I2C设备驱动,我们既可以把I2C设备当做普通的字符设备去操作,同时可以利用内核中庞大而错综复杂的框架。如果当做普通的字符设备,程序员只要把管脚模拟时序或者I2C控制器自己实现不采用内核框架,使得程序员不需去研究I2C设备驱动庞大的框架,但是,如此写出来的驱动移植性跟单片机相差无几,移植性能很差,优点是比较直截了当。如果采用内核驱动框架,系统比较庞大需要程序员对I2C驱动框架有一些了解。本设计采用Linux内核I2C驱动框架。
图2.12 I2C驱动框架
I2C设备驱动有两种组件:I2C-dev.c(通用组件),特定组件(例如:OV9650,lm75)对应于特定的设备驱动。如果是I2C-dev.c万能接口,只创建了一个适配器类型i2c_adapter,只是注册了一个主设备号,并没有创建设备文件,但是在ioctl函数发送了从设备的地址,通过万能接口调用核心层接口发送数据,然后才创建临时的虚拟的设备文件,所以说,如果是走通用组件,只是构建了适配类型。如果走特定类型组件例如本设计中OV9650和GT811电容触摸屏,创建了i2c_client,创建设备文件。如图2.12所示。
I2C驱动组要分为三层,四个文件。设备驱动层(OV9650.c),核心层(I2C-core.c),总线驱动层(I2C-s3c2410.c),资源层(同一层次跟总线驱动层)dev-I2C0.c。
1.I2C设备驱动层
I2C的设备驱动层中,其实相当于平台设备机制的驱动层,构建i2c_driver,注册i2c_driver,实现probe函数和操作方法,在probe函数中:获取i2c_cilent,注册主设备号,创建设备文件,注册操作方法。
2.I2C核心层:在核心层中提供了函数接口实现,然后封装发送接收函数。
3.I2C总线驱动层
由于采用平台设备驱动机制实现,此层获取平台资源,实现了probe函数:获取资源,初始哈硬件,使能时钟,注册中断等等,然后构建了I2C_adapter,注册了适配到I2C总线。最后扫描了板级信息链表,通过名字,如果匹配成功,创建设备文件。除此之外,在此层实现了发送数据和读取数据的方法。
4.I2C资源层:包好基地址和大小,I2C中断号。
5.I2C板级资源
I2C板级资源这一实现大大方便了I2C驱动移植,samsung公司的所有内核注册平台数据在smkdv210.c中。设置好I2C板级信息(从机地址和名字)在平台设备大数组中注册,最后在smdkV210_machine_init()函数中注册到板级信息链表中。
2.1.4 GT811(触摸屏)驱动
GT811触摸屏驱动是input子系统和I2C驱动的组合体。Gt811中主要是初始化触摸屏,GT811调用I2C发送接口函数,配置寄存器或者从寄存器中读取坐标的值。在GT811驱动程序中:构建i2c_driver,注册i2c_driver,实现probe函数。在probe函数中,获取i2c_client,然后硬件初始化,包括中断注册,引脚初始化等。接着构建了input_dev,设置input_dev,并且注册了input_dev。到此,我们可以看出GT811probe函数中构建了两类设备,一是i2c_driver,二是input_dev,从中充分体现了其作为I2C驱动和input子系统结合体的特性。下图2.13所示,为GT811驱动框架。
图2.13 GT811驱动构架