




已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
四川师范大学成都学院电子工程系课程设计报告前言嵌入式系统具有巨大的市场需求前景,可广泛应用于移动计算设备、网络设备,信息电器,工控设备、车载设备、娱乐设施、仪器仪表等场合;开发和应用嵌入式操作系统的难度远大于普通的计算机应用系统。Linux系统本身就是一个优秀的操作系统,再加上他的源代码是开放的,而开放的源代码做的相当漂亮,所以我们就把他作为嵌入式开发的核心原型系统。嵌入式Linux设备驱动是嵌入式系统中十分重要的组成部分。嵌入式Linux的各种设备驱动,包括字符设备驱动、数字显示驱动、键盘驱动、A/D驱动、D/A驱动、LCD驱动、触摸屏驱动、CAN总线驱动、IIC总线驱动、音频总线驱动、IDE接口驱动、闪存芯片驱动、USB驱动、串口驱动、网络设备驱动等,对于一个特定的硬件设备来说,其对应的设备驱动程序是不同的。对于操作系统来说,挂接的设备越多,所需要的设备驱动程序也越多。对于嵌入式系统设计过程中,没有通用的驱动程序可使用。不管是Windows还是Linux,驱动程序都扮演着重要的角色。应用程序只能通过驱动程序才能同硬件设备或系统内核通讯。Linux内核对不同的系统定义了标准的接口(API),应用程序就是通过这些标准的接口来操作内核和硬件。驱动可以被编译的内核中(build-in),也可以做为内核模块(Module)存在于内核的外面,需要的时候动态插入到内核中运行。 1.总体设计方案1.1 Linux系统结构图1 Linux系统结构图1.2 驱动程序原理应用测试程序设备文件驱动模块硬件/etc/modules.conf文件KernelOpen,read,wirte命令操作通过租设备号Mknod通过主设备号关联联通过文件的read write操作返回主设备号Insmod 问系统文件若需要根据别名加载图1 驱动程序原理图2.设计开发环境2.1硬件平台2.1.1 led硬件电路 Led灯硬件电路图2.1.2 S3C2410相关的IO口寄存器名称及地址RegisterAddressR/WDescriptionReset Value GPFCON0x56000050R/WConfigure the pins of pot F0x0GPFDAT0x56000054R/WThe data register for port FUnderfinedGPFUP0x56000058R/WPull-up disable register for port F0x0Reserved0x5600005c-ReservedUnderfined表1 S3C2410相关IO口寄存器名称及地址GPFCON端口配置寄存器GPFCONBitDescriptionGPF715:1400=Input;01=Ouput;10=EINT7;11=ReservedGPF613:1200=Input;01=Ouput;10=EINT6;11=ReservedGPF511:1000=Input;01=Ouput;10=EINT5;11=ReservedGPF49:800=Input;01=Ouput;10=EINT4;11=ReservedGPF37:600=Input;01=Ouput;10=EINT3;11=ReservedGPF25:400=Input;01=Ouput;10=EINT2;11=ReservedGPF13:200=Input;01=Ouput;10=EINT1;11=ReservedGPF01:000=Input;01=Ouput;10=EINT0;11=Reserved表2 GPFCON端口配置寄存器GPFDATA端口数据寄存器GFPDAT BitDescriptionGPF7:07:0When the port congigured as input port,data form extermal sourece can be read to the corresponding pin.When the port is congigured as output pot data written in this register can be sent to the corresponding pin. When the port congigured as function pin .undefined value will be read.表3 S3C2410的GPFDATA端口数据寄存器GPFUP端口上拉电阻使能寄存器GPFUPBit DescriptionGPF7:07:00:The pull-up function attached to the corresponding portp in is enable.1:The pull-up function is disabled.表4 S3C2410的端口上拉电阻使能寄存器2.2软件平台2.2.2软件平台介绍选择了开放源码以及强大的社群支持的Linux操作系统,根据需要对该系统进行了相应的剪裁,编译,以更好地适用于嵌入式系统中。在嵌入式系统软件开发中,普遍采用的交叉编译的方法进行编译调试,即将软件先利用交叉编译、汇编和连接工具在宿主机上生成可执行的二进制代码(该代码不能在宿主机上运行,只能在目标板上运行),再下载到目标板上运行。2.2.2软件开发平台的构建2.2.2.1 linux系统学习 在PC机上安装虚拟机,并在虚拟机上安装linux系统。系统安装成功后,熟悉相关的文件系统及相关的系统命令。如挂载命令mount、显示文件目录命令ls、改变当前工作命令cd等;了解linux系统和windows系统间的文件共享方法;掌握linux系统中的vi编辑器的使用并可以用GDB调试我们编译的程序;最后还要掌握Makefile的相关知识。2.2.2.2 Linux系统中搭建交叉开发环境 为了解决目标板上资源不足的问题,我们往往采用宿主机上开发,然后移植到 目标板上的方式来开发嵌入式系统。但是由于操作系统、目标板的多样性,于是必须搭建合适的各自平台的交叉编译环境。我们是用我们实验板厂商提供的cross-2.95.3交叉编译工具。Linux下的串口通信软件是Minicom。Minicom相当于Windows下的超级终端。我们使用之前需要对他进行参数配置。除了Minicom,NFS服务的建立是不可缺少的。网络文件系统(NFS)是网络上多台机器之间共享主目录,当用户登录至 LAN 上的一台机器(*任何一台*机器)时,这为他或她提供了一致的环境。由于 NFS,挂装远程文件系统树结构并将其完全集成到系统的本地文件系统成为可能。NFS 的透明性和成熟使它成为在 Linux 下进行网络文件共享的有用和流行的选择。3.设备驱动程序的概念设备驱动程序的任务就是控制设备的硬件完成指定的I/O 操作。所以在设备管理中驱动 程序是直接和设备硬件打交道的。驱动程序包含了对设备进行各种操作的代码,在操作系统 的控制下,CPU 通过执行驱动程序来实现对设备底层硬件的处理和操作。Linux 的设备驱动程序的主要功能是:对设备进行初始化;启动或停止设备的运行;把设备上的数据传送到内存;把数据从内存传送到设备;检测设备状态1。 Linux内核把驱动程序划分为三类:字符设备、块设备、网络设备驱动,对于不同的设备有不同的访问方式。本文以按键驱动为例,介绍基本的字符设备驱动程序的编写过程。 驱动程序有两种加载方式:一是直接编译进内核,启动内核时可自动加载;二是以模块的方式加载,在系统启动之后可以insmod 加载。我们在这里采用第二种方式。4.LED驱动程序的主要函数4.1 Linux 设备驱动程序接口 系统调用是操作系统内核与应用程序之间的接口,驱动程序则是操作系统内核与机器硬件的接口。设备驱动程序能够直接访问硬件的代码,必须为应用程序提供系统调用。以便应用程序能访问设备。在 Linux中,主要有三种设备即:字符设备块设备和网络设备,与此相关主要有三类设备驱动程序,字符设备驱动程序,块设备驱动程序和网络设备驱动程序他们的系统调用是一致的,采用统一的接口(在数据结构file _operations 中)。应用程序使用设备就像使用读写普通的文件一样方便,使用相同的 open ( ) , close( ), read ( ) , write ( )等,真正做到了与设备无关。通常 Linux 驱动程序接口分为如下四层:(1)应用程序进程与内核的接口;(2)内核与文件系统的接口;(3)文件系统与设备驱动程序的接口;(4)设备驱动程序与硬件设备的接口;每个驱动程序都有个 file_operations 的数据结构,包含了一系列的函数指针,可以指向自己所开发的接口如 open ( )等。内核中有两个表,一个用于字符设备驱动程序,一个用于块设备驱动程序。这个两个表用于保存指向 file_operations 数据结构的指针,驱动程序内部函数的地址保存在这一结构。字符设备字符设备(char device )和普通文件系统的区别:普通文件系统可以来回读写,而大多字符设备仅仅是数据通道,只能顺序读写。字符设备上 Linux 最简单的设备,可以像文件一样访问。应用程序使用标准系统调用打开,读取,写和关闭,完全好像这个设备是一个普通文件一样。初始化字符设备时,它的设备驱动程序向 Linux 登记,并在字符设备向量表中增加一个 device_struct 数据结构条目,这个设备的主设备标识符(例如,对于 tty 设备的主设备标识符是 4 )用做这个向量表的索引。一个设备的主设备标识符是固定的。Chrdevs 向量表维护已经登记的字符设备文件。块设备块设备(block device )是文件系统的物质基础,它也支持像文件一样访问。这种为打开的块特殊文件提供正确的文件系统操作组的机制和字符设备的十分相似。Linux 用 blkdevs 向量表维护已经登记的块设备文件。它象 chrdevs 向量表一样,使用设备的主设备号作为索引。与字符设备不同,块设备进行分类,SCSI 是其中一类,而 IDE 是另一类。网络设备驱动对于每一个网络接口,都用一个 device 的数据结构表示。通常,网络设备是一个物理设备,如以太网卡,但软件也可以作为网络设备,典型的是回送设备(loopback ) 在内核启动时,系统通过网络设备驱动程序登记已经存在的网络设备。设备用标准的支持网络的机制来把收到的数据转送到相应的网络层。关于网络设备驱动更详细的信息请查看相关资料。4.2设备驱动程序的设备号和入口点Linux 系统通过设备号来区分不同设备。设备号由两部分组成:主设备号和次设备号。主设备号指明对应哪些设备驱动,这种对应关系是固定不变并作为内核资源的一部分存在。需要注意的是,同一个主设备号可以对应两个不同的设备驱动,一个可以是字符设备另一个可以是块设备。次设备号区分被一个设备驱动控制下的某个独立的设备。比如,同一个类型的 USB 设备可以在系统中有几个,它们通过次设备好加以区分,而设备驱动可以只对应一个。在proc/ devices 中列出了系统中处于活动状态设备的主设备号,所谓的活动状态是指与该设备对应的设备驱动已经被系统内核装载。设备入口点也可以理解为“设备文件句柄”,一个设备的入口点和磁盘上的普通文件系统一样,可以删除(rm ) ,移动(mv )和复制(cp )等。我们可以在文件系统中使用 mknod 命令创建一个设备入口点或者通过系统调用 mknof 来创建。在文件系统中创建了设备入口点并没有代表响应的设备驱动和硬件已经准备好,只是代表了和设备驱动通信的一部分。下面给一个创建字符设备入口点的实例:#mknod /dev/testChar c 100 0 其中 c 代表字符设备,如果想创建块设备则用 b 代替 c 。参数 100 代表该设备的主设备号,0 代表该设备的次设备号。对于现有 Linux 操作系统,/dev 目录是必不可少的,这个目录包含了所有 Linux 系统所知道的字符设备,块设备和网络设备。操作字符设备的方法非常简单。打开一个字符设备就像打开一个文本文件一样,只不过读写“文件”的操作实际上是操作设备的过程,可以使用正常的文件操作命令 cat 或者外壳复位向语法实现和设备的数据交换。4.3 Linux 驱动程序的加载在 Linux 下加载驱动程序可以采用动态和静态两种方式。静态加载就是把驱动程序直接编译到内核里,系统启动后可以直接调用。静态加载的缺点是调试起来比较麻烦,每次修改一个地方都要重新编译下载内核,效率较低。动态加载利用了 Linux 的 module 特性,可以在系统启动后用 insmod 命令把驱动程序(.o 文件)添加上去,在不需要的时候用 rmmod 命令来卸载。在台式机上一般采用动态加载的方式。在嵌入式产品里可以先用动态加载的方式来调试,调试完毕后再编译到内核里。设备驱动程序在加载时首先需要调用入口函数 init_module ( ) ,该函数完成设备驱动的初始化工作,比如寄存器置位,结构体附值等一系列工作。其中最重要的一个工作就是向内核注册该设备,对于字符设备调用 register_chrdev ( )完成注册,对于块设备需要调用 register_blkdev ( )完成注册。注册成功后,该设备获得了系统分配的主设备号,自定义的次设备号,并建立起与文件系统的关联。设备在卸载的时候,需要回收响应的资源,;令设备的响应寄存器值复位并从系统中注销该设备。系统调用部分则是对设备的操作过程,比如 open , read ,write , ioctl 等操作。5Linux 下字符设备驱动的添加一个字符设备驱动里面实现对 GPIO 端口的操作。功能说明: 模块加载的时候跑马灯运行起来。我们使用GX-ARM-S3C42410 实验箱的 4 个 LED 指示灯由 4 个 IO 口控制,它们分别是:GPF4GPF7 。当 GPF4 GPF7 输出低电平的时候,相应的 LED 指示灯亮。5.1字符设备的驱动源程序字符设备的驱动源程序 gpiodrv.c 。使用vi编辑器编写符合上面功能的驱动源程序 gpiodrv.c 。源程序的代码如下:#include #include #include #include #include #include #include #include #include #define SIMPLE_GPIO_LED_MAJOR97devfs_handle_t dev_handle;#define VERSION 2410RP-gpio_led-V1.00-09-12-23void showversion(void) printk(*n); printk(t %s tn, VERSION); printk(*nn);/ - READ -ssize_t SIMPLE_GPIO_LED_read (struct file * file ,char * buf, size_t count, loff_t * f_ops)return count;/ - WRITE -ssize_t SIMPLE_GPIO_LED_write (struct file * file ,const char * buf, size_t count, loff_t * f_ops)return count;/ - IOCTL -ssize_t SIMPLE_GPIO_LED_ioctl (struct inode * inode ,struct file * file, unsigned int cmd, long data)GPFCON=(GPFCON|0xFF00)&0xFFFF55FF;GPFUP&=0x0f;switch(cmd)case 1: GPFDAT=(GPFDAT&0x0f)|0xe0;break;case 2: GPFDAT=(GPFDAT&0x0f)|0xd0;break;case 3: GPFDAT=(GPFDAT&0x0f)|0xb0;break;case 4: GPFDAT=(GPFDAT&0x0f)|0x70;break;case 5: GPFDAT=(GPFDAT&0x0f)|0xf0;break;return 0;/ - OPEN -ssize_t SIMPLE_GPIO_LED_open (struct inode * inode ,struct file * file)MOD_INC_USE_COUNT;return 0;/ - RELEASE/CLOSE -ssize_t SIMPLE_GPIO_LED_release (struct inode * inode ,struct file * file)MOD_DEC_USE_COUNT;return 0;/ -struct file_operations GPIO_LED_ctl_ops =open:SIMPLE_GPIO_LED_open,read:SIMPLE_GPIO_LED_read,write:SIMPLE_GPIO_LED_write,ioctl:SIMPLE_GPIO_LED_ioctl,release:SIMPLE_GPIO_LED_release,;/ - INIT -static int _init HW_GPIO_LED_ctl_init(void) int ret = -ENODEV;int i,j;ret = devfs_register_chrdev(SIMPLE_GPIO_LED_MAJOR, GPIO_led, &GPIO_LED_ctl_ops);showversion();if( ret 0 )printk ( S3C2410 init_module failed with %dn -kernel-, ret);return ret;elseprintk( S3C2410 gpio_led_driver register success! -kernel-n);dev_handle = devfs_register(NULL,GPIO_led,DEVFS_FL_DEFAULT,SIMPLE_GPIO_LED_MAJOR,0,S_IFCHR, &GPIO_LED_ctl_ops,NULL);return ret;static int _init GPIO_LED_ctl_init(void) int ret = -ENODEV; ret = HW_GPIO_LED_ctl_init(); if (ret) return ret; return 0;static void _exit cleanup_GPIO_LED_ctl(void)#ifdef OURS_GPIO_LED_DEBUG printk (cleanup_GPIO_LED_ctl -kernel-n); #endifdevfs_unregister_chrdev (SIMPLE_GPIO_LED_MAJOR, GPIO_led );module_init(GPIO_LED_ctl_init);module_exit(cleanup_GPIO_LED_ctl);5.2驱动源程序中相关函数函数说明GX-ARM-S3C42410 实验箱的4个 LED 指示灯S3C2410 的 GPF4GPF7 控制,与这四个端口相关的寄存器有:配置寄存器(GPFCON ) ,数据寄存器(GPFDAT )和上拉寄存器(GPFUP ),下面的代码将 GPF4 GPF7 的属性设置为输出:GPFCON = 0x5500 。GPFCON=(GPFCON|0xFF00)&0xFFFF55FF;file_operations 数据结构,inode 数据结构和 file 数据结构内核通过 file_operations 结构识别设备,通过 file_operations 数据结构提供文件系统的入口点函数,也就是访问设备驱动的函数。file_operations 定义在linux/fs.h 中的函数指针表。这个结构中的每一个成员的名字都对应着一个系统调用。在用户进程利用系统调用对设备文件进行诸如 read/write 操作时,系统调用通过设备文件的主设备好找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数,这是 Linux 的设备驱动程序工作的基本原理。从某种意义上说,写驱动程序的任务之一就是完成 file _operations 中的函数指针。文件系统处理的文件所需要的信息在 inode (索引结点)数据结构中。inode 数据结构提供了关于特别设备文件/dev/DriverName (这里的 DriverName 可能是任何一个设备文件,如 hda0)的信息。file 数据结构主要用于与文件系统对应的设备驱动程序使用。当然,其它设备驱动程序也可以使用,它提供有关被打开的文件的信息。register_chrdev 函数 设备驱动程序所提供的入口点,在设备驱动程序初始化的时候向系统进行登记,以便系统适当的时候调用。在 Linux 系统中,通过调用 register_chrdev 向系统注册字符型设备驱动程序。register_chrdev在 fs/devices.c 文件中的定义如下。int register_chrdev ( unsigned int major , const char *name , struct file_operations *fops )参数中的 major 是为设备驱动程序向系统申请的主设备好,如果 major 为 0 ,则系统为该设备驱动程序动态分配一个主设备号,不过系统分配的这个主设备好是临时的。在这里我们的 major 为 220(IOPORT_MAJOR ) ,这样该字符设备驱动程序的主设备号为 220 , name 是设备名,这里设备名为 gpio 。fops 就是前面所说的对各个调用的入口的说明,在这里,fops 为 gpio_ctl_fops 。registe _chrdev 函数返回。表示成功,返回-INVAL 表示申请的主设备号非法,一般来说是主设备号大于系统所允许的最大设备号。返回-EBUSY 表示所申请的主设备号正被其它设备驱动程序使用。如果动态分配主设备号成功,则此函数将返回所分配的主设备号。如果 register_chardev 操作成功,则设备名就会出现在 proc/devices(教学平台的嵌入式 Linux 平台下)文件中,可以通过 cat /proc/devices 来查看工作设备的信息。5.3驱动程序的 Makefile文件驱动程序的makefile与前面讲到的makefile有所区别,驱动程序在加载以后,就是内核的一个部分,在编译的过程中,必须包含内核中的一些文件,因此在写驱动程序的时候,必须指定内核源代码的路径。该驱动程序的makefile代码如下:INCLUDEDIR= /s3c2410_linux/kernel /includeCROSS_COMPILE=/opt/host/armv4l/bin/armv4l-unknown-linux-CC =$(CROSS_COMPILE)gccCFLAGS+= -I.CFLAGS+= -Wall -O -D_KERNEL_ -DMODULE -I$(INCLUDEDIR)TARGET = gpio_led.oall: $(TARGET)gpio_led:gpio_led.c$(CC) -c $(CFLAGS) $ -o $clean:rm -f *.o * core .depend注意:INCLUDEDIR :=/s3c2410_linux/kernel /include 路径改为宿主机上内核所在的路径。将 gpiodrv.c 和这个 Makefile 放置在同一个新建目录下,进入这个目录,输入 make 后,编译成功后将在这个目录下生成一个 gpioled.o 的文件,这个文件就是可以加载到linux系统中的驱动程序文件。5.4驱动测试程序驱动测试程序其实就是一个简单的针对于相应驱动的应用程序,它的作用在于测试所编写的驱动程序是否能够正常工作。在该测试程序中,使用驱动程序来实现一个跑马灯,是实验箱上的四颗LED循环点亮。该驱动相应的测试程序 gpio_test.c的源码如下:#include #include #include #include #include void mdelay(int t)int i;for(;t0;t-)for(i=1000;i0;i-);int main()int fd;fd=open(/dev/GPIO_led,O_RDWR);if(fd0)printf(error open GPIO_ledn);elseprintf(open GPIO_led success!n);while(1)ioctl(fd,1);mdelay(1000);ioctl(fd,2);mdelay(1000);ioctl(fd,3);mdelay(1000);ioctl(fd,4);mdelay(1000);ioctl(fd,5);mdelay(1000);5.5 测试程序的Makefile该gpio_test.c程序的Makefile文件,源代码如下: CROSS_COMPILER=/tmp/xxx/3.3.2/bin/arm-linux-INCL=-I/tmp/xxx/gec2410-linux- 2.6.8.1/gpio_test:$( CROSS_COMPILER)gcc $(INCL) gpio_test.c o gpio_test Clean:-rm f gpio_test *CROSS_COMPILER=/tmp/xxx/3.3.2/bin/arm-linux-INCL=-I/tmp/xxx/gec2410-linux- 2.6.8.1/改为宿主机上的路径。4.设计总结经过2个星期的课程设计,留给我印象最深的是要设计一个成功的电路,必须要有本产品能最大支持10人(组)限时抢答并同时能记分,个人感觉其功能还算比较完善。此次的设计并不奢望一定能成功,但一定要对已学的各种电子知识能有一定的运用能力,我做设计的目的是希望能检查下对所学知识的运用能力的好坏,并且开始慢慢走上创造的道路,这是非常可贵的一点。5.参考文献(1)专著、论文、学位论文、报告1 李善平Linux与嵌入式系统M.北京:清华大学出版社,2007.11.116-1392 孙延奎小波分析及其应用北京:机械工业出版社,2005.1
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安全生产基本知识测试题及答案解析
- 无锡市安全员考试题库及答案解析
- 地质勘查安全竞赛题库及答案解析
- 2025年煤矿安全生产管理人员安全资格考试多选题库及答案
- 空调机房安全培训试题及答案解析
- 深圳电动车安全测试题目及答案解析
- 2025年上半年软考网络工程师试题与答案
- 《产品碳储量与碳足迹核算规范 红木家具》
- 2025年公共政策与健康联盟的建立探究试题及答案
- 2025年查对制度考试复习题库及答案解析
- 云南师大附中2024年数学高一下期末联考试题含解析
- 供应链管理综合实验实验报告
- (正式版)JBT 5300-2024 工业用阀门材料 选用指南
- 2024量子人工智能技术白皮书-量子信息网络产业联盟-2024.1
- 公务员考试培训-判断推理通关秘籍
- 第13课《警惕可怕的狂犬病》 课件
- 《C++语言基础》全套课件(完整版)
- 《社会工作伦理案例分析》课件 儿童和青少年社会工作伦理
- HSK标准教程5下-课件-L2
- 毕业设计论文-计算机类
- 工作单位接收函
评论
0/150
提交评论