基于ARM的字符驱动程序5页

上传人:文库****9 文档编号:173995932 上传时间:2021-03-15 格式:DOC 页数:5 大小:259.50KB
返回 下载 相关 举报
基于ARM的字符驱动程序5页_第1页
第1页 / 共5页
基于ARM的字符驱动程序5页_第2页
第2页 / 共5页
基于ARM的字符驱动程序5页_第3页
第3页 / 共5页
基于ARM的字符驱动程序5页_第4页
第4页 / 共5页
基于ARM的字符驱动程序5页_第5页
第5页 / 共5页
亲,该文档总共5页,全部预览完了,如果喜欢就下载吧!
资源描述

《基于ARM的字符驱动程序5页》由会员分享,可在线阅读,更多相关《基于ARM的字符驱动程序5页(5页珍藏版)》请在金锄头文库上搜索。

1、基于 Linux 的字符设备驱动设计与实现 信息工程学院 计算机15-3班 刘云飞 5011211304摘要: 在基于 Linux 的嵌入式工业控制系统的开发过程中, 针对最常见的字符设备, 探索了一种设备驱动程序设计的一般方法。该方法为这一类设备驱动实现提供了整体框架, 降低了驱动设计难度。实时时钟模块是典型的字符设备也是工业控制系统中的重要组成部分。作者以基于 I2C 总线的实时时钟在 ARM9 平台的驱动实现为例, 详细介绍了这一方法在嵌入式系统开发中的具体应用。关键词: Linux; 驱动程序; 实时时钟; 嵌入式系统在工业过程自动化领域, 嵌入式技术在稳定性, 可扩展性,成本, 功耗

2、等许多方面已逐步展现出其与传统控制手段相比的独特优势。对于嵌入式工业控制系统, 尽管被控对象和应用场的差异使得外围设备及其接口形式相对丰富复杂, 但总可以将它们归结到 Linux 系统的三设备: 字符设备、块设备、网络设备中来, 而字符设备是其中最常见的形式。 笔者在实际的开发过程中探索和总结了一种针对嵌入式 Linux 字符设备驱动设计实现的一般办法。并通过讨论 RISC 目标系统中典型外围设备- 基于 I2C 总线技术的实时时钟设计与实现, 阐述了这一方法在实际开发中的具体应用。1 Linux 设备驱动程序实现关键技术的归纳与总结Linux 设备驱动程序是为特定的硬件提供给用户程序的一组标

3、准化接口, 它隐藏了设备工作的细节。虽然外部设备差异很大, 但设备的驱动程序遵循一定的通用方法。1) 基于文件的设备管理方式。在 Linux 系统里, 任何设备都以设备文件的形式来表示, 也就是说, 通过对设备文件的操作来实现对硬件设备的操作。2) 主设备号与次设备号。Linux 系统为每一个设备分配了一个主设备号和次设备号, 主设备号标识设备对应的驱动程序, 次设备号标识具体设备的实例。每一类设备使用的主设备号是独一无二的, 系统增加一个驱动程序就要赋予它一个主设备号。这一赋值过程在驱动程序的初始化时进行。3) Linux 设备的操作。系统访问设备就像访问文件一样, 例如打开设备使用系统调用

4、 open( ), 关闭设备使用系统调用 close( )。在 Linux内核中, 字符设备使用 struct file_operations 结构来定义设备的各种操作集合。编写字符设备驱动程序, 主要是实现 structfile_operations 结构中的各个函数。对于结构中没有实现的操作函数, 函数指针变量设置为 NULL。sruct_file_operations 结构在/include/linux/fs.h 文件中定义。4) Linux 设备的注册和卸载。设备驱动程序所提供的入口点, 在设备驱动程序初始化的时候向系统进行注册, 以便系统在适当的时候调用。在 Linux 系统中, 通

5、过调用 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 标志的位掩

6、码; Major 为设备的主设备号;Minor 为设备的次设备号; Mode 为新设备的访问模式; Ops 表示指向设备文件操作数据结构的指针; Info 表示系统设备打开时,文件系统将把 flip- private_data 的指针初始化为该值。类似的, 字符设备的卸载函数定义为:devfs_unregister (devfs_handle_t dev)。接下来, 利用上文提出的方法, 在 Linux 2.4 内核下具体设计实现实时时钟的驱动程序。2 实时时钟驱动程序设计在这一部分, 我们首先说明目标系统的硬件平台及实时时钟驱动程序实现的整体框架, 接着针对实时时钟设备具体操作讨论用户利用驱

