基于ARM的字符驱动程序_第1页
基于ARM的字符驱动程序_第2页
基于ARM的字符驱动程序_第3页
基于ARM的字符驱动程序_第4页
基于ARM的字符驱动程序_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于 Linux 的字符设备驱动设计与实现 信息工程学院 计算机15-3班 刘云飞 摘要: 在基于 Linux 的嵌入式工业控制系统的开发过程中, 针对最常见的字符设备, 探索了一种设备驱动程序设计的一般方法。该方法为这一类设备驱动实现提供了整体框架, 降低了驱动设计难度。实时时钟模块是典型的字符设备也是工业控制系统中的重要组成部分。作者以基于 I2C 总线的实时时钟在 ARM9 平台的驱动实现为例, 详细介绍了这一方法在嵌入式系统开发中的具体应用。关键词: Linux; 驱动程序; 实时时钟; 嵌入式系统在工业过程自动化领域, 嵌入式技术在稳定性, 可扩展性,成本, 功耗等许多方面已逐步展现出其与传统控制手段相比的独特优势。对于嵌入式工业控制系统, 尽管被控对象和应用场的差异使得外围设备及其接口形式相对丰富复杂, 但总可以将它们归结到 Linux 系统的三设备: 字符设备、块设备、网络设备中来, 而字符设备是其中最常见的形式。 笔者在实际的开发过程中探索和总结了一种针对嵌入式 Linux 字符设备驱动设计实现的一般办法。并通过讨论 RISC 目标系统中典型外围设备- 基于 I2C 总线技术的实时时钟设计与实现, 阐述了这一方法在实际开发中的具体应用。1 Linux 设备驱动程序实现关键技术的归纳与总结Linux 设备驱动程序是为特定的硬件提供给用户程序的一组标准化接口, 它隐藏了设备工作的细节。虽然外部设备差异很大, 但设备的驱动程序遵循一定的通用方法。1) 基于文件的设备管理方式。在 Linux 系统里, 任何设备都以设备文件的形式来表示, 也就是说, 通过对设备文件的操作来实现对硬件设备的操作。2) 主设备号与次设备号。Linux 系统为每一个设备分配了一个主设备号和次设备号, 主设备号标识设备对应的驱动程序, 次设备号标识具体设备的实例。每一类设备使用的主设备号是独一无二的, 系统增加一个驱动程序就要赋予它一个主设备号。这一赋值过程在驱动程序的初始化时进行。3) Linux 设备的操作。系统访问设备就像访问文件一样, 例如打开设备使用系统调用 open( ), 关闭设备使用系统调用 close( )。在 Linux内核中, 字符设备使用 struct file_operations 结构来定义设备的各种操作集合。编写字符设备驱动程序, 主要是实现 structfile_operations 结构中的各个函数。对于结构中没有实现的操作函数, 函数指针变量设置为 NULL。sruct_file_operations 结构在/include/linux/fs.h 文件中定义。4) Linux 设备的注册和卸载。设备驱动程序所提供的入口点, 在设备驱动程序初始化的时候向系统进行注册, 以便系统在适当的时候调用。在 Linux 系统中, 通过调用 devfs_register 向系统注册字符型设备驱动程序。devfs_register()的定义为:#define linux/devfs_fs_kernel.hdevfs_handle_t devfs_register (devfs_handle_t dir,const char*name,unsigned int flags,unsigned int major,unsigned int minor,u-mode_t mode,void *ops,void *info);其中, dir 为新创建的设备文件的父目录; Name 为设备的名称; Flags 为 devfs 标志的位掩码; Major 为设备的主设备号;Minor 为设备的次设备号; Mode 为新设备的访问模式; Ops 表示指向设备文件操作数据结构的指针; Info 表示系统设备打开时,文件系统将把 flip- private_data 的指针初始化为该值。类似的, 字符设备的卸载函数定义为:devfs_unregister (devfs_handle_t dev)。接下来, 利用上文提出的方法, 在 Linux 2.4 内核下具体设计实现实时时钟的驱动程序。2 实时时钟驱动程序设计在这一部分, 我们首先说明目标系统的硬件平台及实时时钟驱动程序实现的整体框架, 接着针对实时时钟设备具体操作讨论用户利用驱动程序实现设备管理的过程及软件流程, 最后强调驱动程序设计过程中的一些注意事项。2.1. 目标平台简介目标系 统的 核 心 采用 Cirrus Logic 公 司 32 位微 处 理 器EP9315。该芯片内嵌先进的运行于 200MHZ 的 ARM920T 核, 具有非常丰富的片上资源。实时时钟芯片为飞利浦公司的 PCF8563, 该芯片功耗很低, 具有一个可编程时钟输出, 一个中断输出和掉电检测器, 最大总线速度为 400Kbits/s。以 PCF8563 为实时时钟源, 并外备锂纽扣电池, 为控制系统提供可靠的日历。EP9315 与 PCF8563 通过 I2C 总线进行数据通信, 以完成系统时间的设定和日历信息的获取。如图一所示为两者之间的接口实现示意。EP9315 内部集成了 I2C 总线控制器, 通过 GPIO复 用 实 现 (EEDAT, EECLK 分 别 对 应 GPIOG1, GPIOG0) ;PCF8563 具有中断控制功能,将 INT 与 EPIO13 相连(EGPIO 是EP9315 具有中断功能的通用 IO)。硬件连接简单可靠。图一 实时时钟接口示意2.2. 实时时钟驱动程序的整体框架1) 必要的声明与宏定义#include linux/module.h /* 以模块的方式实现驱动程序 */#include linux/devfs_fs_kernel.h#include iic.c /* 给出了对于 PCF8563 具体操作的实现#define RTCIIC_MAJOR 16 /* 定义设备的主设备号 */#define outl(v,p) outl_t(v,p) /* 端口操作的地址映射 */#define outl_t(v,p)(*(volatile unsigned long *)(p) = (v)2) 实时时钟设备注册及初始化static int _init rtciic_init_module(void)/* 注册设备 rtciic 指向对设备文件操作的数据结构 */dev_handle1 =devfs_register (NULL,rtciic,DEVFS_FL_DE-FAULT,RTCIIC_MAJOR,0, S_IFCHR, &rtciic_fops, NULL);outl(0x03,GPIO_EEDRIVE); outl(0x03,GPIO_PGDDR); /* 初始化 I2C 控制器 */P8563_init(); /* 初始化外围实时时钟芯片 */3) 实时时钟设备注销static void _exit rtcclriic_module(void)devfs_unregister (dev_handle1);2.3. 实时时钟具体操作设计与实现在设备注册过程中, 我们构建了 rtciic_fops 结构指针。在File_operations 结构中定义一组函数指针。struct file_operations rtciic_fops=read : read_rtciic,write: writer_rtciic,ioctl: ioctl_rtciic,open : open_rtciic,release: release_rtciic,系统就是通过这一组函数指针来实现 I2C 实时时钟设备的操作。具体的说, 这主要有两方面工作: 对实时时钟进行时间的设定包括年、月、日、星期、时、分、秒; 从实时时钟获得系统需要的日历信息。分别对应于 writer_rtciic 和 read_rtciic 这两个函数。图二 write_rtciic()系统调用如图二所示 用户空间的应用程序通过调用 writer_rtciic接口, 将存储在 buf 所指向的用户缓冲区大小为 count 长度的数据传递到内核缓冲区, 实现了用户空间到内核空间的数据交换; 驱动程序通过图三所示软件流程将内核缓冲区中用户设定信息通过 I2C 总线技术传递到 PCF8653 的寄存器中, 从而完成了用户对实时时钟的写操作。实时时钟设备的读操作其实现过程与写操作是基本一致的。2.4. 驱动程序实现中的注意事项1) 该驱动程序是在 Linux- 2.4.20 系统下调试通过的。 对于不同的内核版本在设备注册和文件操作方法上可能存在差异。2) 为便于调试和测试, 本驱动程序采用模块方式实现。3) 构建系统 I2C 总线时, EP9315 为主机, PCF8563 为从机。SDA 为双向; SCL 为单向, 相对于实时时钟芯片固定为输入。4) 针对 I2C 总线本身的特点, 在整个设备操作过程中, 严格匹配开始, 结束, 应答等信号的时序是驱动程序正确实现的关键点之一。5)PCF8563 作为 I2C 从设备对于读写两个操作时的地址是不一样的, 读: 0A3H; 写: 0A2, 同时每次进行读写操作时内嵌的字寄存器会自动累加。图三 写操作程序流程图2.5. 驱动程序的验证结果驱动程序的验证, 是通过用户空间的应用程序来实现的。这是一个相对简单的过程, 主要包括如下步骤:以可读写的方式打开设备文件, 并获得设备文件的文件描述符;fd=open(/dev/rtciic, O_RDWR)设定 rtc 的初值, 注意这些值必须以 BCD 码的格式给出;char timeset=0x00,0x00,0x06,0x26,0x5,0x11,0x06;write(fd,timeset,sizeof(timeset)从 RTC 上读出系统时间到缓冲区;char rbuf7;read(fd,rbuf,7);经交叉编译器编译, 通过 tftp 方式下载到目标系统中;在目标系统的 shell 中执行, 结果如图四所示。3 结论该实时时钟实现方法已应用于某高压气体压力与流量控制的嵌入式系统中, 实时时钟不仅能够在系统断电情况下长时间的保持设备日历并为嵌入式软件提供状态信息, 同时也为设备的安全稳定运转及故障诊断等提供参考依据。实时时钟设备的设计与实现, 详细的说明了这一方法的具体应用过程。将该方法运用于高压气体压力与流量控制系统其他字符设备驱动开发中, 起到良好的指导作用。创新点: 归纳总结了一种针对字符设备在 Linux 平台下驱动实现的一般方法; 基于 ARM- LINUX 在 ARM9 平台下进行了I2C 总线的实时时钟驱动设计与测试; 用于本文提出的方法, 指导某嵌入式工业控制系统的其它字符设备的驱动开发, 取得了良好的效果。参考文献1胡诚皓; 刘昆; 邵定宏; ERP 中成本计算的重组和实现程. 2Corbe

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论