欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    嵌入式操作系统cha.ppt

    • 资源ID:6569767       资源大小:432KB        全文页数:74页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    嵌入式操作系统cha.ppt

    第七章中断与系统调用,在Linux系统中,中断是外设与系统通信的必须手段,是处理器实时性的重要体现。通过这一章的学习,需要掌握以下基本内容中断概念基于ARM平台的中断特点Linux内核中断机制Linux中断处理程序设计Linux的中断处理机制Linux的系统调用,学习目标,主要内容,1,3,2,5,中断概念,嵌入式ARM平台的中断特点,Linux内核中断机制,Linux中断处理机制,6,Linux的系统调用,4,Linux中断处理程序设计,一、中断概念,中断机制中断含义中断响应过程,Linux内核要管理计算机上的硬件设备,首先要和他们通信。而处理器的速度跟外围硬件设备的速度往往不在一个数量级上,因此,如果内核采取让处理器向硬件发出一个请求,然后专门等待回应的办法,显然效率很低。既然硬件的响应这么慢,那么内核就应该在此期间处理其他事务,等到硬件真正完成了请求的操作之后,再回过头来对它进行处理。想要实现这种功能,轮询(polling)可能会是一种解决办法。可以让内核定期对设备的状态进行查询,然后做出相应的处理。不过这种方法很可能会让内核做不少无用功,因为无论硬件设备是正在忙碌着完成任务还是已经大功告成,轮询总会周期性地重复执行。更好的办法是由人为的来提供一种机制,让硬件在需要的时候再向内核发出信号(变内核主动为硬件主动)。这就是中断机制。,一、中断概念,1、中断机制,在嵌入式系统中外部设备的功能实现主要是依靠中断机制来实现的,即将设备功能程序的实现以中断服务子程序的形式进行组织。中断(interrupt)是指CPU正在执行的程序时,被内部/外部事件或有程序预先安排的事件所打断,当前正在执行的程序被中止,CPU转去处理所发生的事件,处理完毕后再返回继续执行暂时中止的程序执行,这一过程称为中断。,一、中断概念,2、中断的含义,中断的作用:并行操作硬件故障报警与处理支持多道程序并发运行,提高计算机系统的运行效率支持实时处理功能 Linux中通常分为外部中断(又叫硬件中断)、内部中断(又叫异常)和软件中断。内中断:即程序运行错误引起的中断外中断:即由外部设备、接口卡引起的中断软件中断:由写在程序中的语句引起的中断程序的执行,称为软件中断,一、中断概念,2、中断的含义,2、中断的含义,按中断源进行分类:中断源:引起中断的事件称为中断源。中断源是多种多样的,按其性质可分为内部中断源和外部中断源。内部中断源位于CPU内部。主要的内部中断源有:(1)CPU指令运行产生异常,如除法溢出(除0中断)。(2)程序执行INT软件中断指令。如INT 21H等。(3)程序调试过程中的中断,如单步中断。外部中断源是通过CPU的中断请求引脚发出中断请求信号。主要外部中断源有:(1)I/O设备,如键盘、显示器、打印机。(2)数据通道,如软盘、硬盘等。(3)故障源,如电源掉电、内存及外部设备出错等。(4)其它外部设施备。,一、中断概念,2、中断的含义,允许/禁止(开/关)中断:CPU通过指令限制某些设备发出中断请求,称为屏蔽中断。从CPU要不要接收中断即能不能限制某些中断发生的角度,中断可分为:可屏蔽中断:可被CPU通过指令限制某些设备发出中断请求的中断不可屏蔽中断:不允许屏蔽的中断如电源掉电 中断优先级:为了管理众多的中断请求,需要按每个(类)中断处理的急迫程度,对中断进行分级管理,称其为中断优先级。在有多个中断请求时,总是响应与处理优先级高的设备的中断请求。中断嵌套:当CPU正在处理优先级较低的一个中断,又来了优先级更高的一个中断请求,则CPU先停止低优先级的中断处理过程,去响应优先级更高的中断请求,在优先级更高的中断处理完成之后,再继续处理低优先级的中断,这种情况称为中断嵌套。,一、中断概念,具体的中断过程:一次完整的中断过程由中断请求、中断响应和中断处理三个阶段组成。中断请求:是由中断源发出的并送给CPU的控制信号,由中断源设备通过将接口卡上的中断寄存器的相应位置“1”完成。中断响应:当CPU接到中断请求,若满足下列条件,就会响应中断。中断处理过程:关中断-保存断点保护现场-判中断源转中断服务-开中断-执行中断服务程序-关中断-恢复现场恢复断点-开中断-返回断点,3、中断过程,一、中断概念,主要内容,1,3,2,5,中断概念,嵌入式ARM平台的硬件中断特点,Linux内核中断机制,Linux中断处理机制,6,Linux的系统调用,4,Linux中断处理程序设计,二、嵌入式ARM平台的硬件中断特点,硬件中断中断请求过程ARM平台中断,1、硬件中断,二、嵌入式ARM平台中断特点,2、中断请求过程,二、嵌入式ARM平台中断特点,中断发生时,外设需要通知操作系统它那里发生了一些事情,但是中断的功能仅仅是一个设备报警,当报警灯亮时中断处理程序只知道有事情发生,但发生了什么事情还需要查看设备才行。即就是访问设备上的一些寄存器后,才知道具体发生什么的事情,如何怎么处理。具体过程:设备通过中断线向中断控制器发送信号告诉操作系统它产生了一个中断;操作系统从中断控制器的状态位得知哪条中断线上产生的中断;根据中断线上的设备特点来处理中断。,2、中断请求过程,二、嵌入式ARM平台中断特点,在Linux下,硬件中断叫做IRQ(Interrupt Requests的缩写),通常把申请一条中断线称为申请一个IRQ或者申请一个中断号。申请IRQ(Interrupt Requirement)的过程,分为3步:将所有的中断线探测一遍,看看哪些中断还没有被占用。从这些还没有被占用的中断中选一个作为该设备的IRQ。通过中断申请函数申请选定的IRQ,这时要指定申请的方式是独占还是共享。根据中断申请函数的返回值决定是否重新申请或者放弃申请并返回错误。,3、ARM平台的中断,二、嵌入式ARM平台中断特点,系统中每一个注册的中断源,都会分配一个唯一IRQ编号用于识别该中断。IRQ编号贯穿在整个Linux的通用中断子系统中。在嵌入式平台中,每个中断源的IRQ编号都会在arch相关的一些头文件中,例如arch/xxx/mach-xxx/include/irqs.h。驱动程序在请求中断服务时,它会使用IRQ编号注册该中断,中断发生时,CPU通常会从中断控制器中获取相关信息,然后计算出相应的IRQ编号,然后把该IRQ编号传递到相应的驱动程序中。,主要内容,1,3,2,5,中断概念,嵌入式ARM平台的硬件中断特点,Linux内核中断机制,Linux中断处理机制,6,Linux的系统调用,4,Linux中断处理程序设计,三、Linux内核中断机制概述,Linux内核中断原理Linux内核中断方式Linux内核中断方式的区别,1、Linux内核中断机制,三、Linux内核中断概述,Linux系统的中断就是通常意义上的“中断处理程序”,它是直接处理由硬件发过来的中断信号。当Linux内核收到中断请求后,它首先判断中断源,然后调用相应的设备驱动程序,驱动程序会去设备上查看其状态寄存器以了解发生了什么事情,并进行相应的操作。Linux内核与中断相关的部分包括:硬件中断,下半部任务和内核线程。,2、Linux内核中断方式,三、Linux内核中断概述,(1)硬中断任务 硬中断是指那些由处理器以外的外设产生的中断,这些中断被处理器接收后交给内核中的中断处理程序处理。要注意的是:第一,硬中断是异步产生的,中断发生后立刻得到处理,也就是说中断操作可以抢占内核中正在运行的代码。这点非常重要。第二,中断操作是发生在中断上下文中的(所谓中断上下文指的是和任何进程无关的上下文环境)。中断上下文中不可以使用进程相关的资源,也不能够进行调度或睡眠。异步发生的中断处理程序根本不知道当前进程的任何信息,也不关心当前哪个进程在运行,它完全是个过客。,2、Linux内核中断方式,三、Linux内核中断概述,(2)下半部分任务 Linux中,中断处理程序从概念上被分为上半部分(top half)和下半部分(bottom half);在中断发生时上半部分的处理过程立即执行,但是下半部分(如果有的话)却推迟执行。内核把上半部分和下半部分作为独立的函数来处理,上半部分决定其相关的下半部分是否需要执行。必须立即执行的部分必须位于上半部分,而可以推迟的部分可能属于下半部分。,2、Linux内核中断方式,三、Linux内核中断概述,(2)下半部分任务 下半部任务是一种推后执行任务,它将某些不那么紧迫的任务推迟到系统更方便的时刻运行。内核中实现下半部的手段经过不断演化,目前已经从最原始的BH(bottom half)衍生出tasklet,软中断softirq,工作队列(work queues)。上半部只能通过中断处理程序来完成,下半部的实现却是有很多种方式。,为什么这样划分成两个部分呢,3、Linux内核中断方式,三、Linux内核中断概述,(3)软中断操作 软中断softirq不象硬中断那样是由硬件中断信号触发执行的,所以也不同于硬件中断那样随时都能够被执行。软中断会在内核处理任务完毕后返回用户级程序前得到处理机会。即就是有三个时刻它将被执行do_softirq函数。硬件中断操作完成后,系统调用返回时,内核调度程序中。从中可以看出软中断会紧随硬中断处理,所以抢占内核任务至少在时钟中断后总有机会运行一次。还要记得软中断可以在不同处理器上并发执行。,2、Linux内核中断方式,三、Linux内核中断概述,(3)软中断操作 实际上软中断使用的并不多,反而是后面的tasklet比较多,但tasklet是通过软中断实现的,软中断的代码位于/kernel/softirq.c中。软中断是在编译期间静态分配的,由softirq_action结构表示,它定义在linux/interrupt.h中。使用时先open_softirq,需要发出此软中断时使用raise_softirq或cpu_raise_softirq。软中断的执行也处于中断上下文中,所以中断上下文对它的限制是和硬中断一样的,一样不能进入阻塞状态。,3、Linux内核中断方式区别,三、Linux内核中断概述,tasklet和bottom half都是建立在软中断之上的两种延迟机制,其具体不同之处在于:软中断是静态分配的,而且同类软中断可以并发地在几个CPU上运行。tasklet可以动态分配,并且不同种类的Tasklets可以并发地在几个CPU上运行,但同类的Tasklets不可以。bottom half 只能静态分配。实际上,下半部分是一个不能与其它下半部分并发执行的高优先级tasklet,即使它们类型不同,而且在不同 CPU上运行。tasklet可以理解为软中断的派生,所以它的调度时机与软中断一致。,3、Linux内核中断方式区别,三、Linux内核中断概述,Tasklets与softirq的主要一个区别就是在同一时刻,只能用一个cpu来运行一个tasklet。而softirq就不然,可以在不同cpu上运行同一个softirq,但要注意做好相关的保护工作。Tasklets而它与BH的区别是不同的Tasklets可以在同一时刻运行在不同的cpu上,而BH是不可以的。而在它的结构定义中,最重要的就是func成员,它所指的地址就是最终要执行的处理函数。对于内核中需要延迟执行的多数任务都可以利用tasklet来完成,由于同类tasklet本身已经进行了同步保护,所以使用tasklet相比软中断要简单得多,而且效率也不错。,3、Linux内核中断方式区别,三、Linux内核中断概述,bottom half 是Linux最早的内核延迟方法,它结构简单且容易控制,因为所有的BH处理程序都被严格地顺序执行,不允许任何两个BH处理程序同时并发执行,即使它们的类型不同也不可以,这样一来BH执行期间减少了许多同步保护。但是BH不得不被淘汰,因为它的简便牺牲了多处理器并发处理的高性能,等于一队人过独木桥那样速度受到牵制。任务列队是BH的替代品,来自BH,所以它的属性也和BH相同。它的原意在于简化BH的操作接口,但它的随意性(数量随意、执行时机随意)却给系统带来了混乱,所以到今天已经被工作队列所取代。,主要内容,1,3,2,5,中断概念,嵌入式ARM平台的硬件中断特点,Linux内核中断机制,Linux中断处理机制,6,Linux的系统调用,4,Linux中断处理程序设计,四、Linux中断处理程序,中断处理系统结构注册中断处理函数中断标志flags中断上下文,1、中断处理系统结构,Linux中断处理子系统的一个基本任务是将中断正确路由到中断处理代码中的正确位置。这些代码必须了解系统的中断拓扑结构。Linux使用一组指针来指向包含处理系统中断例程的调用地址。这些例程属于对应于此设备的设备驱动,同时由它负责在设备初始化时为每个设备驱动申请其请求的中断。Linux对中断组织管理的相关的三个重要数据结构:struct irq_desc IRQ描述符在内核中,每个中断向量都有相应的有一个irq_desc结构体(稍早内核版本中为irq_desc_t)来描述一个中断向量(也就是中断源),四、Linux中断处理程序,1、中断处理系统结构,Linux内核将所有的中断统一编号,使用一个irq_desc结构数组来描述这些中断;每个数组项对应一个中断,也可能是一组中断,它们共用相同的中断号,里面记录了中断的名称、中断状态、中断标记(比如中断类型、是否共享中断等),并提供了中断的低层硬件访问函数(清除、屏蔽、使能中断),提供了这个中断的处理函数入口,通过它可以调用用户注册的中断处理函数。通过irq_desc结构数组就可以了解中断处理体系结构,irq_desc结构的数据类型include/linux/irq.h中定义,,四、Linux中断处理程序,四、Linux中断处理程序,struct irq_desc unsigned intirq;struct timer_rand_state*timer_rand_state;unsigned int*kstat_irqs;#ifdef CONFIG_INTR_REMAPstruct irq_2_iommu*irq_2_iommu;#endifirq_flow_handler_thandle_irq;/当前中断的处理函数入口struct irq_chip*chip;/低层的硬件访问struct msi_desc*msi_desc;void*handler_data;void*chip_data;struct irqaction*action;/用户提供的中断处理函数链表unsigned intstatus;/IRQ状态.const char*name;/中断的名称 _cacheline_internodealigned_in_smp;,四、Linux中断处理程序,handle_irq是这个或这组中断的处理函数入口。发生中断时,总入口函数asm_do_IRQ将根据中断号调用相应irq_desc数组项中handle_irq。handle_irq使用chip结构中的函数清除、屏蔽或者重新使能中断,还要调用用户在action链表中注册的中断处理函数。,1、中断处理系统结构,Linux对中断组织管理的数据结构:struct irqaction中断服务例程描述符,在IRQ描述符中指针action的结构为irqaction,它是为多个设备能共享一条中断线而设置的一个数据结构,代表了每个注册中断对应的信息。在include/linux/interrupt.h中定义如下:,四、Linux中断处理程序,struct irqaction irq_handler_t handler;/用户注册的中断处理函数unsigned long flags;/中断标志const char*name;/用户注册的中断名字void*dev_id;/用户传给上面的handler的参数struct irqaction*next;/指向下一个用户注册函数的指针int irq;/中断号;,1、中断处理系统结构,Linux对中断组织管理的数据结构:struct irq_chip片级的中断描述符 是一个中断控制器的描述符,其中的成员大多用于操作底层硬件,比如设置寄存器以屏蔽中断,使能中断,清除中断等。通常不同的体系结构就有一套自己的中断处理方式。内核为了统一的处理中断,提供了底层的中断处理抽象接口,对于每个平台都需要实现底层的接口函数。这样对于上层的中断通用处理程序就无需任何改动。这样的结构体就好比一个插板,我们可以使用各种插头。至于插板内部是如何实现的,使用者并不需要过于关心。,四、Linux中断处理程序,四、Linux中断处理程序,struct irq_chip const char*name;unsigned int(*startup)(unsigned int irq);/启动中断,如果不设置,缺省为“enablevoid(*shutdown)(unsigned int irq);/*关闭中断,如果不设置,缺省为disable*/void(*enable)(unsigned int irq);/使用中断,如果不设置,缺省为unmaskvoid(*disable)(unsigned int irq);/禁止中断,如果不设置,缺省为“mask”void(*ack)(unsigned int irq);/*响应中断,通常是清除当前中断使得可以接收下一个中断*/void(*mask)(unsigned int irq);/屏蔽中断源void(*mask_ack)(unsigned int irq);/屏蔽和响应中断void(*unmask)(unsigned int irq);/开启中断源void(*eoi)(unsigned int irq);.const char*typename;,1、中断处理系统结构,四、Linux中断处理程序,Linux对中断组织管理的数据结构之间的关系:,1、中断处理系统结构,四、Linux中断处理程序,通过上述分析:struct irq_chip描述了中断最底层的部分;struct irqacton则描述最上层具体的中断处理函数;而与中断向量所对应的struct desc则类似一个中间层,将中断中的硬件相关的部分和软件相关的部分连接起来。,1、中断处理系统结构,四、Linux中断处理程序,Linux中断处理过程,1、中断处理系统结构,中断发生时Linux首先读取系统可编程中断控制器中中断状态寄存器判断出中断源,将其转换成irq_action数组中偏移值。如果此中断没有对应的中断处理过程则Linux核将记录这个错误,不然它将调用对应此中断源的所有irqaction数据结构中的中断处理例程。具体中断处理程序的调用过程:在do_IRQ函数中,通过对irq_desc结构体中handler_irq字段的引用,调用handler_irq所指向的服务程序;在这个服务程序中会调用hand_IRQ_event函数;在hand_IRQ_event函数中,通过对irqaction结构体中handler字段的引用最终调用我们所写的中断处理程序。,四、Linux中断处理程序,2、注册中断函数,与Linux设备驱动程序中断处理相关的,内核提供的注册和注销中断函数,即request_irq和free_irq,这两个函数在实际中非常重要,其函数原型在/include/linux/interrupt.h中声明。int request_irq(unsigned int irq,void(*handler)(int irq,void dev_id,struct pt_regs*regs),unsigned long flags,const char*device,void*dev_id)/功能是注册一个IRQ参数irq表示所要申请的硬件中断号。Handler是向系统登记的中断处理子程序,dev_id为申请时告诉系统的设备标识,regs为中断发生时寄存器内容。device为设备名,将会出现在/proc/interrupts文件里。flag是申请时的选项(属性)。,四、Linux中断处理程序,2、注册中断函数,int request_irq()/功能是注册一个IRQrequest_irq()成功执行会返回0。如果返回非0值,就表示有错误发生,指定的中断处理程序不会被注册。最常见的错误是一EBUSY,它表示给定的中断线已经在使用(或者当前用户没有指定SA_ SHIRQ)。INVAL表示irq15或者handler=NULL例如:假定一个程序要对/dev/fd0/设备进行访问,通常将IRQ6分配给软盘控制器,给定这个中断号6,软盘驱动程序就可以发出下列请求 request_irq(6,floppy_interrupt,SA_INTERRUPT|SA_SAMPLE_RANDOM,floppy,NULL);,四、Linux中断处理程序,2、注册中断函数,中断卸载free_irq卸载驱动程序或者关闭设备时,需要注销相应的中断处理程序,并释放中断线。可以调用void free_irq(unsigned int irq,void*dev_ id)来释放中断线。参数irq表示硬件中断号。dev_id为设备标识,该参数是为了区别共享同一中断号的不同设备而设,若此中断号为一个设备所独享,这个参数可为空。,四、Linux中断处理程序,2、注册中断函数,中断卸载free_irq如果指定的中断线不是共享的,那么,该函数删除处理程序的同时将禁用这条中断线。如果中断线是共享的,则仅删除dev_id所对应的处理程序,而这条中断线本身只有在删除了最后一个处理程序时才会被禁用。对于共享的中断线,需要一个唯一的信息来区分其上面的多个处理程序,并让free_irq()仅仅删除指定的处理程序。如果dev_id非空,它都必须与需要删除的处理程序相匹配。非共享中断,该域可以为空,但需要和注册时使用的指针一致。例如,当软盘操作终止时(或者终止对/dev/fd0/的I/O操作,或者卸载这个文件系统),驱动程序就放弃这个中断号:free_irq(6,NULL);,四、Linux中断处理程序,3、中断标志flags,中断标志flags可以设置为:SA_INTERRUPT。如果设置该位,就指示这是一个快速中断处理程序,如果清除这位,那么它就是一个慢速中断处理程序。SA_SHIRQ 该位表明中断可以在设备间共享。SA_SAMPLE_RANDOM 该位表明产生的中断对/dev/random和/dev/urandom设备要使用的熵池(entropy pool)有贡献。读这些设备返回真正的随机数,这些随机数是从一个熵池中取得的,如果希望设备真正随机地产生中断,应该置上这个标志。而如果的中断是可预测的,那就不值得设置这个标志位它对系统的熵池没有任何贡献。,四、Linux中断处理程序,4、ISR上下文,当进程发出一个系统调用的请求时,由应用户态切换到内核态。这样的内核控制路径被成为进程内核路径,也叫进程上下文。当CPU执行一个与中断有关的内核控制路径的时候,被成为中断上下文。中断的上半部和下半部都属于ISR上下文。,四、Linux中断处理程序,主要内容,1,3,2,5,中断概念,嵌入式ARM平台的硬件中断特点,Linux内核中断机制,Linux中断处理机制,6,Linux的系统调用,4,Linux中断处理程序设计,五、Linux中断处理机制,TaskLet机制上半部和下半部工作队列,中断是内核不可缺少的一部分,但是中断处理程序本身存在一些局限性,于是内核将中断分为上下两个部分,上半部分中断处理程序,用来完成对硬件中断的即时响应,下半部分推迟执行,下半部执行的关键在于他们运行的时候,允许响应中断。下半部的实现方式:中内核提供了三种不同形式的下半部实现机制:软中断,tasklet和工作队列。,五、Linux中断处理机制,1、TaskLet机制,tasklet是一种特殊的软中断机制,它可以被多次调度运行。Linux内核使用tasklet机制实现下半部处理。软中断向量HI_SOFTIRQ和TASKLET_SOFTIRQ均是用tasklet机制来实现的。实际上,现在的下半处理程序本身就是用tasklet实现的。tasklet机制是Linux内核对BH机制的一种扩展:1.与一般的软中断不同,某一段tasklet代码在某个时刻只能在一个CPU上运行,而不像一般的软中断服务函数(即softirq_action结构中的action函数指针)那样在同一时刻可以被多个CPU并发地执行。2.与BH机制不同,不同的tasklet代码在同一时刻可以在多个CPU上并发地执行,而不像BH机制那样必须严格地串行化执行(也即在同一时刻系统中只能有一个CPU执行BH函数)。,五、Linux中断处理机制,1、TaskLet机制,tasklet_struct结构定义在文件中。定义一个处理函数void my_tasklet_func(unsigned long)DECLARE_TASKLET(my_tasklet,my_tasklet_func,data);/*定义一个tasklet结构my_tasklet,与my_tasklet_func(data)函数相关联,相当于DECLARE_TASK_QUEUE()*/tasklet_schedule(/*登记my_tasklet,允许系统在适当的时候进行调度运行,相当于queue_task(&my_task,&tq_immediate)和mark_bh(IMMEDIATE_BH)*/,五、Linux中断处理机制,1、TaskLet机制,tasklet机制还提供了另外一些调用接口:DECLARE_TASKLET_DISABLED(name,function,data);tasklet_enable(struct tasklet_struct*);tasklet_disble(struct tasklet_struct*);tasklet_init(struct tasklet_struct*,void(*func)(unsigned long),unsigned long);tasklet_kill(struct tasklet_struct*);,五、Linux中断处理机制,1、TaskLet机制,Linux系统中定义了两个tasklet队列的向量表,每个向量对应一个CPU(向量表大小为系统能支持的CPU最大个数,在SMP方式下目前为32)组织成一个tasklet链表:struct tasklet_head tasklet_vecNR_CPUS _cacheline_aligned;struct tasklet_head tasklet_hi_vecNR_CPUS _cacheline_aligned;对于32个bottom half,系统也定义了对应的32个tasklet结构:struct tasklet_struct bh_task_vec32;,五、Linux中断处理机制,2、上半部分和下半部分机制,上半部和下半部的设计Linux中的一个中断处理程序分为两个部分:上半部(top half)和下半部(bottom half)。上半部的功能是“登记中断”。当一个中断发生时,他就把设备驱动程序中中断例程的下半部挂到该设备的下半部执行队列中去,然后就等待新的中断的到来。因此,上半部执行的速度就会很快,可以服务更多的中断请求。但是,仅有登记中断是远远不够的,因为中断的事件可能很复杂。因此,Linux引入了一个下半部,来完成中断事件的绝大多数使命。,五、Linux中断处理机制,2、上半部分和下半部分机制,上半部和下半部的设计Linux中的一个中断处理程序分为两个部分:下半部和上半部最大的不同是下半部是可中断的,而上半部是不可中断的。下半部一般所负责的工作是查看设备以获得产生中断的事件信息,并根据这些信息(一般通过读设备上的寄存器得来)进行相应的处理。第一部分是中断处理程序,用来完成对硬件中断的及时响应,第二部分就是我们所说的下半部,完成余下的相对宽松的任务。,五、Linux中断处理机制,2、上半部分和下半部分机制,上半部和下半部的设计中断处理程序的不可重入性在中断处理的过程中要屏蔽同一IRQ来的新中断,是因为中断处理程序是不可重入的,所以不能并行执行同一个中断处理程序。设备驱动程序和设备寄存器交互,而且设备寄存器是一个全局变量,因此很难写出重入的代码。最简单的方法是禁止同一设备的中断处理程序并行。,五、Linux中断处理机制,3、工作队列,(1)工作队列概念工作队列(work queue)是另一种中断后处理机制。tasklet虽然也是中断后处理,但是它始终处于中断上下文中,所有的代码必须是原子的。而工作队列函数则处于一个特殊的内核线程上下文中,因此它可以阻塞。工作队列和前面讨论的其他形式都不相同,它可以把工作推后,交由一个内核线程去执行-该工作总是会在进程上下文执行。这样,通过工作队列执行代码能占尽进程上下文的所有优势,最重要的就是工作队列允许重新调度甚至是睡眠。,五、Linux中断处理机制,(2)工作队列的实现工作队列子系统是一个用于创建内核线程的接口,通过它创建的进程负责执行由内核其他部分排到队列里的其他任务。它创建的这些内核线程被称作工作者线程。工作队列可以让驱动程序创建一个专门的工作者线程来处理需要推后的工作。不过,工作队列子系统提供了一个默认的工作者线程来处理这些工作。因此,工作队列最基本的表现形式就转变成了一个把需要推后执行的任务交给特定的通用线程这样一个接口。,3、工作队列,五、Linux中断处理机制,(3)工作队列的数据结构工作队列数据结构:有一个 struct workqueue_struct 类型,在 中定义。创建一个新的任务队列和与之相关的工作者线程,你只需调用一个简单的函数:struct workqueue_struct*create_workqueue(const char*name);name是工作队列的名字。工作队列任务可以在编译时或者运行时创建。任务需要封装为一个叫做work_struct的结构体,3、工作队列,五、Linux中断处理机制,(3)工作队列的数据结构工作的数据结构:工作用中定义的work_struct结构表示:struct work_structunsigned long pending;/*这个工作正在等待处理吗?*/struct list_head entry;/*连接所有工作的链表*/void(*func)(void*);/*要执行的函数*/void*data;/*传递给函数的参数*/void*wq_data;/*内部使用*/struct timer_list timer;/*延迟的工作队列所用到的定时器*/;这些结构体被连接成链表,在每个处理器的每种类型的队列都对应这样一个链表。当一个工作者线程被唤醒时,它会执行它的链表上的所有工作。,3、工作队列,五、Linux中断处理机制,(3)工作队列的数据结构创建推后的工作要使用工作队列,首先要做的是创建一些需要推后完成的工作。可以通过DECLARE_WORK在编译时静态地创建该结构:DECLARE_WORK(name,void(*func)(void*),void*data);这样就会静态地创建一个名为name,待执行函数为func,参数为data的work_struct结构。在运行时初始化一个工作队列通过指针创建一个工作:INIT_WORK(structwork_struct*work,woid(*func)(void*),void*data);这会动态地初始化一个由work指向的工作。,3、工作队列,五、Linux中断处理机制,(3)工作队列的数据结构用下面的函数调用来把一个任务加入到工作队列中:int queue_work(struct workqueue_struct*queue,struct work_struct*work);int queue_delayed_work(struct workqueue_struct*queue,struct work_struct*work,unsigned long delay);任何一个在工作队列中等待的任务用下面的方法取消:int cancel_delayed_work(struct work_struct*work);清空工作队列中的所有任务使用:void flush_workqueue(struct workqueue_struct*queue);,3、工作队列,五、Linux中断处理机制,(3)工作队列的数据结构销毁工作队列使用:void destroy_workqueue(struct workqueue_struct*queue);驱动程序可以使用内核提供的缺省工作队列。int schedule_work(struct work_struct*work);/向工作队列中添加一个任务 int schedule_delayed_work(struct work_struct*work,unsigned long delay);/向工作队列中添加一个任务并延迟执行,3、工作队列,五、Linux中断处理机制,主要内容,1,3,2,5,中断概念,嵌入式ARM平台的硬件中断特点,Linux内核中断机制,Linux中断处理机制,6,Linux的系统调用,4,Linux中断处理程序设计,六、Linux中断系统调用,初始化系统调用system_call函数参数传递与验证,什么是系统调用在Linux的世界里,我们经常会遇到系统调用这一术语,所谓系统调用,就是内核提供的、功能十分强大的一系列的函数。这些系统调用是在内核中实现的,再通过一定的方式把系统调用给用户,一般都通过门(gate)陷入(trap)实现。系统调用是用户程序和内核交互的接口。系统调用的作用系统调用在Linux系统中发挥着巨大的作用,如果没有系统调用,那么应用程序就失去了内核的支持。我们在编程时用到的很多函数,如fork、open等这些函数最终都是在系统调用里实现的。系统调用是用户接口在内核中的实现,如果没有系统调用,用户就不能利用内核。,六、Linux系统调用,Linux系统在CPU的保护模式下提供了四个特权级别,目前内核都只用到了其中的两个特权级别,分别为“特权级0”和“特权级3”,级别0也就是我们通常所讲的内核模式,级别3也就是我们通常所讲的用户模式。划分这两个级别主要是对系统提供保护。内核模式可以执行一些特权指令和进入用户模式,而用户模式则不能。这里特别提出的是,内核模式与用户模式分别使用自己的堆栈,当发生模式切换的时候同时要进行堆栈的切换。,1、初始化系统调用,六、Linux系统调用,每个进程都有自己的地址空间(也称为进程空间),进程的地址空间也分为两部分:用户空间和系统空间,在用户模式下只能访问进程的用户空间,在内核模式下则可以访问进程的全部地址空间,这个地址空间里的地址是一个逻辑地址,通过系统段面式的管理机制,访问的实际内存要做二级地址转换,即:逻辑地址/线性地址/物理地址。系统调用对于内核来说就相当于函数,关键问题是从用户模式到内核模式的转换、堆栈的切换以及参数的传递。,1、初始化系统调用,六、Linux系统调用,内核在初始化期间会调用traps.c文件中的trap_init()函数建立IDT表;该函数又会调用set_system_gate(SYSCALL_VECTOR,&system_call)函数来建立对应表项。段选择内核代码段_KERNEL_CS;根据偏移量指向arch/x86/kernel/entry.S文件中的system_call汇编代码段。,1、初始化系统调用,六、Linux系统调用,这个函数位于arch/x86/kernel/entry.S文件中,system_call汇编代码段运行于系统核心态,对系统调用进行预处理,并调用相应的服务例程进行处理,其主要工作如下:使用SAVA_ALL宏将要用到的所有寄存器保存到栈中;通过

    注意事项

    本文(嵌入式操作系统cha.ppt)为本站会员(小飞机)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开