




已阅读5页,还剩40页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Linux字符设备驱动程序设计,刘淼threewaterup-2006.3.21,linux的驱动程序,Linux下对外设的访问只能通过驱动程序Linux对于驱动程序有统一的接口,以文件的形式定义系统的驱动程序:Open、Release、read、write、ioctl驱动程序是内核的一部分,可以使用中断、DMA等操作驱动程序需要在用户态和内核态之间传递数据uClinux下可以在应用层直接访问外设,操作寄存器口,但是无法处理中断不推荐使用对于复杂的应用可以考虑是用mmap,内核功能的划分,进程管理(进程之间的通讯与同步)内存管理(malloc/free)文件系统设备控制网络功能(网络通讯协议等),Linux下设备和模块的分类,按照上述系统内核的功能,Linux中把系统的设备定义成如下三类:字符设备块设备网络设备,Linux下的设备,Linux的设备以文件的形式存在于/dev目录下设备文件是特殊文件,使用ls/dev-l命令可以看到:crw-1rootroot10,7Aug312002amigamouse1crw-1rootroot10,134Aug312002apm_biosbrw-rw-1rootdisk29,0Aug312002aztcd,主设备号和次设备号,主设备号标识设备对应的驱动程序一个驱动程序可以控制若干个设备,次设备号提供了一种区分它们的方法系统增加一个驱动程序就要赋予它一个主设备号。这一赋值过程在驱动程序的初始化过程中intregister_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops);,创建设备节点,设备已经注册到内核表中,对于设备的访问通过设备文件(设备文件与设备驱动程序的主设备号匹配),内核会调用驱动程序中的正确函数给程序一个它们可以请求设备驱动程序的名字。这个名字必须插入到/dev目录中,并与驱动程序的主设备号和次设备号相连使用mknod在文件系统上创建一个设备节点mknod/dev/mydevicec2540,动态分配设备号,在Documentation/device.txt文件中可以找到已经静态分配给大部分设备的列表由于许多数字已经分配了,为新设备选择一个唯一的号码是很困难的如果调用register_chrdev时的major为零,函数就会选择一个空闲号码并做为返回值返回,动态分配的问题,动态分配的主设备号不能保证总是一样的,无法事先创建设备节点可以从/proc/devices读取cat/proc/devices利用脚本动态创建设备文件节点,设备管理的问题,如今,Linux支持很多不同种类的硬件。这意味着/dev中都有数百个特殊文件来表示所有这些设备。而且,这些特殊文件中大多数甚至不会映射到系统中存在的设备上,使用devfs,在Linux2.4的内核里引入了devfs来解决linux下设备文件管理的问题在驱动程序中通过devfs_register()函数创建设备文件系统的节点系统启动的时候mount设备文件系统所有需要的设备节点都由内核自动管理。/dev目录下只有挂载的设备,Linux2.6内核与devfs,Linux2.6内核引入了sysfs文件系统为每个系统的硬件树进行分级处理Devfs在Linux2.6中被标记为舍弃的特性(在Linux2.6.15及以后的版本则取消了对它的支持),而使用udev。维护动态设备从sysfs获得的信息,可以提供对特定设备的固定设备名。对于热插拔的设备,这尤其重要udev是在用户空间的脚本文件,这很容易被编辑和修改为了保证旧应用程序的兼容性,在嵌入式系统中,是用devfs还是一个好方法。即使在Linux2.6.15内核以后,也可以通过ndevfs(nanodevfs)补丁提供对devfs特性的兼容。,Linux内核硬件驱动标准模板,#include#include#includestaticint_initname_of_initialization_routine(void)/*codehere*/staticvoid_exitname_of_cleanup_routine(void)/*codehere*/module_init(name_of_initialization_routine);module_exit(name_of_cleanup_routine);,module_init(1),include/linux/init.h中#definemodule_init(x)_initcall(x);#define_initcall(fn)staticinitcall_t_initcall_#fn_init_call=fnstaticinitcall_t_initcall_name_of_initialization_routine_init_call=name_of_initialization_routine,module_init(2),include/linux/init.h中定义:#define_init_call_attribute_(unused,_section_(.initcall.init)typedefint(*initcall_t)(void);arch/arm/vmlinux-armv.lds.in文件中:_initcall_start=.;*(.initcall.init)_initcall_end=.;.=ALIGN(4096);_init_end=.;init/main.c文件中定义了do_initcalls函数,_init宏,在include/linux/init.h中对于非模块加载的驱动程序:#define_init_attribute_(_section_(.text.init)通过_init,会把函数中的代码放到.text.init段。这个段在系统启动以后会被释放。在系统内核启动以后,会看到:Freeinginitmemory:68K,Linux设备驱动程序结构,结构体file_operations的定义,在include/linux/fs.h中主要包括:open,close(或者release),read,write,ioctl,poll,mmap等,一个简单的Linux驱动程序原理,创建一个字符设备,staticint_initpxa_Led_init(void)intret,i;Updateled();ret=register_chrdev(0,DEVICE_NAME,创建设备节点/dev/led/0,其他处理,staticvoid_exitpxa_Led_exit(void)#ifdefCONFIG_DEVFS_FSdevfs_unregister(devfs_Ledraw);devfs_unregister(devfs_Led_dir);#endifunregister_chrdev(LedMajor,DEVICE_NAME);module_init(pxa_Led_init);module_exit(pxa_Led_exit);,相关操作,staticintpxa_Led_open(structinode*inode,structfile*filp)MOD_INC_USE_COUNT;DPRINTK(openn);return0;staticstructfile_operationspxa_fops=owner:THIS_MODULE,open:pxa_Led_open,write:pxa_Led_write,release:pxa_Led_release,;,点亮LED,staticssize_tpxa_Led_write(structfile*file,constchar*buffer,size_tcount,loff_t*ppos)copy_from_user(,配置和编译脚本,Linux内核的编译过程,是通过内核源码中根目录和各个子目录中的Makefile分级管理的。其中,根目录的Makefile是最重要的,它可以看成是Makefile最初的入口。Make脚本读取.config文件,并根据其信息最终生成vmlinux(elf格式的Linux内核)和modules(模块)。make通过向下递归调用子目录中的Makefile来编译这两个目标。,内核的kbuild脚本,把驱动程序放到内核中,在编译内核的时候可以自由裁减。kbuild脚本随着Linux内核的发展,更新很快参考Documentation/kbuild目录下的相关文档,ARM的工作模式,ARM处理器有7种操作模式:用户模式(usr)-正常的程序执行模式快速中断模式(fiq)-支持高速数据传输或通道处理中断模式(irq)-用于通用中断处理管理员模式(svc)-操作系统的保护模式.中止模式(abt)-支持虚拟内存和/或内存保护等异常系统模式(sys)-支持操作系统的特殊用户模式(运行操作系统任务)未定义模式(und)-支持硬件协处理器的软件仿真除了用户模式外,其他模式均可视为特权模式,ARM的寄存器(1),37个寄存器31个通用32位寄存器,包括程序计数器PC6个状态寄存器15个通用寄存器(R0toR14),以及2个状态寄存器和程序计数器(PC)在任何时候都中可见的可见的寄存器取决于处理器的模式,不同的模式映射了不同的工作寄存器,ARM的寄存器(2),R0到R15可以直接访问R0到R14是通用寄存器R13:堆栈指针(sp)(通常)每种处理器模式都有单独的堆栈R14:链接寄存器(lr)R15:程序计数器(PC)CPSR当前程序状态寄存器,包括代码标志状态和当前模式位5个SPSR-(程序状态保存寄存器)当异常发生时保存CPSR状态,ARM寄存器的组织,注:表明用户或系统模式使用的正常寄存器已经被异常模式指定的另一个寄存器取代,ARM是如何处理中断的,入口是从arch/arm/kernel/entry-armv.S开始arch/arm/kernel/traps.c的trap_init函数初始化中断入口_trap_init在entry-armv.S中,异常接口映射,vector_IRQ的处理过程,ldrr13,.LCsirqsublr,lr,#4strlr,r13mrslr,spsrstrlr,r13,#4,保存状态预切换模式查表跳转,mrsr13,cpsrbicr13,r13,#MODE_MASKorrr13,r13,#MODE_SVCmsrspsr_cxsf,r13,spsr_cxsf,andlr,lr,#15ldrlr,pc,lr,lsl#2movspc,lr,IRQ模式中断的处理,主要分为两种情况:从User模式进入IRQ模式从SVC模式进入IRQ模式其他特权模式均不可能产生IRQ中断,需要有错处处理代码_irq_invalid,_irq_svc的处理过程,进入,堆栈增长方向,低,高,subsp,sp,#S_FRAME_SIZE,R0-R12,stmiasp,r0-r12,ldrr7,.LCirq,_temp_irq,addr5,sp,#S_FRAME_SIZE,svc_r13,ldmiar7,r7-r9,lr_irq-4,spsr_irq,addr4,sp,#S_SP,R4-,movr6,lr,svc_lr,stmiar4,r5,r6,r7,r8,r9,svc_r13,lr_irq-4,spsr_irq,svc_lr,中断处理的流程,进入_irq_svc时,为中断返回填充栈内数据占先式(可剥夺)内核的预处理get_irqnr_and_base得到中断向量进入C的中断处理函数asm_do_IRQ占先式内核的调度处理中断返回,非占先式与占先式,非占先式(non-preemptive)非占先式调度法也称作合作型多任务(cooperativemultitasking),各个任务彼此合作共享一个CPU。中断服务可以使一个高优先级的任务由挂起状态变为就绪状态。但中断服务以后控制权还是回到原来被中断了的那个任务,直到改任务主动放弃CPU的使用权时,那个高优先级的任务才能获得CPU的使用权。非占先式内核的一个特点是几乎不需要使用信号量保护共享数据。运行着的任务占有CPU,而不必担心被别的任务抢占。非占先式内核的最大缺陷在于其响应高优先级的任务慢,任务已经进入就绪态,但还不能运行,也许要等很时间,直到当前运行着的任务释放CPU。内核的任务级响应时间是不确定的,不知道什么时候最高优先级的任务才能拿到CPU的控制权,完全取决于应用程序什么时候释放CPU。,非占先式(Non-Preemptive),占先式(preemptive),当系统响应时间很重要时,要使用占先式内核。最高优先级的任务一旦就绪,总能得到CPU的控制权。当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU使用权就被剥夺了,或者说被挂起了,那个高优先级的任务立刻得到了CPU的控制权。使用占先式内核时,应用程序不应直接使用不可重入型函数。如果调入不可重入型函数时,低优先级的任务CPU的使用权被高优先级任务剥夺,那么,不可重入型函数中的数据就有可能被破坏。,占先式(Preemptive),占先式内核的中断处理,asm_do_IRQ中的处理,在arch/arm/kernel/irq.c中从汇编到C传递的参数do_IRQ(intirq,structpt_regs*regs)查表调用注册的中断处理程序。通过全局数组irq_desc管理,注册中断函数,intrequest_irq(unsignedintirq,irqreturn_t(*handler)(int,void*,structpt_regs*),unsignedlongirq_flags,constchar*devname,void*dev_id)irq,中断向量号handler
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度跨境贸易代理服务合同范本
- 2025版印刷设备维修保密协议
- 二零二五年度新型环保灰砂砖批量采购合同规范版
- 二零二五年度租赁房屋租赁押金及违约责任合同
- 2025版化工原材料采购与供应链管理合同
- 2025版环保企业安全生产管理与应急处理合同
- 2025版城市更新改造项目施工合同规范文本
- 二零二五年新型储能电站维护与保养服务协议
- 2025电梯维保安全协议书-高层住宅电梯全面保障合同
- 2025版钢结构厂房施工期道路通行与临时设施建设合同
- 《人工智能:AIGC基础与应用》高职全套教学课件
- 2025年云南省建筑行业安全员A证理论考试练习题(100题)含答案
- 社会福利 课件全套 高和荣 第1-11章 绪论-社会福利的挑战
- 系统工程师工作总结
- 2025届上海市(春秋考)高考英语考纲词汇对照表清单
- 合同延期协议模板
- 医院创建平安医院领导小组职责
- 光源与照明工程师月工作总结
- 《腰椎病的推拿疗法》课件
- 《T-ZGYSYJH 004-2022 产褥期妇女食养药膳技术指南》
- 齐河经济开发区马寨小区安置楼工程临时用电组织设计(5月10日改)
评论
0/150
提交评论