嵌入式系统中断课件

上传人:阳*** 文档编号:84634556 上传时间:2022-05-04 格式:PPT 页数:51 大小:261.50KB
收藏 版权申诉 举报 下载
嵌入式系统中断课件_第1页
第1页 / 共51页
嵌入式系统中断课件_第2页
第2页 / 共51页
嵌入式系统中断课件_第3页
第3页 / 共51页
资源描述:

《嵌入式系统中断课件》由会员分享,可在线阅读,更多相关《嵌入式系统中断课件(51页珍藏版)》请在装配图网上搜索。

1、嵌入式系统中断 中断与异常中断与异常嵌入式系统中断主要内容n 中断的基本知识n 中断描述符表的初始化n 中断处理n 中断的下半部处理机制n 中断的应用时钟中断嵌入式系统中断中断的基本概念n 硬中断的概念硬中断即和硬件相关的中断也就是通常意义上的“中断处理程序”,它是直接处理由硬件发过来的中断信号的。n 中断执行的过程当某个设备发出中断请求时,CPU停止正在执行的指令, 转而跳到包括中断处理代码或者包括指 向中断处理代码的转移指令所在的内存区域。这些代码一般在CP U的中断方式下运 行。就回去自己驱动的设备上去看看设备的状态寄存器以了 解发生了什么事情,并进行相应的操作。当中断处理完毕以后,CP

2、U将恢复到以前的状态,继续执行中断处理前正在执行的指令。嵌入式系统中断n中断的流程如图ni8259.c负责对外部中断的支持。8259芯片负责接收外部设备如定时器、键盘、声卡等的中断,两块8259共支持16个中断 嵌入式系统中断嵌入式系统中断Linux 中断处理特色n分 为上半部和下半部执行n上 半部屏蔽所有中断n下 半部允许中断,执行几乎所有中断嵌入式系统中断n中断控中断控 制的主要优点:制的主要优点: CPU只只 有在有在I/O需要服务时才响应需要服务时才响应n外部中断:外部中断: 外部外部 设备所发出的设备所发出的I/O请求请求n内部内部 中断:中断: 也称之为也称之为“异常异常”,是为解

3、决机器运,是为解决机器运行时所出现的某些随机事件及编程方行时所出现的某些随机事件及编程方便而出现的便而出现的中断常识中断常识嵌入式系统中断n中断向量中断向量 :中 断源的编号n外设可屏蔽中断:外设可屏蔽中断:屏蔽外 部I/O请求 n异常及非异常及非 屏蔽中断屏蔽中断 :CPU内部中断或计算机内部硬件出错引起的异 常n中断描述符表中断描述符表 :描述 中断的相关信息n中断的中断的 相相 关汇关汇 编指令编指令 :嵌入式系统中断n中断中断 向量:向量: 每个中 断源都被分配一个8位无符号整数作为类型码,即中断向量n中断的种类:中断的种类:中断:n外部 可屏蔽中断n外部非 屏蔽中断异常:不 使用中断

4、控制器,不能被屏蔽n故 障n陷 阱中断向量中断源的类型中断向量中断源的类型嵌入式系统中断nIntel x86通过两片中断控制器8259A来响应15个外中断源,每个8259A可管理8个中断源。n外部设备拥有相应权限时 ,可以向特定的中断线发送中断请求信号n外部I/O请求的屏蔽:从CPU的角度, 清除eflag的中断标志位从中断控制器的角度,将中断屏蔽寄存器的相应位置位外设可屏蔽中断外设可屏蔽中断嵌入式系统中断n 异常就是CPU内部出现的中断,即在CPU执行特定指令时出现的非法情况。n非屏蔽 中断就是 计算机内部硬件出错时引起的异常情况 nIntel把非屏蔽中断作为一种异常来处理n在CPU执行一个

