基于 Linux 的 Intel Xscale PXA27X 的 LED 驱动程序.doc

上传人:sccc 文档编号:5197695 上传时间:2023-06-13 格式:DOC 页数:9 大小:164.50KB
返回 下载 相关 举报
基于 Linux 的 Intel Xscale PXA27X 的 LED 驱动程序.doc_第1页
第1页 / 共9页
基于 Linux 的 Intel Xscale PXA27X 的 LED 驱动程序.doc_第2页
第2页 / 共9页
基于 Linux 的 Intel Xscale PXA27X 的 LED 驱动程序.doc_第3页
第3页 / 共9页
基于 Linux 的 Intel Xscale PXA27X 的 LED 驱动程序.doc_第4页
第4页 / 共9页
基于 Linux 的 Intel Xscale PXA27X 的 LED 驱动程序.doc_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《基于 Linux 的 Intel Xscale PXA27X 的 LED 驱动程序.doc》由会员分享,可在线阅读,更多相关《基于 Linux 的 Intel Xscale PXA27X 的 LED 驱动程序.doc(9页珍藏版)》请在三一办公上搜索。

1、精品论文基于 Linux 的 Intel Xscale PXA27X 的 LED 驱动程序实例开发王鑫 中国矿业大学信息与电气工程学院,徐州(221008) E-mail:wangxinshandong摘要:本文首先介绍了嵌入式Linux系统在PXA27X上的开发流程,进而介绍了设备驱动 的概念和功能。然后结合具体的YLE-PXA270开发板介绍了基于Linux下Intel Xscale PXA27X 的LED驱动及测试程序的设计,并介绍了以模块形式加载的过程,和编写、编译和调试的方法与步骤,并给出了部分驱动程序和测试程序的核心代码。为方便使用make工具编译的读者,还给出了Makefile文

2、件的完整详细的代码。给出了在YLE-PXA270开发板上的具体开发 与实验得出的有效而正确快速的调试与测试方法步骤。本设备驱动程序编写的思路严格按照 Linux下设备驱动程序的要求, 对其它基于Linux的设备驱动有很强的参考意义。关键词:Linux;LED;驱动;测试程序1. 前言目前, 嵌入式系统的开发已经离不开操作系统的支持, 而开发基于嵌入式操作系统的底 层硬件驱动程序是研发中必不可少的工作之一。Strong ARM 处理器将 Intel 处理器技术和 AMR 体系结构融为一体,致力于为手提式通信和消费电子类设备提供理想的解决方案。Intel XScale 微体系结构则提供全性能、高性

3、价比、低功耗的解决方案,支持 16 位 Thumb 指令和 集成数字信号处理(DSP)指令。XScale 架构微处理器是 Intel 公司针对目前新信息家电发展的 大量需求之下,发展的 Strong ARM 嵌入式处理器的第二代微处理器架构,Intel 公司在 2004 年 IDF 展览会上发布代号为 Bulverde 的 PXA27X 处理器,PXA27X 嵌入式处理器提供了业 界领先的多媒体性能,丰富的外设集成,它的设计面向于无线客户端,应用了第二代内存堆 栈技术,这使得它能够满足大多数在移动领域的应用需求。2. 嵌入式 Linux 系统在 PXA27X 上的开发嵌入式 Linux 系统在

4、 PXA27X 上的开发流程如下:1开发环境的建立2.Bootloader3.Linux 系统在 PXA27X平台上的移植4.嵌入式文件系统5.Linux 设备驱动程序开发6.嵌入式 GUI嵌入式操作系统位于低层硬件与用户之间,是两者沟通的桥梁,用户可以通过操作系统的用户界面来输入命令,操作系统则对命令进行解释,驱动硬件设备,实现用户的需求。设 备驱动可以理解为操作系统的一部分,设备驱动程序控制了操作系统和硬件设备之间的交 互。Linux 设备驱动程序在 Linux 的内核源代码中占有很大的比例,源代码长度的日益增加 主要是驱动程序的增加。对于一个特定的硬件设备来说,其对应的设备驱动程序是不同

