中断原理和中断类别
时间:2010-12-21 来源:cjjnjust
中断是指CPU运行过程中,外设遇到紧急的事物要处理,使得CPU暂停当前指令的执行转去执行中断指令,执行完中断服务程序后又回到当前的指令继续执行。
中断可以分为硬中断和软中断 硬中断是指CPU外设对CPU产生中断。 软中断是指应用程序产生异常,或者人为的产生中断,它是对内核进行中断。
对控制器来说,中断源很多,必须有一个中断控制器来管理这些中断。INTEL8259就是一个典型的中断控制器。
INTEL 中断向量共有256种,分为异常和中断,异常是不可以屏蔽的,也不使用中断控制器。而外设中断是可以通过中断控制器的编程来实现屏蔽的。 LINUX中256个中断向量的分配: 0-31: 异常 32-47:IO设备 48-255:用向量来标识的软中断,LINUX用其中一个来实现系统调用。
8259A 可以控制8个外设中断源。
中断向量表的起始位置 实模式下 0-1K 保护模式 放在IDTR中断描述符寄存器。
相关命令 CALL 调用过程指令 INT 调用中断过程的指令 IRET 中断返回指令 LIDT 加载中断描述表的指令
IDT表项的设置
set_intr_gate set_trap_gate set_system_gate
外部中断的设置
用户态发生中断,而中断处理程序在内核态,那么需要将用户态的堆栈指针进行压栈。
Linux中的中断描述表 struct iqr_desc_t irq_desc[NR_IRQS]. irq_desc_t结构体中的成员action指向该中断号对应的irqaction结构体链表。
中断处理程序和中断服务例程 中断处理程序:IRQ0X**_interrupt(). 相当于某个中断向量的总服务程序。每一个中断线对应一个中断向量。 为了让多个设备共享一个中断线。内核设置了一个IRQACTION的数据结构。 Struct { void (*handler) (int, void*, struct pt_regs *); unsigned long flags; unsigned long mask; unsigned char *name; void *dev_id; struct irqaction *next; }; 每一个handler就是一个中断服务例程,
在驱动初始化的时候,若使用到了中断,通常要用request_irq建立一个中断服务例程。即申请一个irqaction的结构体。并把它挂载到irq_desc[irq_num]->action链表的下面。这样CPU接收到中断请求后,就可以在irq_desc[]找到该设备的中断服务程序。 IRQn_interrupt()->do_IRQ()->handler_IRQ_event()->action->handler();
do_IRQ->handle_IRQ_event do{ status |= action->flags; action ->handler(irq, action->dev_id, regs); action = action->next; }while(action);
中断可以分为硬中断和软中断 硬中断是指CPU外设对CPU产生中断。 软中断是指应用程序产生异常,或者人为的产生中断,它是对内核进行中断。
对控制器来说,中断源很多,必须有一个中断控制器来管理这些中断。INTEL8259就是一个典型的中断控制器。
INTEL 中断向量共有256种,分为异常和中断,异常是不可以屏蔽的,也不使用中断控制器。而外设中断是可以通过中断控制器的编程来实现屏蔽的。 LINUX中256个中断向量的分配: 0-31: 异常 32-47:IO设备 48-255:用向量来标识的软中断,LINUX用其中一个来实现系统调用。
8259A 可以控制8个外设中断源。
中断向量表的起始位置 实模式下 0-1K 保护模式 放在IDTR中断描述符寄存器。
相关命令 CALL 调用过程指令 INT 调用中断过程的指令 IRET 中断返回指令 LIDT 加载中断描述表的指令
IDT表项的设置
set_intr_gate set_trap_gate set_system_gate
外部中断的设置
for(i = 0; i < NR_IRQS; i++){ |
用户态发生中断,而中断处理程序在内核态,那么需要将用户态的堆栈指针进行压栈。
Linux中的中断描述表 struct iqr_desc_t irq_desc[NR_IRQS]. irq_desc_t结构体中的成员action指向该中断号对应的irqaction结构体链表。
中断处理程序和中断服务例程 中断处理程序:IRQ0X**_interrupt(). 相当于某个中断向量的总服务程序。每一个中断线对应一个中断向量。 为了让多个设备共享一个中断线。内核设置了一个IRQACTION的数据结构。 Struct { void (*handler) (int, void*, struct pt_regs *); unsigned long flags; unsigned long mask; unsigned char *name; void *dev_id; struct irqaction *next; }; 每一个handler就是一个中断服务例程,
在驱动初始化的时候,若使用到了中断,通常要用request_irq建立一个中断服务例程。即申请一个irqaction的结构体。并把它挂载到irq_desc[irq_num]->action链表的下面。这样CPU接收到中断请求后,就可以在irq_desc[]找到该设备的中断服务程序。 IRQn_interrupt()->do_IRQ()->handler_IRQ_event()->action->handler();
do_IRQ->handle_IRQ_event do{ status |= action->flags; action ->handler(irq, action->dev_id, regs); action = action->next; }while(action);
相关阅读 更多 +