5、 异常处理程序时,就不再为其他异 常或可屏蔽中断请求服务 异常及非屏蔽中断 嵌入式系统中断 中断的相关数据结构 n从数据结 构入手,应该说 是分析操作系统源码最常用的和最主要的方法。因为操 作系统的几 大功能部件,如进程管理、 设备管 理、内存 管理等, 都可以通过对其相应的数据结 构的分析来弄懂 其实现机制。 很好的掌握这种方法, 对分析Linux内核大有帮助。n中断向量在保护模式下的实现机制是中断描述符表 (Interrupt Descriptor Table, IDT),中断描述符表的结构如图3.4所示。中断描述符 表即中断向量表相当于一个数组,包含256个中断描述符,每个中断描述符8位

6、,对应硬件提供的256个中断服务 例程的入口,即256个中断向量。IDT的位置由idtr确定,idtr是个48位的寄存器,高32位是IDT的基址,低16位为IDT的界限(通常为2k=256*8)。 嵌入式系统中断中断的相关数据结构n图 3.4 Linux 的中断处理数据结构 嵌入式系统中断中断的相关数据结构n在 i386 系统中,Linux 启动时要设置系统的中断描述符表IDT。IDT 中包含各个中断(以及异常,诸如浮点运算溢出)的服务程序地址,中断服务程序地址由 Linux 提供。每个设备驱动程序可以在图 3.4 所示的结构(irq_action)中注册自己的中断及中断处理程序地址。Linu

7、x 的中断服务程序根据 irq_action 中的注册信息调用相应的设备驱动程序的中断处理程序。和硬件相关的中断处理代码隐藏在中断服务程序中,这样,设备驱动程序的中断处理程序可在不同平台之间 方便移植。一般来说,CPU 在处理中断时,首先要在堆栈中保存与 CPU 指令执行相关的寄存器(例如指令计数 寄存器),然后调用中断服务程序,中断服务程序结束时 再恢复这些寄存器。嵌入式系统中断 中断的相关数据结构nirq_action 实际是一个数组,其中包含指向 irqaction 的指针,每个数组元素分别定义一个 IRQ。Linux 内核提供相应的操作函数,设备驱动程序可调用这些操作函数设置相应的中断

8、处理函数。一般在系统启动时,由各个设备驱动程序通过如下途径获取相关的设备 IRQ 并设置对应的 irq_action 数组元素所指向的 irqaction 结构。n由于0-31号中断向量已被Intel保留,就剩下32-255共224个中断向量可用。在Linux中,这224个中断向量除了0 x80 (SYSCALL_VECTOR)用作系统调用总入口之外,其它都用在外部硬件中断源(包括可编程中断控制器8259A的15个irq)上。实际上,当没有定义CONFIG_X86_IO_APIC时,其它223(除0 x80外)个中断向量,只利用了从32号开始的15个,其它208个空着未用。这些中断服务程序入口

9、的设置将在下面详细说明。n与硬中断相关数据结构主要有三个, 三者关系如图3.5所示。 嵌入式系统中断3.2.2 中断的相关数据结构n图3.5 与硬中断相关的几个数据结构的关系 嵌入式系统中断中断的相关数据结构n (1) 定义在/arch/i386/Kernel/irq.h中的struct hw_interrupt_type数据结构,它是一个抽象的中 断控制器。这包含一系列的指向函数的指针,这些函数处理控制器 特有的操作:ntypename:控制器的名字。 nstartup:允许从给定 的控制器的IRQ所产生的事件。 nshutdown:禁止从给 定的控制器的IRQ所产生的事件。 nhandle