5、的,- 5 -比如网卡,声卡,键盘,鼠标,摄像头,LED 跑马灯等。对于操作系统来说,挂接的设备越多,所需的设备驱动程序也越多。在嵌入式系统设计过程中,没有通用的驱动程序可使用, 驱动程序开发是整个嵌入式设计过程中必不可少的一部分。设备驱动主要完成以下功能:z对设备进行初始化;z使设备投入运行和退出服务;z从设备接收数据并将它们送回内核;z将数据从内核送到设备;z检测和处理设备出现的错误。图 1设备管理系统层次结构系统调用是操作系统内核与应用程序之间的接口,驱动程序则是操作系统内核与机器硬 件的接口。设备驱动程序能够直接访问硬件的代码,必须为应用程序提供系统调用,以便应 用程序能够访问设备,在

6、 Linux 中,主要有 3 种设备,即字符设备,块设备和网络设备,与 此相关的主要有 3 类设备驱动程序,即字符设备驱动程序,块设备驱动程序和网络设备驱动 程序。它们的系统调用是一致的,采用统一接口(在数据结构 file_operations 中)。应用程 序使用设备就像使用读/写普通的文字一样方便,使用相同的 open(),close(),read(),write()等, 真正做到了与设备无关1。通常,Linux 驱动程序接口分为如下 4 层:z应用程序进程与内核的接口;z内核与文件系统的接口;z文件系统与设备驱动程序的接口;z设备驱动程序与硬件设备的接口;在系统内部 I/O 设备的存取通

7、过一组固定的入口点来进行,这组入口点是由每个设备的 驱动程序提供的。具体的 Linux 系统里,设备驱动程序所提供的这组入口点有一个 file_operations 数据结构来向系统进行说明。3. LED 驱动程序设计Linux 的设备驱动程序可以分为 3 个主要组成部分:z自动配置和初始化子程序,负责检测所要驱动的硬件设备是否存在和是否能正常工 作。如果设备正常,则对这个设备及其相关设备的相关驱动程序需要的软件状态进 行初始化。这部分驱动程序仅在初始化时被调用一次。z服务于 I/O 请求的子程序,又称为驱动车虚的上半部分。调用这部分程序是由于系 统调用的结果,这部分程序在执行时系统仍认为是和

8、进行调用的进程属于同一个进 程,只是由用户态变成了核心态,具有进行此系统调用的用户程序的运行环境,因 此可以在其中调用 sleep()等与进程运行相关的函数。z中断服务子程序,又称为驱动程序的下半部分。在 Linux 系统中,并不是直接从中 断向量表中调用设备驱动程序的中断服务子程序,而是由 Linux 系统来接收硬件中断,再由系统调用中断服务子程序。中断可以产生在任何一个程序运行时,因此在 中断服务程序被调用时,不能依赖于任何进程的状态,也就不能调用任何与进程运 行环境运行有关的函数。因此设备驱动程序一般支持同一类型的若干设备,所以一 般在系统调用中断服务子程序时都带有一个或多个参数,以唯一

9、表示请求服务的设 备。在 Linux 系统里,对中断的处理是属于系统核心部分,因而如果设备与系统之 间以中断方式进行数据交换,就必须把该设备的驱动程序作为系统核心的一部分,设备驱动程序通过调用 request_irq 函数来申请中断,通过 free_irq 来释放中断。 从程序结构角度而言,驱动程序是子程序和数据的集合,是输入输出设备的软件接接口,它的任务就是向系统提供接口函数,从而实现对系统中各种设备进行访问的功能,所以简单 的说编写驱动程序就是实现这接口函数。针对不同的设备,驱动程序分三类:字符设备驱动、 块设备驱动、网络设备驱动,下面首先介绍 Linux 系统的三种设备。1字符设备 可以

