您好,欢迎访问三七文档
当前位置:首页 > 办公文档 > 其它办公文档 > ARM9嵌入式第七章习题
第7章嵌入式Linux设备驱动程序开发模拟试题一.简答题1、嵌入式Linux的设备文件的属性是由哪三部分信息组成?答:第一部分是文件的类型,第二部分是一个主设备号,第三部分是一个次设备号。其中类型和主设备号结合在一起惟一地确定了设备文件驱动程序及其界面,而次设备号则说明目标设备是同类设备中的第几个。2、嵌入式Linux的设备管理子系统的结构通常由哪几部分组成?答:嵌入式Linux的设备管理子系统的结构通常包括用户进程、文件系统层、设备驱动层和硬件层。3、简述用户进程答:用户进程:用户进程一般位于内核之外,当它需要操作设备时,可以就像访问普通文件一样,通过调用read(),write()等文件操作系统调用来完成对设备文件的访问和控制。4、简述嵌入式Linux的设备管理子系统结构中的文件系统层的作用答:文件系统层:它位于用户进程层下面,属于内核空间,基本功能是执行适合于所有设备的输入输出功能,使用户透明的访问文件。通过本层的封装,设备文件在上一层看来就和普通文件没有区别,也拥有读、写和执行权限,拥有和它对应的索引节点等。在用户进程发出系统调用要求输入输出操作时,文件系统层就处理请求的权限,通过设备驱动层的接口将任务传到驱动程序。5、简述嵌入式Linux的设备管理子系统结构中的文件系统层的作用答:设备驱动层:设备驱动程序位于内核中,它根据文件系统层的输入输出请求来操作硬件上的设备控制器,完成设备的初始化、打开释放、以及数据在内核和设备间的传递等操作。6、Linux中的设备可以分为哪三类?答:Linux中的设备可以分为三类:字符设备,块设备和网络设备。7、解释Linux中的字符设备,并举出几种常见的字符设备。答:Linux中的字符设备没有缓冲区,数据的处理是以字节为单位按顺序进行的,它不支持随机读写。普通打印机、系统的串口以及终端显示器是比较常见的字符设备,嵌入式系统中简单的按键、触摸屏、手写板也都属于字符设备。8、解释Linux中的块设备,并举出几种常见的块设备。答:Linux中的块设备是指那些在输入/输出时数据处理以块为单位的设备,它一般都采用了缓存技术,支持数据的随机读写。典型的块设备有硬盘、cd-rom等。对用户来说块设备和字符设备的访问接口都是一样的,都是一组基于文件的系统调用,如read,write等,它们实现上细节的区别仅在内核和驱动程序的软件接口上。9、解释Linux中的网络设备,并举出几种常见的网络设备。答:Linux中网络设备的实现方法不同于字符型设备和块型设备,它面向的上一层不是文件系统层而是网络协议层,设备节点只有在系统正确初始化网络控制器之后才能建立。内核和网络设备驱动程序间的通信,与字符设备驱动程序、块设备驱动程序与内核间的通信也是完全不一样的。网卡是属于网络设备。10、怎样查看目标机上的设备的主次设备号?答:进入目标机后,查看/dev目录下的设备的主次设备号可以使用如下命令:[/mnt/yaffs]ls/dev-l一个运行的linux系统,当前使用的设备可以通过文件/proc/devices查看。11、向系统添加一个驱动程序相当于添加一个主设备号,写出字符型设备主设备号的添加和注销函数,并说明这两个函数原型在linux的何文件中说明。答:字符型设备主设备号的添加和注销分别通过调用函数register_chrdev()和unregister_chrdev()实现,这两个函数原型在linux/fs.h文件说明。externintregister_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops);externintunregister_chrdev(unsignedintmajor,constchar*name);这两个函数运行成功是返回0,运行失败返回一个负的错误码。参数major对应所请求的主设备号,name对应设备的名字,fops对应于该设备的一个结构。12、简述数据结构file_operations的作用。答:linux的内核内部通过file结构识别设备,通过file_operations数据结构提供文件系统的入口点函数,也就是访问设备驱动的函数。这个数据结构的每一个成员的名字都对应着一个系统调用。在用户进程利用系统调用对设备文件进行诸如read/write操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数,这就是Limux的设备驱动程序的工作原理。在file_operations数据结构中,指出了设备驱动程序所提供的入口点位置。13、解释下面函数的作用1)intcheck_region(unsignedintfrom,unsignedintextent);2)voidrequest_region(unsignedintfrom,unsignedintextent,constchar*name);3)voidrelease_region(unsignedintfrom,unsignedintextent);答:1)intcheck_region(unsignedintfrom,unsignedintextent);这个函数察看系统的I/O表,看是否有别的驱动程序占用某一段I/O口。2)voidrequest_region(unsignedintfrom,unsignedintextent,constchar*name);如果这段I/O端口没有被占用,在驱动程序中就可以使用它。在使用之前,必须向系统登记,以防止被其他程序占用。登记后,在/proc/ioports文件中可以看到你登记的I/O口。在对I/O口登记后,就可以放心地用inb(),outb()之类的函数来访问了。3)voidrelease_region(unsignedintfrom,unsignedintextent);此函数用来释放登记的I/O口。上面三个函数的参数为:from表示所申请的I/O端口的起始地址;extent为所要申请的从from开始的端口数;name为设备名,将会出现在/proc/ioports文件里;check_region返回0表示I/O端口空闲,否则为正在被使用。14、内核模块与应用程序之间存在着什么区别?答:内核模块与应用程序之间存在着区别。应用程序是从头到尾完成一个任务,而模块则是为以后处理某些请求而注册自己,完成这个任务后,它的“主”函数就立即中止了。然而,内核源码仅能连接编译到内核模块中,不像应用那样有众多的支持库,内核能调用的是由内核开放出来的那些函数。由于没有库连接到模块中,所以源码文件不应该模块化任何常规头文件。15、解释内核空间和用户空间的区别。模块运行的空间称为“内核空间”,而应用程序运行的则是在“用户空间”中。它们分别引用不同的内存映射,也就是程序代码使用不同的“地址空间”。Linux通过系统调用和硬件中断完成从用户空间到内核空间的控制转移。执行系统调用的内核代码在进程的上下文中执行,它执行调用进程的操作并且可以访问进程地址空间的数据。16、Linux的设备的驱动程序在加载的时候首先需要调用入口函数init_module(),该函数最重要的一个工作就是向内核注册该设备,对于字符设备调用哪个函数完成注册?答:调用register_chrdev()完成注册。register_chrdev()的原型定义如下:intregister_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops);其中:major是为设备驱动程序向系统申请的主设备号,如果为0,则系统为此驱动程序动态分配一个主设备号。name是设备名,fops是对各个调用的入口点说明。此函数返回0时表示成功;返回-EINVAL,表示申请的主设备号非法,主要原因是主设备号大于系统所允许的最大设备号;返回-EBUSY,表示所申请的主设备号正在被其他设备程序使用。如果动态分配主设备号成功,此函数将返回所分配的主设备号。若register_chrdev()操作成功,设备名就会出现在/proc/dvices文件中。17、怎样判别Linux的设备是否注册成功?答:Linux在/dev目录中为每个设备建立一个文件,用ls–l命令列出函数返回值,若小于0,则表示注册失败;返回0或者大于0的值表示注册成功。注册以后,Linux将设备名与主、次设备号联系起来。当有对此设备名的访问时,Linux通过请求访问的设备名得到主、次设备号,然后把此访问分发到对应的设备驱动,设备驱动再根据次设备号调用不同的函数。18、怎样完成Linux的字符设备的注销?答:当设备驱动模块从Linux内核中卸载,对应的主设备号必须被释放。字符设备在cleanup_module()函数中调用unregister_chrdev()来完成设备的注销。unregister_chrdev()的定义为:intunregister_chrdev(unsignedintmajor,constchar*name);此函数的参数为主设备号major和设备名name。Linux内核把name和major在内核注册的名称对比,如果不相等,卸载失败,并返回-EINVAL;如果major大于最大的设备号,也返回-EINVAL。19、若驱动程序是内核的一部分,初始化函数如何声明?当驱动程序是以模块的形式编写时,应如何声明?答:若驱动程序是内核的一部分,初始化函数则要按如下方式声明:int__initchr_driver_init(void);其中__init是必不可少的,在系统启动时会由内核调用chr_driver_init,完成驱动程序的初始化。当驱动程序是以模块的形式编写时,则要按照如下方式声明:intinit_module(void)在执行insmod命令插入模块时,会调用init_module函数完成初始化工作。20、在目标板上怎样安装和删除一个已编译生成的字符设备驱动模块leds.o文件?答:先将字符设备驱动模块leds.o文件复制到目标板的/lib目录下,使用以下命令安装leds模块:$insmod/lib/leds.o删除该模块的命令是:$rmmodleds.o21、Linux设备驱动程序通过调用request_irq函数来申请中断,通过free_irq来释放中断。它们在linux/sched.h中的定义如下:intrequest_irq(unsignedintirq,void(*handler)(intirq,voiddev_id,structpt_regs*regs),unsignedlongflags,constchar*device,void*dev_id);voidfree_irq(unsignedintirq,void*dev_id);试简述request_irq函数。答:Linux设备驱动程序通过调用request_irq函数来申请中断,从request_irq函数返回的值为0时,表示申请成功;负值表示出现错误。该函数中的参数为:irq表示所要申请的硬件中断号。handler为向系统登记的中断处理子程序,中断产生时由系统来调用,调用时所带参数irq为中断号,dev_id为申请时告诉系统的设备标识,regs为中断发生时寄存器内容。device为设备名,将会出现在/proc/interrupts文件里。flag是申请时的选项,它决定中断处理程序的一些特性,其中最重要的是决定中断处理程序是快速处理程序(flag里设置了SA_INTERRUPT)还是慢速处理程序(不设置SA_INTERRUPT)。22、写出将在S3C-2410X的Linux中注册外部中断2的程序代码段。答:下面的代码将在S3C-2410X的Linux中注册外部中断2。eint_irq=IRQ_EINT2;set_external_irq(eint_irq,EXT_FALLING_EDGE,GPIO
本文标题:ARM9嵌入式第七章习题
链接地址:https://www.777doc.com/doc-2901793 .html