10、:根据提供 给该函数的IRQ,处理唯一的中断。 nenable和disable:这两个函数基本上和startup和shutdown相同; nstruct hw_interrupt_type nconst char * typename; nvoid (*startup)(unsigned int irq); nvoid (*shutdown)(unsigned int irq); nvoid (*handle)(unsigned int irq, struct pt_regs * regs); nvoid (*enable)(unsigned int irq); nvoid (*disable

11、)(unsigned int irq); n; 嵌入式系统中断 中断的相关数据结构n(2) 定义在/arch/i386/Kernel/irq.h中的另外一个数据结构是irq_desc_t,它具有如下成员: nstatus:一个整数。代表IRQ的状态:IRQ是否被禁止了,有关IRQ的设备当前是否正被自动检测,等等。 nhandler:指向hw_interrupt_type的指针。 naction:指向irqaction结构组成的队列的头。正常情况下每个IRQ只有一个操作,因此链接列表的正常长度是1(或者0)。但是,如果IRQ被两个或者多个设备所共享,那么这个队列中就有多个操作。 ndepth:i

12、rq_desc_t的当前用户的个数。主要是用来保证在中断处理过程中IRQ不会被禁止。嵌入式系统中断中断的相关数据结构nirq_desc是irq_desc_t 类型 的数组。对于每一个IRQ都有一个数组入口,即数组把每一个IRQ映射 到和它相关的处理程序和irq_desc_t中的其它信息。 typedef struct unsigned int status; / IRQ status - IRQ_INPROGRESS, IRQ_DISABLED struct hw_interrupt_type *handler; / handle/enable/disable functions struct

13、 irqaction *action; / IRQ action list unsigned int depth; / Disable depth for nested irq disables irq_desc_t; 嵌入式系统中断中断的相关数据结构n(3) 定义在include/linux/ interrupt.h中的struct irqaction数据结构包含了内核接收到特定IRQ之后应采取的操作,其成员如下:nhandler:是一指向某个函数的指针。该函数就是所在结构对相应中断的处理函数。 nflags:取值只有SA_INTERRUPT(中断可嵌套),SA_SAMPLE_RANDOM(

14、这个中断是源于物理随机性的),和SA_SHIRQ(这个IRQ和其它struct irqaction共享)。 nmask:在x86或者体系结构无关的代码中不会使用(除非将其设置为0);只有在SPARC64的移植版本中要跟踪有关软盘的信息时才会使用它。 nname:产生中断的硬件设备的名字。因为不止一个硬件可以共享一个IRQ。 ndev_id:标识硬件类型的一个唯一的ID。Linux支持的所有硬件设备的每一种类型,都有一个由制造厂商定义的在此成员中记录的设备ID。 nnext:如果IRQ是共享的,那么这就是指向队列中下一个struct irqaction结构的指针。通常情况下,IRQ不是共享的,因

15、此这个成员就为空。 嵌入式系统中断中断的相关数据结构nstruct irqaction nvoid (*handler)(int, void *, struct pt_regs *); nunsigned long flags; nunsigned long mask; nconst char *name; nvoid *dev_id; nstruct irqaction *next; n;嵌入式系统中断n中断和异常的 硬件处理 :从硬件的角从硬件的角 度看度看CPU如何处理中断和异常如何处理中断和异常n中断请求队列 的建立:方便外设共方便外设共 享中断线享中断线 n中断处理程序的执行 n从中

16、断返回:调用恢复中断现场的宏调用恢复中断现场的宏RESTORE_ALL,彻底从,彻底从中断返回中断返回 中断处理中断处理 嵌入式系统中断n当CPU执行了当前指令之后,CS和EIP这对寄存器中所包含的内容就是下一条将要执行指令的虚地址。n在对下一条指令执行前,CPU先要判断在执行当前指令的过程中是否发生了中断或异常。n如果发生了一个中断或异常,那么CPU将做以下事情 :中断和异常的硬件处理中断和异常的硬件处理 嵌入式系统中断n确定所发生中断或异常的向量i(在0255之间) n通过IDTR寄存器找到IDT表,读取IDT表第i项(或叫第i个门) n分“段”级、“门”级两步进行有效性检查 n检查是否发

