还剩4页未读,继续阅读
文本内容:
第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_chrdevunsignedintmajorconstchar*namestructfile_operations*fops;externintunregister_chrdevunsignedintmajorconstchar*name;这两个函数运行成功是返回0,运行失败返回一个负的错误码参数major对应所请求的主设备号,name对应设备的名字,fops对应于该设备的一个结构
12、简述数据结构file_operations的作用答linux的内核内部通过file结构识别设备,通过file_operations数据结构提供文件系统的入口点函数,也就是访问设备驱动的函数这个数据结构的每一个成员的名字都对应着一个系统调用在用户进程利用系统调用对设备文件进行诸如read/write操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数,这就是Limux的设备驱动程序的工作原理在file_operations数据结构中,指出了设备驱动程序所提供的入口点位置
13、解释下面函数的作用1)intcheck_regionunsignedintfromunsignedintextent;2)voidrequest_regionunsignedintfromunsignedintextentconstchar*name;3)voidrelease_regionunsignedintfromunsignedintextent;答1)intcheck_regionunsignedintfromunsignedintextent; 这个函数察看系统的I/O表,看是否有别的驱动程序占用某一段I/O口2)voidrequest_regionunsignedintfromunsignedintextentconstchar*name; 如果这段I/O端口没有被占用,在驱动程序中就可以使用它在使用之前,必须向系统登记,以防止被其他程序占用登记后,在/proc/ioports文件中可以看到你登记的I/O口 在对I/O口登记后,就可以放心地用inb,outb之类的函数来访问了3)voidrelease_regionunsignedintfromunsignedintextent;此函数用来释放登记的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_chrdevunsignedintmajorconstchar*namestructfile_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_chrdevunsignedintmajorconstchar*name;此函数的参数为主设备号major和设备名nameLinux内核把name和major在内核注册的名称对比,如果不相等,卸载失败,并返回-EINVAL;如果major大于最大的设备号,也返回-EINVAL
19、若驱动程序是内核的一部分,初始化函数如何声明?当驱动程序是以模块的形式编写时,应如何声明?答若驱动程序是内核的一部分,初始化函数则要按如下方式声明int__initchr_driver_initvoid;其中__init是必不可少的,在系统启动时会由内核调用chr_driver_init,完成驱动程序的初始化当驱动程序是以模块的形式编写时,则要按照如下方式声明intinit_modulevoid在执行insmod命令插入模块时,会调用init_module函数完成初始化工作
20、在目标板上怎样安装和删除一个已编译生成的字符设备驱动模块leds.o文件?答先将字符设备驱动模块leds.o文件复制到目标板的/lib目录下,使用以下命令安装leds模块$insmod/lib/leds.o删除该模块的命令是$rmmodleds.o
21、Linux设备驱动程序通过调用request_irq函数来申请中断,通过free_irq来释放中断它们在linux/sched.h中的定义如下intrequest_irqunsignedintirqvoid*handlerintirqvoiddev_idstructpt_regs*regsunsignedlongflagsconstchar*devicevoid*dev_id;voidfree_irqunsignedintirqvoid*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中注册外部中断2eint_irq=IRQ_EINT2;set_external_irqeint_irqEXT_FALLING_EDGEGPIO_PULLUP_DIS;ret_val=request_irqeint_irqeint2_handler“S3C2410Xeint2”0;ifret_val0{returnret_val;}用来打开和关闭中断的函数如下#definecli_asm__volatile_cli::#definesli_asm__volatile_sli::
23、有一模块module.o文件,在/lib/modules目录下写出装载和卸载模块的命令答首先从/lib/modules目录和内核相关的子目录中查找模块文件,如果需要从当前目录装载,可使用如下命令#insmodmodule.o若要卸载该模块,可使用如下命令#rmmodmodule.o
二、综合题
1、LED接口电路如图
2.1所示其中LED
1、LED
2、LED3及LED4分别接S3C2410芯片的I/O口GPB
7、GPB
8、GPB9及GPB10图中4个LED为共阳极接法,通过读写GPBI/O口可以控制LED的状态当端口电平为低时LED点亮,输出高电平时LED熄灭阅读下面的程序段,说明其程序完成的功能staticint__initleds_initvoid{intret;inti;ret=register_chrdevLED_MAJORDEVICE_NAMEleds_fops;ifret0{printkDEVICE_NAMEcantregistermajornumber\n;returnret;}devfs_handle=devfs_registerNULLDEVICE_NAMEDEVFS_FL_DEFAULTLED_MAJOR0S_IFCHR|S_IRUSR|S_IWUSRmatrix4_leds_fopsNULL;/*使用宏进行端口初始化,set_gpio_ctrl和write_gpio_bit均为宏定义*/fori=0;i8;i++{set_gpio_ctrlled_table[i]|GPIO_PULLUP_EN|GPIO_MODE_OUT;write_gpio_bitled_table[i]1;}printkDEVICE_NAMEinitialized\n;return0;}答模块的入口函数leds_init,所做的工作是通过register_chrdev完成字符设备在系统中的注册,并建立与文件系统的并联并使I/O端口对应的LED在初始状态为熄灭
2、下面是s3c
2410.h文件中几个宏定义阅读下面几条宏定义语句,试写出GPBCON、GPBDAT、GPBUP对应的寄存器地址#defineGPIO_CTL_BASE0x56000000/*IO口控制寄存器及地址*/#definebGPIOp__REGGPIO_CTL_BASE+p/*寄存器地址0X50000000+p*/#defineGPBCONbGPIO0x10/*寄存器地址0X56000010*/#defineGPBDATbGPIO0x14/*寄存器地址0X56000014*/#defineGPBUPbGPIO0x18/*寄存器地址0X56000018*/...答GPBCON寄存器地址为0X56000010;GPBDAT寄存器地址为0X56000014;GPBUP寄存器地址为0X
560000183、下面的函数完成什么功能?staticvoid__exitleds_exitvoid{devfs_unregisterdevfs_handle;unregister_chrdevLED_MAJORDEVICE_NAME;}答卸载模块时调用leds_exit函数,执行后设备处于空闲状态此函数的功能是完成本设备文件系统的注销和本设备的注销
4、用insmod命令加载模块时,调用什么函数加载模块?用rmmod命令来卸载模块时,调用什么函数卸载模块?答用insmod命令加载模块时,调用module_init,而在module_init中调用register_chrdev完成字符设备注册;用rmmod命令来卸载模块时,会调用module_exit函数,而在module_exit函数中调用unregister_chrdev来完成设备的注销图
2.1。