10、像文件一样访问字符设备,字符设备驱动程序负责实现这些行为。这样的驱动程序通常会实现 open,close,read 和 write 系统调用。系统控制台和并口就是字符设备的例子, 它们可以很好地用流概念描述。通过文件系统节点可以访问字符设备,例如/dev/tty1 和/dev/lp1。2块设备块设备是文件系统的宿主,如磁盘。在大多数 Unix 系统中,只能将块设备看作对多个 块进行访问,一个块设备通常是 1K 字节数据。Linux 允许用户象字符设备那样读取块设 备允许一次传输任意数目的字节。结果是,块设备和字符设备只在内核内部的管理上有 所区别,因此也就是在内核/驱动程序间的软件接口上有所区

11、别。3网络设备 任何网络事务处理都是通过接口实现的,即,可以和其他宿主交换数据的设备。通常,接口是一个硬件设备,但也可以象 loopback(回路)接口一样是软件工具。网络接口是由内 核网络子系统驱动的,它负责发送和接收数据包,而且无需了解每次事务是如何映射到实际 被发送的数据包。尽管“telnet”和“ftp”连接都是面向流的,它们使用同样的设备进行传输; 但设备并没有看到任何流,仅看到数据报。由于不是面向流的设备,所以网络接口不能象/dev/tty1 那样简单地映射到文件系统的节点上。Unix 调用这些接口的方式是给它们分配一个 独立的名字(如 eth0)。这样的名字在文件系统中并没有对应

12、项。内核和网络设备驱动程序之间的通信与字符设备驱动程序和块设备驱动程序与内核间的通信是完全不一样的。内核不再调用 read,write,它调用与数据包传送相关的函数。图 2 设备驱动程序的工作过程如前所述,设备驱动程序是一组由内核中的相关子例程和数据组成的 I/0 设备软件接口。 每当内核意识到要对某个设备进行特殊的操作时,它就调用相应的驱动例程。这就使得控制 从用户进程转移到了驱动例程,当驱动例程完成后控制又被返回至用户进程。图 2 就显示了 以上的过程。系统调用是操作系统内核、应用程序之间的接口,设备驱动程序是操作系统内 核、机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,这样

13、在应用程序看 来,硬件设备只是一个设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作。 设备驱动程序是内核的一部分,它完成以下的功能;z对设备初始化和释放。z把数据从内核传送到硬件和从硬件读取数据。z读取应用程序传送给设备文件的数据和回送应用程序请求的数据。 z检测和处理设备出现的错误。 每个设备驱动程序都具有以下几个特性:z具有一整套的和硬件设备通讯的例程,并且提供给操作系统一套标准的软件接口。z具有一个可以被操作系统动态地调用和移除的自包含组件。 z可以控制和管理用户程序和物理设备之间的数据流。 由于存在这些特点,本课题中将它们的共同点提炼出来,形成一个驱动程序框架。这样就可 以简

14、化驱动程序的编程开发。3.1 主要数据结构1struct device struct 系统启动过程中要登记的块设备和字符设备管理表的定义在文件 fs/devices.c 中: struct device structconst char*name;struct file_operations*fops;static struct device_struct chrdevsMAX_CHRDEV;static struct device_struct blkdevsMAX BLKDEV;其实块设备表和字符设备表使用了相同的数据结构。在某些系统中,这些设备表也称作 设备开关表,不同的是它们直接定义了

15、一组函数指针进行对设备的管理。而这里系统用文件 操作(file_operations)代替了那组开关。文件操作是文件系统与设备驱动程序之间的接口,系 统特殊文件在建立的时候并没有把两者对应起来,只是把设备的缺省文件结构和 i 节点结构 赋给设备文件,而真正的对应定义在系统启动之后,当设备被打开时才进行的。操作 blkdev_open 和 chrdev_open 定义在文件 devices.c 中,它们的基本功能是当设备 文件初次打开时,根抓该文件的 i 节点信息找到设备真正的文件操作接口,然后更新原 来的设备表项;最后再调用该设备的 open 操作。/include/linux/major.h