17、生了特权级的变化 中断和异常处理中中断和异常处理中CPUCPU的工作的工作SSESPEFLAGSCSEIPERROR CODEEFLAGSCSEIPERROR CODE堆栈增长方向中断发生前夕的SS:ESP返回地址错误码中断处理程序堆栈嵌入式系统中断n由于硬件 条件的限制,很多硬件设备共享一条中断线n为方便处理,Linux为每条中断线设置了一个 中断请求队列n中断服务例程 与中断处理程序n中断线共享的数据结构n注册中断服务例程中断请求队列的建立中断请求队列的建立嵌入式系统中断n中断服务例程(Interrupt Service Routine ):每个中断请求都有自己单独的中断服务例程n中断处理

18、程序:共享同一条中断线的所有中断请求有一个总的中断处理程序n在Linux中,15条中断线对应15个中断处理程序中断服务例程与中断处理程序中断服务例程与中断处理程序 嵌入式系统中断struct irqaction void (*handler)(int, void *, struct pt_regs *); unsigned long flags; unsigned long mask; const char *name; void *dev_id; struct irqaction *next; ; nHandler:指向一个具体I/O设备的中断服务例程nFlags:用一组标志描述中断线与I/

19、O设备之间的关系。nSA_INTERRUPT:中断处理程序执行时必须禁止中断nSA_SHIRQ:允许其它设备共享这条中断线。中断线共享的数据结构中断线共享的数据结构 嵌入式系统中断struct irqaction void (*handler)(int, void *, struct pt_regs *); unsigned long flags; unsigned long mask; const char *name; void *dev_id; struct irqaction *next; ; SA_SAMPLE_RANDOMSA_SAMPLE_RANDOM:内核可以用它做随机数产生器

20、。 SA_PROBESA_PROBE:内核正在使用这条中断线进行硬件设备探测。 NameName:I/O设备名 dev_iddev_id:指定I/O设备的主设备号和次设备号(参见第9章)。 NextNext:指向irqaction描述符链表的下一个元素 中断线共享的数据结构中断线共享的数据结构 嵌入式系统中断n初始化IDT表之后,必须通过 request_irq() 函数将相应的中断服务例程挂入中断请求队列,即对其进行注册 n在关闭设备时,必须通过调用free_irq()函数释放所申请的中断请求号 注册中断服务例程注册中断服务例程 int request_irq(unsigned int ir

21、q, void (*handler)(int, void *, struct pt_regs *),unsigned long irqflags, const char * devname,void *dev_id)嵌入式系统中断nCPU从中断 控制器的一个端口取得中断向量I n根据I从中断 描述符表IDT中找到相应的中断门n从中断门获 得中断处理程序的入口地址 n 判断是否要 进行堆栈切换n调用do_IRQ ()对所接收的中断进行应答 ,并禁止这条中断线n调用handle_IRQ_event()来运行对应的中断服务例程 中断处理程序的执行中断处理程序的执行 嵌入式系统中断n当处理所有外设中断

22、请求的函数do_IRQ()执行时,内核栈顶包含的就是do_IRQ()的返回地址,这个地址指向ret_from_intr n从中断返回时, CPU要调用恢复中断现场的宏 RESTORE_ALL,彻底从中断返回。 从中断返回从中断返回 嵌入式系统中断n中断服务例程在中断请求关闭的条中断服务例程在中断请求关闭的条件下执行件下执行, ,避免嵌套使中断控制复避免嵌套使中断控制复杂化杂化 n系统不能长时间关中断运行,因此系统不能长时间关中断运行,因此内核应尽可能快的处理完中断请求,内核应尽可能快的处理完中断请求,尽其所能把更多的处理向后推迟尽其所能把更多的处理向后推迟n内核把中断处理分为两部分:内核把中断

23、处理分为两部分:上半上半部(部(top halftop half)和下半部()和下半部(bottom bottom halfhalf),上半部内核立即执行,而),上半部内核立即执行,而下半部留着稍后处理下半部留着稍后处理 中断的下半部处理机制 嵌入式系统中断n中断描述符表(中断描述符表(IDT):即中断向量表,):即中断向量表,每个中断占据一个表项每个中断占据一个表项中断描述符表中断描述符表嵌入式系统中断n调用过程指令CALL : CALL 过程名过程名n调用中断过程的指令INT INT 中断向量中断向量 n中断返回指 令IRETIRET n加载中断描述符表的指令LIDT LIDT 48位的伪

