我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:小鱼儿玄机二站之姐妹 > 起始信号 >

嵌入式Linux系统中I2C总线设备的驱动设计

归档日期:06-06       文本归类:起始信号      文章编辑:爱尚语录

  程序的结构,并以AT91RM9200和X1227为例,介绍了如何在嵌入式

  是PHILIPS公司推出的两线式串行总线,用于连接微控制器及其外围设备,具有简单、高效等特点。由于其接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片引脚的数量,降低了互联成本,特别适用于嵌入式产品。而Linux系统具有开源、免费、网上资源丰富等优点,目前已成为

  的主流选择。因此如何在嵌入式Linux系统中实现I2C功能成为实际开发中的问题。

  I2C总线C 总线通过串行数据SDA 和串行时钟SCL线在连接到总线的器件间传递信息,每个器件都有一个唯一的地址识别。根据数据传输时的功能不同,把器件分为主机和从机。主机是初始化总线的数据传输并产生允许传输的时钟信号的器件,通常是微控制器。此时,任何被寻址的器件都被认为是从机,例如LCD驱动器、E2PROM等。

  I2C总线协议规定,各主机进行通信时都要有起始、结束、发送数据和应答信号。这些信号都是通信过程中的基本单元。起始信号就是在SCL线为高时SDA线从高变化到低;停止信号就是在SCL线为高时SDA线从低变化到高;应答信号是在SCL为高时SDA为低;非应答信号相反,是在SCL为高时SDA为高。

  总线个字节。协议规定,在启动总线位是对从机的寻址地址,第8位为方向位(“0”表示主机对从机的写操作;“1”表示主机对从机的读操作),其余的字节为操作数据。数据传送过程是:在I2C总线发送起始信号后,发送从机的7位寻址地址和1位表示这次操作性质的读写位,在有应答信号后开始传送数据,直到发送停止信号。主机每发送1个字节就要检测SDA线上有没有收到应答信号,有则继续发送,否则将停止发送数据。

  1.I2C core框架:提供了核心数据结构的定义和相关接口函数,用来实现I2C适配器驱动和设备驱动的注册、注销管理,以及I2C通信方法上层的、与具体适配器无关的代码,为系统中每个I2C总线增加相应的读写方法。

  2.I2C总线适配器驱动:定义描述具体I2C总线c_adapter数据结构、实现在具体I2C适配器上的I2C总线c_algorithm数据结构进行描述。

  3.I2C 设备驱动:定义描述具体设备的i2c_client和可能的私有数据结构、借助I2C core提供的函数接口完成设备在内核的注册,并实现具体的功能,包括read, write以及ioctl等对用户层操作的接口。

  总体而言,Linux中I2C总线的驱动分为两个部分:总线驱动(BUS)和设备驱动(DEVICE)。I2C core与I2C总线适配器驱动完成了硬件上的主机总线C driver则实现了从机设备驱动。在设计中,I2C core提供的接口是统一的,不需要修改,我们只需要实现特定I2C总线C设备驱动,这样大大提高了系统的可移植性。

  的时钟模块。在该设计中,AT91RM9200作为I2C的主机部分,X1227作为从机。下面以此为例,具体介绍这两部分驱动的实现。

  AT91RM9200 I2C总线T处理器,它提供标准的两线C接口,主机工作模式。通过TWI 控制寄存器TWI_CR设置I2C工作模式和状态。时钟由寄存器TWI_CWGR中编程值产生。该寄存器定义了TWCK 信号,使接口适应宽范围时钟。具体在linux中AT91RM9200 I2C总线适配器驱动的实现,首先初始化AT91RM9200 I2C的工作模式,然后装载I2C总线驱动,这需要两个结构模块来描述:struct i2c_adapter和struct i2c_algorithm。

  这个模块并未提供读写函数,具体的读写方法由第二个模块struct i2c_algorithm提供。

  数据传输处理如下:数据发送主机初始化Start状态后,向主机模式寄存器TWI_MMR中DADR发送一个7位从机地址,以通知从机器件。从机地址后的位表示传输方向(写或读)。该位为0,说明是写操作(发送操作);若该位为1,说明为数据读请求( 接收操作)。TWI 传输要求从机每收到一个字节后均要给出应答。在应答时钟脉冲中,主机释放数据线(HIGH),将从机拉低以产生应答。主机在该时钟脉冲中轮询数据线,可使用轮询或中断方式来检验状态位。若从机未应答该字节,将置位状态寄存器TWI_SR的NAK 位。

  写操作则发送数据至保持寄存器TWI_THR,设置TWI_CR的START 位以启动传输。数据在内部移位寄存器中移位,当检测到应答,TXRDY位置位,直到TWI_THR中有新数据写入,才清除该位。主机产生STOP 状态来结束传输。设置START 后开始读序列。当状态寄存器中RXRDY 位置位时,接收保持寄存器(TWI_RHR)以收到一个字符。当读TWI_RHR 时RXRDY 位复位。

  TWI接口可执行多种传输格式:7位从机地址和10位从机地址。通过主机模式寄存器TWI_MMR配置三个内部地址字节。若从机仅支持7 位地址,IADRSZ 必须置为0。若从机地址大于7 位,用户必须配置地址大小IADRSZ 并在内部地址寄存器TWI_IADR中设置其他从机地址位。

  X1227 是一个带有时钟、日历、CPU 监控电路和两路查询报警的实时时钟。时钟使用一个低成本的32.768kHz 的晶体作为输入,可精密地用秒、分钟、小时、日期、星期、月、年来显示时间,它可以自动调整闰年至2096年。同时X1227有一个看门狗定时器、3个超时时间可供选择。另外,X1227有一个4K位的EEPROM阵列,可用作某些用户配置数据的存储器。下面以X1227为例,说明一个具体的I2C设备驱动程序的设计要点。

  如前所述,I2C总线驱动只是提供了对一条总线的读写机制,本身并不会去做通信。通信是由I2C设备驱动来做的,设备驱动透过I2C总线同具体的设备进行通讯。一个设备驱动有两个模块来描述,struct i2c_client和struct i2c_driver。i2c_client用来描述一个具体的I2C设备,i2c_driver结构提供了i2c_adapter与i2c_client之间的通信方式。

  其中:attach_adapter利用适配器驱动提供的I2C总线访问方法,利用设备驱动程序模块中提供的地址线索信息,检测可能存在的设备及其地址。如果成功发现设备,则创建一个struct i2c_client来标识这个设备,并向该适配器的数据结构注册。detach_client用于从总线c_client及相应的私有数据结构。command是用户接口中的ioctl功能的底层实现。

  I2C设备驱动需要实现两个方面的接口,一个是对I2C core框架的接口,设备初始化时通过函数i2c_add_driver调用,来实现驱动的注册。这个i2c_driver一旦装入完成,其中的attach_adapter函数就会被调用。

  另一个是对用户应用层的接口,提供用户程序访问I2C设备的接口,包括实现open,release,read,write以及最重要的ioctl等标准文件操作的接口函数。每个设备驱动程序都有一个称为file_operations的数据结构,用来实现接口函数。

  其中open和release用来打开和关闭X1227,x1227_rtc_ioctl则向用户提供的一系列控制时钟芯片的具体命令:RTC_GET_TIME(以固定的数据格式读取实时时钟的时间)、RTC_SET_TIME(以固定的数据格式设定实时时钟的时间)以及E2PROM读写等。

  对于X1227,一般注册为一个miscdevice设备(所有miscdevice设备共同一个主设备号,不同的次设备号)。

  要测试X1227的时钟功能,首先把AT91RM9200的I2C总线模块在系统启动时先后加载。需要指出的是,Linux将时钟分为系统时钟和硬件时钟两种。系统时钟是指当前Linux Kernel中的时钟,而硬件时钟则是主板上由电池供电的那个主板硬件时钟,也就是本文中的X1227。

  在Linux中,用于时钟查看和设置的命令主要有date、hwclock。首先设置系统时钟,比如设置为2006年8月17日12点30分:date 6,然后设置硬件时钟为当前系统时钟时间,使用命令/sbin/hwclock 衧ystohc,则X1227中的时间设置为当前系统时间。然后,通常在操作系统启动时设置启动脚本/sbin/hwclock 衕ctosys,利用X1227内的时间更新系统时钟,然后直到重启或关闭系统,由系统时钟来记录时间。

  本文介绍了I2C总线C设备驱动的实现。该设计成功用于某网络测试设备的主控模块上,实现了设备的实时时钟功能,便于整个系统的监控。I2C总线在目前的嵌入式领域中应用非常广泛,如音/视频的控制,存储设备的通讯等,而Linux也已成为

  的主流。从linux内核看,I2C的驱动程序具有清晰的层次结构,为编程者开发I2C相关驱动提供了规范的框架。

  2. 郑旭阳、李兵兵、黄新平,模拟I2C总线多主通信研究与软件设计,单片机与嵌入式系统应用,2005,12:29_32

本文链接:http://shivatamil.com/qishixinhao/120.html