16、 中定义了设备表的长 度。设备表中不同的表项表示不同种类的设备,也就是说,LINUX 系统分别支持各 128 种 不同的块设备和字符设备。2struct file_operations操作系统将每个外部设备当作文件来处理,内核通过 file_operations 结构来访问 driver 的功能。file_operations 的定义在文件中。每个字符设备都有一个 file_operatioins 结构。这个结构指向一组操作函数(open,read.)。每个函数的定义由 driver 提供。当然,有 些标准操作某些设备并不支持,这时,file_operatons 结构中对应表项为 NULL。(

17、随着 linux 内核的不断升级,file_op eratioins 结构也不断变大。最新的版本中,甚至函数原型也发生了 一些变化。当然,新版本总会向下兼容的。)结构的每一个成员的名字都对应着一个系统调用。用户进程利用系统调用在对设备文件 进行诸如 read/write 操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序, 然后读取这个数据结构相应的函数指针,接着把控制权交给该函数。这是 linux 的设备驱动 程序工作的基本原理。既然是这样,则编写设备驱动程序的主要工作就是编写子函数,并填 充 file_operations 的各个域。3.2 模块化模块化的概念 Linux 中的可

18、加载模块(Module),是 Linux 内核支持的动态可加载模块 (loadable module),它们是核心的一部分(通常是设备驱动程序),但是并没有编译到核心里面 去。Module 可以单独编译成为目标代码,module 是个目标文件。它可以根据需要在系统启 动后动态地加载到系统核心之中。当 module 不再被需要时,可以动态地卸载出系统核心。 Linux 中大多数设备驱动程序或文件系统都作成 module 的。超级用户可以通过 insmod 和 rmmod 命令显示地将 module 载入核心或从核心中将它卸载。核心也可在需要时,请求守 护进程(kerne1d)装载和卸载 modu

19、le。通过动态地将代码载入核心可以减小核心代码的规模, 使核心配置更为灵活。若在调试新核心代码时采用 module 技术,用户不必每次修改后都需 重新编译核心和启动系统。加载模块使用命令 insmod/路径/模块名,该动作实际调用次设备 驱动程序中的 init_module()函数;卸载模块使用命令 rmmod/路径/模块名,它调用驱动程序 中的 cleanup_module()函数。加载成功后,系统将分配给该驱动程序一个主设备号。通过这 个主设备号,我们就可以建立设备文件了。建立设备文件使用 mknod:mknod/dev/设备名c/-b 主设备号次设备号。其中-c 参数代表建立的是字符设备

20、,-b 代表建立的是块设备。主设备 号可以通过命令 cat/proc/devices 看到,次设备号由自己定,用来区别同一类型的不同设备, 如硬盘的 C 分区和 D 分区的主设备号相同,次设备号不同。建立了设备以后,我们就可以 通过用户程序来使用驱动程序了。删除设备文件用如下命令:rm/dev/设备文件名3。3.3 驱动程序设计3.3.1 初始化部分PXA27X 系列处理器通常情况下有 121 个复用功能输入/输出 GPIO 端口引脚,每一个 端口都可以由软件设置来满足各种系统配置和设计需求。图 3 LED 指示灯的接口电路系统在上电后,一般要在_init_module()函数中对各设备进行初

21、始化,然后载入各设备驱 动。对于开发板外围设备来说,初始化部分要做的工作有两方面,一是要对 CPU 的寄存器进 行设置,使 CPU 的 GPIO 接口能够正常工作,通过 GPIO 接口对芯片进行配置,使之能够正 常工作。PXA27X 的寄存器设置包括对状态寄存器,控制寄存器,端口配置寄存器,监视寄 存器,复用功能寄存器的设置。二是对中断服务程序的挂接。对 CPU 寄存器的设置可以按 照 PXA27X 数据手册上对 GPIO 接口的配置步骤进行配置。GPIO 接口配置成功后,按照 PXA27X 数据手册上提供的时序,通过 GPIO_Write(u_char *addr, int alen)函数对