24、描述符位的伪描述符 相关汇编指令相关汇编指令 嵌入式系统中断n Linux内核在系统的初始化阶段要初始化可编程控制器8259A;将中断描述符表的起始地址装入IDTR寄存器,并初始化表中的每一项 n当计算机运行在实模式时,中断描述符表被初始化, 并由BIOS使用 。n真正进入了Linux内核,中断描述符表就被移到内存的另一个区域, 并为进入保护模式进行预初始化 初始化中断描述符表初始化中断描述符表嵌入式系统中断nIDT表项的设置通过_set_gaet()函数实现 n调用该函数在IDT表中插入一个中断门:set_intr_gate(unsigned int n, void *addr) n调用该函

25、数在IDT表中插入一个陷阱门:set_trap_gate(unsigned int n, void *addr) n调用该函数在IDT表中插入一个系统门:set_system_gate(unsigned int n, void *addr) IDT表项的设置表项的设置嵌入式系统中断ntrap_init()函数用 于设置中断描述符表开头的19个陷阱 门和系统门n这些中断向量都 是CPU保留用于异常处理的 ,例:nset_trap_gate(0,÷_error); set_trap_gate(1,&debug); set_trap_gate(19,&simd_coprocessor_e

26、rror); set_system_gate(SYSCALL_VECTOR,&system_call); 初始化陷阱门和系统门初始化陷阱门和系统门嵌入式系统中断n中断门的设置是由init_IRQ( )函数中的一段代码完成的 :n设置时必须跳过用于系统调用的向量0 x80 n中断处理程序的入口地址是一个数组interrupt,数组中的每个元素是指向中断处理函数的指针。 中断门的设置中断门的设置 for (i = 0; i NR_IRQS; i+) int vector = FIRST_EXTERNAL_VECTOR + i; if (vector != SYSCALL_VECTOR) set_i

27、ntr_gate(vector, interrupti); 嵌入式系统中断n小任务是指待处理的下半部,其数据结构为tasklet_struct,每个结构代表一个独立的小任务 n小任务既可以静态地创建,也可以动态地创建 小任务机制小任务机制 struct tasklet_struct Struct tasklet_struct *next;unsigned long state; atomic_t count; void (*func) (unsigned long);unsigned long data; ; 嵌入式系统中断nvoid tasklet_handler(unsigned long

28、 data)n小任务不能睡眠,不能在小任务中使用信号量或者其它产生阻塞的函数。但它运行时可以响应中断 n通过调用tasklet_schedule()函数并传递给它相应的tasklet_struct指针,该小任务就会被调度以便适当的时候执行:tasklet_schedule(&my_tasklet) n在小任务被调度以后,只要有机会它就会尽可能早的运行 编写并调度自己的小任务编写并调度自己的小任务嵌入式系统中断n下半部是一个不能与其他下半部并发执行的高优先级小任务n bh_base是一个指向下半部的指针数组,用于组织 所有下半部n bh_base数组共有32项,每一项都是一种下半部下半部下半部

29、下半部外部设备TIMER_BH 定时器T Q U E U E _ B H 周期性任务队列S E R I A L _ B H 串行端口IMMEDIATE_BH 立即任务队列Linux常用的下半部嵌入式系统中断n任务队列就是指以双向队列形式连接起来的任务链表,每一个链表元素都描述了一个可执行的内核任务 n三个特殊的任务队列:tq _immediatetq _immediate任务队列任务队列,由IMMEDIATE_BH下半部运行,该队列中包括要执行的内核函数和标准的下半部。 tq_timertq_timer任务队列任务队列,由TQUEUE_BH下半部运行,每次时钟中断都激活这个下半部。tq_dis

