首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Linux下I2C总线EEPROM驱动程序设计方法(2)

Linux下I2C总线EEPROM驱动程序设计方法(2)

3 Linux中I2C总线驱动体系结构
在Linux系统中,对于一个给定的I2C总线硬件配置系统,I2C总线驱动程序体系结构由I2C总线驱动和I2C设备驱动组成。其中I2C总线驱动包括一个具体的控制器驱动和I2C总线的算法驱动。一个算法驱动适用于一类总线控制器。而一个具体的总线控制器驱动要使用某一种算法。例如,Linux内核中提供的算法i2e-algo-8260可以用在MPC82xx系列处理器提供的I2C总线控制器上。Linux内核中提供了一些常见处理器如MPC82xx系列的算法驱动。对于I2C设备,基本上每种具体设备都有自己的基本特性。其驱动程序一般都需要特别设计。
在I2C总线驱动程序体系结构中。使用数据结构Driver来表示I2C设备驱动,使用数据结构Client表示一个具体的I2C设备。而对于I2C总线
控制器,各种总线控制器在进行数据传输时采用的算法有好多种,使用相同算法的控制器提供的控制接口也可能不同。在I2C总线驱动程序体系结构中,用数据结构Algorithm来表示算法,用数据结构Adapter来表示不同的总线控制器。Linux内核的I2C总线驱动程序体系结构如图5所示。

图5 Linux内核I2C总线驱动程序体系结构
在图5中,一个Client对象对应一个具体的I2C总线设备,而一种I2C设备的Driver可以同时支持多个Client。每个Adapter对应一个具体的I2C总线控制器。不同的I2C总线控制器可以使用相同的算法Algorithm。i2c-core是I2C总线驱动程序体系结构的核心,在这个模块中,除了为总线设备驱动提供了一些统一的调用接口来访问具体的总线驱动程序功能,以进行读写或设置操作外,还提供了将各种支持的总线设备驱动和总线驱动添加到这个体系中的方法,以及当不再使用这些驱动时将其从体系中删除的方法。i2c-core将总线驱动程序体系一分为二,相互独立。可以针对某个I2C总线设备来设计一个I2C设备驱动程序,而不需要关心系统的I2C总线控制器是何种类型,所以提高了其可移植性。另一方面,在设计I2C总线驱动时也可以不要考虑其将用来支持何种设备。因为i2c-core提供了统一的接口,所以也为设计这两类驱动提供了方便。
4 开发实例
Linux内核已经提供了I2C驱动中所需要的基本模块。i2c-core、i2c-dev和i2c-proc是总线控制器和I2C设备所需要的核心模块。对于MPC8250处理器,内核中还有MPC8260的算法模块i2c-algo-8260,它也适用于MPC8250的I2C控制接口。这些模块程序在默认条件下是不会被编译到内核里的,所以需要在配置Linux内核时把这些模块选中。在笔者的开发中需要实现的是I2C总线控制器驱动和I2C设备EEPROM驱动。
4.1 I2C总线控制器驱动的设计
MPC8250的I2C总线驱动程序由i2c-algo-8260算法模块和MPC8250具体的I2C总线控制器驱动组成。其中i2c-algo-8260算法模块已经在内核中实现,所以主要实现FC总线控制器驱动。
i2c-algo-8260算法模块主要用来描述MPC82xx处理器如何在I2C总线上传输数据。该模块中主要实现了MPC82xx处理器上I2C总线的初始化、读写、ioctl控制和中断请求等功能。另外,还有i2c_8260_add_bus和i2c_8260_del_bus两个函数,它们是使用这个算法的Adapter初始化时和退出时调用的函数,用来注册和注销一个总线控制器,需要从模块导出。这些函数功能都被封装在一个i2c-algorithm结构中,传递给使用这个算法的Adapter。算法模块中这些函数需要调用特定控制器模块中的函数来实现具体的操作。
在I2C总线控制器驱动模块中主要要实现两个结构体i2c_adapter和i2c_algo_8260_data,定义这两个结构中的函数指针成员。并且用己经初始化好的i2c_algo_826o_data结构来初始化struct i2c_adapter结构的algo_data成员变量。其中,定义i2e_algo_8260_data结构为:
struct i2c_algo_8260_data rw8250_data={
setisr:rw8250_install_isr
};
这里的成员变量rw8250_install__isr提供了MPC8250的I2C总线控制器向内核申请中端请求的功能。结构体i2c_adapter定义如下:
struct i2c_adapter rw8250_ops={“rw8250”,I2C_HW_
MPC8250_RW8250,NULL,&rw8250_data,rw8250_inc_use,rw8250_dec_use,rw8250_reg,rw8250_unreg,};
其中,“rw8250”是该总线控制器的标识名,宏名I2C_HW_MPC8250_RW8250定义了内核中注册该适配器的ID号,而成员函数rw8250_inc_use和rw8250_dec_use用来增加和减少内核使用该模块的次数。
另外,该模块还要完成一个注册模块时的初始化函数rw8250_iic_init,在该函数中要初始化I2C控制器使用的通用端口号PortD14、PortD15,并在双端口RAM 中为发送和接受数据的缓冲区分配空间。函数rw8250_iic_init在进行模块初始化时将被init_module调用。
总之。I2C控制器模块中设计的这些函数都是为i2c_algo_8650算法模块服务的。最后需要封装在i2c-adapter结构中。通过i2c_algo_8260_data算法模块中输出的接口函数传递给算法模块。
4.2 I2C设备驱动的设计
I2C设备EEPROM 驱动除了要根据EEPROM的具体特性进行设计外。还要考虑I2C总线驱动程序体系结构的特性。在EEPROM设备驱动程序中需要实现一个i2c_driver结构。每个对应于具体设备的Client都从这个结构来构造。在i2c_driver结构中有两个函数attach_adapter和detach_client必须要实现。i2c_driver结构的定义如下:
struct i2c_driver eeprom_driver = {
/*name*/ “I2C_EEPROM_DRIVER”,/*id*/I2C_DRIVERID_EEPROM,
/*flags*/ I2C_DF_NOTIFY,/*attach_ adapter*/&eeprom_attach_adapter,/*detach_client */&eeprom_detach_client,
/*command*/&eeprom_command,/*inc_use*/ &eeprom_inc_use,/*dec_use*/ &eeprom_dec_use
};
在设备驱动中。向EEPROM 写数据通过调用i2c-core提供的i2c_master_send函数来完成。从EEPROM 读取数据通过另一个函数i2c_master_read来完成。与一般设备驱动不同的地方就是在EEPROM驱动模块初始函数中要调用i2c-core提供的i2c_add_driver函数来注册该设备。在模块退出函数中调用i2c_del_driver函数来注销该设备。
5 结束语
I2C总线具有控制简单、通信速率高等优点,作为一种2线双向同步串行数据总线,它为嵌入式系统设计提供了一种完善的集成电路间的串行总线扩展技术,大大简化了应用系统的硬件设计,为实现应用系统的模块化设计创造了极为有利的条件。同时,在很多情况下需要对系统中的某些动态信息进行掉电保护。在数据量不太大的场合下,通过I2C总线连接的EEPROM在这方面就比较能发挥作用。而Linux作为一种新的操作系统,目前在嵌入式系统中的应用非常广泛。其发展前景无法估量。由于Linux源码开放,且非常易于移植,为其编写设备驱动程序相对容易。本文介绍了Linux下I2C总线EEPROM驱动程序的一般设计方法。
继承事业,薪火相传
返回列表