7、动程序实现设备管理的过程及软件流程, 最后强调驱动程序设计过程中的一些注意事项。2.1. 目标平台简介目标系 统的 核 心 采用 Cirrus Logic 公 司 32 位微 处 理 器EP9315。该芯片内嵌先进的运行于 200MHZ 的 ARM920T 核, 具有非常丰富的片上资源。实时时钟芯片为飞利浦公司的 PCF8563, 该芯片功耗很低, 具有一个可编程时钟输出, 一个中断输出和掉电检测器, 最大总线速度为 400Kbits/s。以 PCF8563 为实时时钟源, 并外备锂纽扣电池, 为控制系统提供可靠的日历。EP9315 与 PCF8563 通过 I2C 总线进行数据通信, 以完成

8、系统时间的设定和日历信息的获取。如图一所示为两者之间的接口实现示意。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#

9、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,

10、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 结构指针。在

11、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 这两个函数

12、。图二 write_rtciic()系统调用如图二所示 用户空间的应用程序通过调用 writer_rtciic接口, 将存储在 buf 所指向的用户缓冲区大小为 count 长度的数据传递到内核缓冲区, 实现了用户空间到内核空间的数据交换; 驱动程序通过图三所示软件流程将内核缓冲区中用户设定信息通过 I2C 总线技术传递到 PCF8653 的寄存器中, 从而完成了用户对实时时钟的写操作。实时时钟设备的读操作其实现过程与写操作是基本一致的。2.4. 驱动程序实现中的注意事项1) 该驱动程序是在 Linux- 2.4.20 系统下调试通过的。 对于不同的内核版本在设备注册和文件操作方法上可能存在差

13、异。2) 为便于调试和测试, 本驱动程序采用模块方式实现。3) 构建系统 I2C 总线时, EP9315 为主机, PCF8563 为从机。SDA 为双向; SCL 为单向, 相对于实时时钟芯片固定为输入。4) 针对 I2C 总线本身的特点, 在整个设备操作过程中, 严格匹配开始, 结束, 应答等信号的时序是驱动程序正确实现的关键点之一。5)PCF8563 作为 I2C 从设备对于读写两个操作时的地址是不一样的, 读: 0A3H; 写: 0A2, 同时每次进行读写操作时内嵌的字寄存器会自动累加。图三 写操作程序流程图2.5. 驱动程序的验证结果驱动程序的验证, 是通过用户空间的应用程序来实现的

14、。这是一个相对简单的过程, 主要包括如下步骤:以可读写的方式打开设备文件, 并获得设备文件的文件描述符;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 结论该实时时钟

15、实现方法已应用于某高压气体压力与流量控制的嵌入式系统中, 实时时钟不仅能够在系统断电情况下长时间的保持设备日历并为嵌入式软件提供状态信息, 同时也为设备的安全稳定运转及故障诊断等提供参考依据。实时时钟设备的设计与实现, 详细的说明了这一方法的具体应用过程。将该方法运用于高压气体压力与流量控制系统其他字符设备驱动开发中, 起到良好的指导作用。创新点: 归纳总结了一种针对字符设备在 Linux 平台下驱动实现的一般方法; 基于 ARM- LINUX 在 ARM9 平台下进行了I2C 总线的实时时钟驱动设计与测试; 用于本文提出的方法, 指导某嵌入式工业控制系统的其它字符设备的驱动开发, 取得了良好的效果。参考文献1胡诚皓; 刘昆; 邵定宏; ERP 中成本计算的重组和实现程. 2Corbet J , Ruibini A. Linux 设备驱动程序.第二版.北京:中国电力出版社,20043Love R.Linux 内核设计与实现.第二版.北京:中国机械工业出版社,20064 李驹光,郑耿,江泽明. 嵌入式 Linux 系统开发详解- 基于EP93XX系列 ARM.北京:清华大学出版社,20065王太勇,王涛,杨杰等.基于嵌入式技术的数控系统开发设计.天津大学学报.20066陈志辉.I2C 总线在 MCS51 系列单片机数据采集中的实现.微计算机信息,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号