30、ktq_disk任务队列任务队列,用于块设备任务。任务队列任务队列 嵌入式系统中断n大部分PC机中有两个时钟源,分别是实时实时时钟(时钟(RTCRTC)和和 操作系统(操作系统(OSOS)时钟)时钟n实时时钟也叫硬件时钟,它靠电池供电,即使系统断电,也可以维持日期和时间。nRTC和OS时钟之间的关系通常也被称作操作系统的时钟运作机制 n不同的操作系统,其时钟运作机制也不同 中断的应用时钟中断中断的应用时钟中断 嵌入式系统中断时钟运作机制嵌入式系统中断nOS时钟是由可编程定时/计数器产生的输出脉冲触发中断而产生的n操作系统的“时间基准” 由设计者决定,Linux的时间基准是1970年1月1日凌晨

31、0点n OS时钟记录的时间就是系统时间。系统 时间以“时钟节拍”为单位nLinux中用全局变量jiffiesjiffies表示系统自启动以来的时钟节拍数目 LinuxLinux时间系统时间系统 嵌入式系统中断n每一次时钟中断的产生都触发下列几个每一次时钟中断的产生都触发下列几个主要的操作:主要的操作:自系统启动以来所花费的时间自系统启动以来所花费的时间更新时间和日期更新时间和日期 确定当前进程在确定当前进程在CPU 上已运行了多长时上已运行了多长时 间,如果已经超过了分配给它的时间,则抢间,如果已经超过了分配给它的时间,则抢占它占它 更新资源使用统计数更新资源使用统计数 检查定时器时间间隔是否

32、已到,如果是,检查定时器时间间隔是否已到,如果是, 则调用适当的函数则调用适当的函数 时钟中断处理程序时钟中断处理程序 嵌入式系统中断ntimer_bh( )函数与TIMER_BH 下半部相关联,它在每个时钟节拍都被激活 nTIMER_BH 下半部以关中断调用update_times( )函数,该函数会以关中断来更新xtime n更新了系统时钟xtime之后,update_times( )再次打开中断时钟中断的下半部处理时钟中断的下半部处理 嵌入式系统中断n定时器是管理内核所花时间的基础,也被称为动态定时器或内核定时器 n定时器的使用:执行一些初始化工作,设置一个到期时间,指定到时后执行的函数

33、,然后激活定时器就可以了n定时器由timer_list结构表示 定时器及应用定时器及应用 struct timer_list struct list_head entry; unsigned long expires; unsigned long data; void (*function)(unsigned long); ; 嵌入式系统中断n定义定时器:struct timer_list my_timer; n初始化定时器:init_timer(&my_timer); n激活定时器:add_timer(&my_timer);n如果需要在定时器到期前停止定时器,可以使用del_timer()函

34、数:del_timer(&my_timer);定时器的使用定时器的使用嵌入式系统中断n内核在时钟中断发生后执行定时器,定时器在下半部中被run_timer_list( )执行 n 定时器的使用:例:创建和使用进程延时定时器的执行与应用定时器的执行与应用嵌入式系统中断timeout = 2 * HZ; /*1HZ等于100,因此为2000ms*/set_current_state(TASK_INTERRUPTIBLE); remaining = schedule_timeout(timeout); 内核用定时器实现进程的延时,调用schedule_timeout( )函数,该函数执行下列语句:s

35、truct timer_list timer;expire = timeout + jiffies; init_timer(&timer); timer.expires = expire; timer.data = (unsigned long) current; timer.function = process_timeout; add_timer(&timer); schedule( ); /* 进程被挂起直到定时器到期 */ del_timer_sync(&timer); timeout = expire - jiffies; return (timeout 0 ? 0 : timeout); 当延时到期时,内核执行下列函数:void process_timeout(unsigned long data) struct task_struct * p = (struct task_struct *) data; wake_up_process(p);

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!