22、 PXA27X 芯片的寄存器进行配置。首先应该对 PXA27X 芯片进行复位设置,然后把该芯片设置成在 配置工作模式下。然后对输出控制寄存器配置,最后配置芯片在正常工作模式下2。对中断服务程序的挂 接 , 主要在 include 目 录中的 request_irq (unsigned int irq,void(*handler)(int irq,void dev_id,struct pt_regs *regs)函数中完成,free_irq()函数来释放中 断。在这里,参数 irq 表示所要申请的硬件中断号:handler 为向系统等级的中断处理子程序, 中断产生是由系统来调用,调用时所带参数

23、irq 为中断号;dev_id 为申请时告诉系统的设备 标示;regs 为中断发生时的寄存器内容;device 为设备名,将会出现在/proc/interrupts 文件 里;flag 是申请时的选项,它决定中断处理程序的一些特性,其中最重要的是中断处理程序 是快速处理程序还是慢速处理程序。快速处理程序运行时,所有中断都被屏蔽;而慢速处理 程序运行时,除了正在处理的中断外,其他终端都没有被屏蔽。在 Linux 系统中,终端可以 被不同的中断处理程序共享。3.3.2GPIO 控制 在编写GPIO控制程序之前,必须明确控制的流程。上文提过,我们接收数据采用中断方式。采用leds_event(led

24、_halted)函数,禁止内核的LED时间改变LED灯的状态(屏蔽内核对LED的控制),采用leds_event(led_halted + 2)函数,取消屏蔽。int gpio_ctl_ioctl(struct inode*inode,struct file *file,unsigned int command,unsigned long arg )函数控制GPIO的输出来控制LED的状态,采用DM_WaitMs()延时函数来循环一次点亮各个LED灯,在需要点亮个灯的时- 9 -候,只要在应用程序中运行ioctl()函数就可以。3.3.3 上层接口函数在上层应用程序中,主要通过 tty 设备提

25、供的统一接口函数 read(),write(),ioctl()函数对底层的硬件设备进行操作。在上文中我们已经说明了,read()和 write()函 数主要通过回调函数把底层GPIO接口输入/输出数据传送到上层应用程序。虽然在初始化 时已经对这些进行了设置,但在应用程序中仍然可以根据应用需要,通过调用 I/ O 基本函数 ioctl ()进行灵活修改。同时 canIoctl ( ) 也提供了设备工作模式的设置和读取等很多功能,用 户可以根据应用的需要进行相应的重设置。3.4 编写、编译和调试在 linux 操作系统下有很多驱动程序的编写环境,最普通的是文本编辑器。驱动程序写 完后保存为*.c

26、就可以了。或者你也可以使用专门的 c 语言开发工具 Emacs,不过低版本的 Emacs 不太好用。或者你干脆在 Visual C 环境中编写驱动程序,写完后把文件后缀名改为.c 就可以了。编译的方法也有很多,gcc、Makefile、以及放入/usr/src/linux/driver/下与内核一 起编译4。按如上方法可以产生 main 程序,而且也不是很麻烦。但是如果我们考虑一下如果有 一天我们修改了其中的一个文件,那么我们难道还要重新输入上面的命令?也许你会说,这 个很容易解决啊,写一个 SHELL 脚本,让它帮我去完成不就可以了。对于这个程序来说, 确实是可以起到作用的,但是当我们把事情

27、想的更复杂一点如果我们的程序有几百个源程序 的时候,难道也要编译器重新一个一个的去编译?为此,聪明的程序员们想出了一个很好的 工具来做这件事情,这就是 make。在我们执行 make 之前,我们要先编写一个非常重要的 文件Makefile。对于上面的那个程序来说,可能的一个 Makefile 的文件是: 注:格式要标准(TAB 空格)PXA270X_KERNEL_DIR = /home/linux-2.6.9/目录ifneq ($(KERNELRELEASE), )obj-m := gpiodrv.o/目标文件elseKERNELDIR ?= $(PXA270X_KERNEL_DIR) PWD

28、 := $(shell pwd)default:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean:rm -f *.o *.ko/生成.ko文件endif有了这个 Makefile 文件,无论我们什么时候修改了源程序当中的什么文件,我们只要将Makefile 文件和驱动程序放在一个目录下,执行make命令,生成 .ko文件,我们的编译器 都只会去编译和我们的修改有关的文件,其它的文件则完全被忽略。make clean(确保所有有关文件都处于最新版本状态) make zImage(编译压缩形式的内核) 在需要内核支持较多的外设和功能时,内核可能变得很大,

29、此时可以编译内核:make bzlmag e加载模块,编译完内核后,要对选择的模块进行编译:#make module(编译选择的模块)#make module-install(将编译后的模块转移到系统标准位置)编写的程序不太可能一次性就会成功,在程序当中,常会出现许许多多意料不到的错误, 这个时候就要对程序进行调试。最常用的调试软件是 gdb。如果在图形界面下调试程序,那 么可以选择 xxgdb,此时要在编译的时候加入g 选项。关于 gdb 的使用可以看 gdb 的帮助文 件。4. 应用,测试及结论4.1 应用程序应用程序的书写主要是用来证明驱动程序的正确性,并在上层应用程序中,验证 ioct

30、l()函数的正确性。 首先我们通过 tty 设备提供的基本 I/O 函数 open()打开我们创建 的设备,程序如下:Fd= open(DEVICE_GPIOTEST,O_RDONLY); 打开设备后,系统会返回 一个设备描述符 Fd,下面的程序中便可以通过设备描述符 Fd 对设备进行相应的操作。4.2 测试目标机运行应用程序,可以使用 ioctl(fd,1,6),点亮个灯,循环 6 次,delay()来延时。启 动开发板,cd /tmp;rz 命令分别将 gpiodrv.ko 和 gpio_test 下载到板子里 insmod gpiodrv.ko(以模块的形式加载),chmod R 777

31、 gpio_test 来设置权限,mknod /dev/GPIO c 220 0 来 创建设备节点,注意设备名的大小写,./gpio_test 运行 LED 的测试程序就可以了。4.3 结论通过上述方法的测试,LED 可以通过延时,控制实现不同顺序,不同时间间隔的点亮, 证明驱动程序良好。驱动能够满足要求,可以用到实际开发板应用中。本文介绍了基于 Linux 的 Intel Xscale PXA27X 的 LED 驱动程序实例开发,以 PXA270 芯片为具体操作为依据,列出了部分驱动及应用程序的核心代码。本文严格按照 Linux 硬件 驱动程序的开发要求,可以作为 Linux 下类似设备驱动

32、的参考。参考文献1 杨刚等.32 位 RISC 嵌入式处理器及其应用M.电子工业出版社.2007.7 :323-337. 2 杨刚等.32 位 RISC 嵌入式处理器及其应用M.电子工业出版社.2007.7 :136-146.3 王岩.基于 Intel XScale 处理器的嵌入式 Linux 的关键技术与应用D.东南大学, 2005.3. 4 刘柯军. 嵌入式 LINUX 及其设备驱动实现技术的研究D.北京邮电大学, 2006.6.The Example of the Development of Intel Xscale PXA27X LED Driver Based on LinuxWa

33、ng XinCUMT, School of Information and Electric Engineering, Xuzhou (221008)AbstractThis paper firstly introduced the development process of the embedded Linux system on PXA27X ,andthen introduced the concept and functions of the device drivers. Then the light of the specificYLE-PXA270 Development Bo

34、ard introduced the design and testing procedures of the LED drive based on Linux on Intel Xscale PXA27X, and introduce a module of the course load, and the preparation, building and debugging of the methods and procedures. and give the part of drivers and test procedures for the core code. To facili

35、tate the reader to use of compiler tools Make, also presented a paper Makefile for full details of the code. Show out the development of the specificdevelopment board YLE-PXA270 with the experiment come to the rapid, effective and correct methods of debugging and testing steps. This device drivers prepared in strict accordance with the idea of Linux device drivers ,and have a strong reference value for other Linux-based device drivers.Key words: Linux; LED; driver; test procedures作者简介:王鑫,男,1984 年 3 月出生,籍贯山东烟台,2007 年毕业于中国矿业大学,现 为中国矿业大学信息与电气工程学院硕士研究生,研究方向为嵌入式系统开发及应用和 UWB 超宽带无线技术。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号