精华内容
下载资源
问答
  • Linux中断知识汇总: 【深入理解Linux内核】【中断】内容...产生中断的每一个设备都一个相应的中断处理程序。中断处理程序是被内核调用来响应中断的,他们运行于中断上下文中,该上下文中的代码不可阻塞。 我们一.

    Linux中断知识汇总:

    【深入理解Linux内核】【中断】内容汇总帖


    目录

    什么是中断处理程序?

    注册中断处理程序

    编写中断处理程序

    编写中断处理程序的注意事项

    为什么在中断里不可以睡眠?

    为什么在中断里不可以使用耗时很长的函数?


    什么是中断处理程序?

    中断处理程序:在响应一个特定中断的时候,内核会执行一个函数,该函数叫做中断处理程序。产生中断的每一个设备都有一个相应的中断处理程序。中断处理程序是被内核调用来响应中断的,他们运行于中断上下文中,该上下文中的代码不可阻塞。

    我们一般把中断处理分为两个部分。中断处理程序是上半部——接收到一个中断就立即开始执行,通常用于做有严格时限的工作。能够被允许稍后运行的工作会被推迟到下半部去。此后在合适的时机,下半部会被运行。


    注册中断处理程序

    int request_irq(unsigned int irq, irq_handler_t handler,unsigned long irqflags, const char *devname, void *dev_id)
    
    具体说明:
    irq是要申请的硬件中断号。
    handler是向系统注册的中断处理函数,是一个回调函数,中断发生时,系统调用这个函数,dev_id参数将被传递给它。
    irqflags是中断处理的属性:
        若设置了IRQF_DISABLED (老版本中的SA_INTERRUPT,本版zhon已经不支持了),则表示中断处理程序是 快速处理程序,快速处理程序被调用时屏蔽所有中断,慢速处理程序不屏蔽;
        若设置了IRQF_SHARED (老版本中的SA_SHIRQ),则表示多个设备共享中断;
        若设置了IRQF_SAMPLE_RANDOM(老版本中的SA_SAMPLE_RANDOM),表示对系统熵有贡献,对系统获取随机数有好处。(这几个flag是可以通过或的方式同时使用的)
    devname设置中断名称,通常是设备驱动程序的名称  在cat /proc/interrupts中可以看到此名称。
    dev_id在中断共享时会用到,一般设置为这个设备的设备结构体或者NULL。

    编写中断处理程序

    static inqreturn_t intr_handler(int irq, void *dev)
    
    
    具体说明:
    第一个参数irq就是这个处理程序要响应的中断号。如今这个参数已经没什么用了,可能只是在打印日志信息时会用到。
    第二个参数dev是一个通用指针,它在与中断处理程序注册时传递给request_irq的产生dev必须一致。dev可能指向中断处理程序使用的一个数据结构。
    中断处理程序可能返回两个特殊的值:IRQ_NONE和IRQ_HANDLED。当不是在注册处理函数期间产生源,返回IRQ_NONE。当中断处理程序被正确调用,且确实是它所对应的设备产生了中断时,返回IRQ_HALDLED。
    linux下的中断处理函数无需考虑重入,默认中断嵌套功能是不开启的。

    编写中断处理程序的注意事项

    • 不可以执行耗时的任务】代码执行效率尽量高,代码一定要简洁,尽量少调用其他函数,尽量避免增加中断的执行时长,中断处理需要快进快出。
      1. 不可以使用耗时很长的函数,因为中断会关闭调度,中断的优先级高于任何任务的优先级,长时间的中断处理会影响到系统的响应速度,使整个系统的任务无法政策运行,造成很多的任务超时,容易导致很多不可预知的后果。【可以使用中断底半部解决】
      2. 对于一些必须的操作可以放在中断中处理,其他的以异步执行的方式,放到中断底半部中解决。
    • 不可以睡眠或者放弃CPU】中断处理程序中不可以睡眠,不可以使用可能引起睡眠的函数,也不可以使用可能会引起睡眠的锁。
      1. 不可以使用metux等引起休眠的锁。可以使用自旋锁,但必须保证自旋等待时间足够短。【可以使用自旋锁解决】
      2. 不可以使用会引起休眠的函数。比如ssleep(), msleep(), kmalloc, copy_to_user(), copy_from_user() 等。
    • 中断是不可重入函数】同一时刻同一中断只能在一个CPU上被触发,中断被响应后会被关闭该中断,相同的中断处理函数不能同时在多个处理器上运行。


    为什么在中断里不可以睡眠?

    从系统调度的角度来说,调度的触发方式有几种(主动触发、睡眠、唤醒、中断退出时的判断),而在进入中断之前,系统调度会被关闭。在调度函数schedule()中,也会首先判断是否在中断上下文,如果是则直接退出。此时一旦睡眠或者放弃CPU,这时内核无法调度别的进程来执行,系统就会死掉。


    为什么在中断里不可以使用耗时很长的函数?

    因为中断会关闭调度,中断的优先级高于任何任务的优先级,长时间的中断处理会影响到系统的响应速度,使整个系统的任务无法政策运行,造成很多的任务超时,容易导致很多不可预知的后果。【可以使用中断底半部解决】

     

    展开全文
  • 中断处理

    2017-11-09 12:02:00
    概述 ...什么时候采用中断中断服务处理多大。通常中断处理尽可能短。 事件要如何通知到主程序,这些代码要如何架构才能最好适应异步处理。  FreeRTOS提供一系列特性使开发者策略得...

    概述

      嵌入式系统需要对整个系统的环境产生的事情做出反应。比如以太网外围部件收到一个数据包。各种源头产生的事件。我们需要考虑的是

    1. 事件如何被检测,通常采用中断。事件输入也可以通过查询获得。
    2. 什么时候采用中断,中断服务处理量有多大。通常中断中处理尽可能短。
    3. 事件要如何通知到主程序,这些代码要如何架构才能最好适应异步处理。

      FreeRTOS提供一系列特性使开发者策略得以实现。(只有以FromISR 或者 FROM_ISR 结束的API或宏才可以在中断服务程序中使用)。

    延迟中断处理

      二值信号量和计数信号量可以让某个特殊的中断发生时,让任务解除阻塞。中断只做快速处理少部分工作。中断处理可以说呗推迟到一个“处理任务中”。中断中抛出信号,处理任务则在阻塞等待信号,当信号到来,阻塞等待任务解除阻塞。

      void vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore ); //create binary semaphore

      portBASE_TYPE xSemaphoreTake( xSemaphoreHandle xSemaphore, portTickType xTicksToWait ); //take a semaphore

      portBASE_TYPE xSemaphoreGiveFromISR( xSemaphoreHandle xSemaphore,

                                          portBASE_TYPE *pxHigherPriorityTaskWoken );
     这里注意第二个参数  
    pxHigherPriorityTaskWoken 如果调用xSemaphoreTake()函数的处理任务的优先级比当前任务要高,那么这个参数被设置为pdTRUE。中断处理中要做检测这个参数,如果为pdTRUE 则做一次手动任务切换

      

      if( xHigherPriorityTaskWoken == pdTRUE )
      {
    

                 /* 给出信号量以使得等待此信号量的任务解除阻塞。如果解出阻塞的任务的优先级高于当前任务的优先 级 – 强制进行一次任务切换,以确保中断直接返回到解出阻塞的任务(优选级更高)。

            说明:在实际使用中,ISR中强制上下文切换的宏依赖于具体移植。此处调用的是基于Open Watcom DOS 移植的宏。其它平台下的移植可能有不同的语法要求。对于实际使用的平台,请参如数对应移植自带的示 例程序,以决定正确的语法和符号。
            */

              portSWITCH_CONTEXT();
      }

      计数信号和二值信号基本操作相同,唯一不同的是 计数信号的保存多个信号资源,就是说可以多次接收信号。这避免了中断丢失的情况。那么这里有一个问题,信号处理任务检测只要有信号量那么就退出阻塞去做相应处理,

      那么如果有多种信号,我们要如何区分信号的种类呢?

      我们可以将信号量和消息队列结合使用,当数据到来我们将数据做一次封装,将数据和数据种类封装成一个消息队列单元,这个在处理任务做通过判断消息种类就可以知道数据是用作什么处理,


    中断嵌套

      建立一个全面中断嵌套模型需要设置 configMAX_SYSCALL_INTERRUPT_PRIRITY  为比 configKERNEL_INTERRUPT_PRIORITY 更高的优先级。在这之间的优先级的中断会被临界区的应用程序阻塞,但是他们可以调用中断安全版本的FreeRTOS API,在configKERNEL_INTERRUPT_PRIORITY优先级之上的任务无法被临界区阻塞

    转载于:https://www.cnblogs.com/a-lai/p/7808725.html

    展开全文
  • 中断和中断处理

    2017-08-29 14:18:32
    中断和中断处理 任何操作系统内核的核心任务,都包含对连接到计算机上的硬件设备进行有效管理,如硬盘、蓝光碟机、健盘、鼠标、3D处理器,以及无线电等。而想要管理这些设备,首先要能和它们互通音信才行。 ...

    中断和中断处理

    任何操作系统内核的核心任务,都包含有对连接到计算机上的硬件设备进行有效管理,如硬盘、蓝光碟机、健盘、鼠标、3D处理器,以及无线电等。而想要管理这些设备,首先要能和它们互通音信才行。

    两者的速率往往是不匹配的,如果依靠内核去询问会降低性能。所以提出一种让硬件有需要时向内核发出信号,让内核去做处理。该机制称为中断机制。

    中断

    中断使得硬件得以发出通知给处理器。

    从物理学的角度看,中断是一种电信号,由硬件设备生成,并直接送入中断控制器的输入引脚中—中断控制器是个简单的电子芯片,其作用是将多路中断管线,采用复用技术只通过一个和处理器相连接的管线与处理器通信。当接收到一个中断后,中断控制器会给处理器发送一个电信号。处理器一经检测到此信号,便中断自己的当前工作转而处理中断。此后,处理器会通知操作系统已经产生中断,这样,操作系统就可以对这个中断进行适当地处理了。

    不同的设备对应的中断不同,而每个中断都通过一个唯一的数字标志。因此,来自键盘的中断就有别于来自硬盘的中断,从而使得操作系统能够对中断进行区分,并知道哪个硬件设备产生了哪个中断。这样,操作系统才能给不同的中断提供对应的中断处理程序。

    中断值称为中断请求(IRQ)。每个IRQ线和数值相关联。如:IRQ 0是时钟中断。中断一般的动态分配的。

    异常

    基本的判别就是:

    中断是硬件引起,CPU以外的事件引起。异常是软件代码引起。(除0异常 缺页异常 系统调用)。

    中断处理程序

    在响应一个特定中断的时候,内核会执行一个函数,该函数叫做中断处理程序interrupt handler或中断服务例程(interrupt server routine)。产生中断的每个设备都有一个相应的中断处理程序。例如,由一个函数专门处理来自系统时钟的中断,而另外一个函数专门处理由键盘产生的中断。一个设备的中断处理程序是它设备驱动程序(deriver)的一部分—设备驱动程序是用于对设备进行管理的内核代码。

    中断处理程序与其他内核函数的真止区别在于:中断处理程序是被内核调用来响应中断的,而它们运行于我们称之为中断上下文的特殊上下文中中断上下文偶尔也称作原子上下文,因为正如我们看到的,该上下文中的执行代码不可阻塞。

    中断随时可能发生,所以程序也随时可能运行。必须要保证中断是快速执行的,才能快速从中断中恢复。

    上半部与下半部的对比

    中断处理程序既要快速又要处理更多的数据。为了达到这个目的把中断拆分为了两部分。

    • 中断处理程序是上半部分(top half)-接收到中断,他就立即执行。

    • 能够稍微往后执行的会被推迟的到下半部(bottom half).

    让我们考察一下上半部和下半部分割的例子,还是以我们的老朋友—网卡作为实例口当网卡接收来自网络的数据包时,需要通知内核数据包到了。网卡需要立即完成这件事,从而优化网络的吞吐量和传输周期,以避免超时。因此,网卜立即发出中断:晦,内核,我这里有最新数据包。内核通过执行网卡已注册的中断处理程序来做出应答。

    内核负责把数据从网卡的buffer中拷贝到系统内存,中断处理程序完成,至于数据的处理则在下半部分。

    注册中断处理程序

    中断处理程序是管理硬件的驱动程序的组成部分。每一设备都有相关的驱动程序,如果设备使用中断(大部分设备如此),那么相应的驱动程序就注册一个中断处理程序。

    使用 request_irq() 来注册:

    /* request_irq: allocate a given interrupt line */
    int request_irq(unsigned int irq,
                    irq_handler_t handler,
                    unsigned long flags,
                    const char *name,
                    void *dev)
      typedef irqreturn_t (*irq_handler_t)(int, void *);
    • irq:表示要分配的中断号。

    • handler:函数指针,中断处理程序的指针。

    • flags:中断处理标志位,可以为0,也可以为以下一个或者多个掩码。

      • IRQF_DISABLED—内核在处理该中断的时候禁止其他中断。

      • IRQF_SAMPLE_RANDOM——此标志表明这个设备产生的中断对内核墒池有贡献。(未明)

      • IRQF_TIMER——该标志是特别为系统定时器的中断处理而准备的。

      • IRQF_SHARED——·此标志表明可以在多个中断处理程序之间共享中断线。线上注册的每个处理程序必须指定这个标志;否则,在每条线上只能有一个处理程序。

    • name:中断设备的ASCII文本表示。

    • dev:用于共享中断线。当一个中断处理程序需要释放时(稍后讨论),dev将提供唯一的标志信息(} OO}1C,以便从共享中断线的诸多中断处理程序中删除指定的那一个。如果没有这个参数,那么内核不可能知道在给定的中断线上到底要删除哪一个处理程序。如果无须共享中断线,那么将该参数斌为空值(NULL)就可以了,但是,如果中断线是被共享的,那么就必须传递唯一的信息(除非设备又旧又破且位于ISA总线上,那么就必须支持共享中断)。

    request_irq()可能会睡眠。所以不能在中断上下文和不允许阻塞的代码中调用该函数。(因为该函数会调用kmalloc(),而其会睡眠)。

    例子

    request_irq():
    if (request_irq(irqn, my_interrupt, IRQF_SHARED, "my_device", my_dev)) {
        printk(KERN_ERR "my_device: cannot register IRQ %d\n", irqn);
        return -EIO;
    }
    
    void free_irq(unsigned int irq, void *dev)

    编写中断处理程序

    
    static irqreturn_t intr_handler(int irq, void *dev)

    第一个参数是中断号,目前没有多少作用,因为dev出现了。

    第二个参数dev是一个通用指针,它与在中断处理程序注册时传递给request_irq()的参数dev必须一致。如果该值有唯一确定性(这样做是为了能支持共享),那么它就相当于一个cookie,可以用来区分共享同一中断处理程序的多个设备。另外}}Y也可能指向中断处理程序使用的一个数据结构。因为对每个设备而言,设备结构都是唯一的,而且可能在中断处理程序中也用得到,因此,它也通常被看做dev。

    重入和中断处理程序

    中断处理程序不可能重入。因为在处理该程序的时候该中断线上的信号会被屏蔽掉。

    共享的中断处理程序

    共享的处理程序与非共享的处理程序在注册和运行方式上比较相似,但差异主要有以下三处:

    1. request_irq()的flag必须设置为IRQF_SHARED

    2. dev参数必须唯一。

    3. 中断处理程序必须能够知道设备是否真的出现中断。如果硬件不支持这一功能,那中断处理程序肯定会束手无策,它根本没法知道到底是与它对应的设备发出了这个中断,还是共享这条中断线的其他设备发出了这个中断。

    内核接收一个中断后,它将依次调用在该中断线上注册的每一个处理程序。因此,一个处理程序必须知道它是否应该为这个中断负责,如果与它相关的设备并没有产生中断,那么处理程序应该立即退出。这需要硬件设备提供状态寄存器(或类似机制),以便中断处理程序进行检查。毫无疑问,大多数硬件都提供这种功能。

    eg:

    下面是一个实例:real-time clock(RTC)驱动程序。

    
    /* register rtc_interrupt on rtc_irq */
    if (request_irq(rtc_irq, rtc_interrupt, IRQF_SHARED, "rtc", (void *)&rtc_port)) {
          printk(KERN_ERR "rtc: cannot register IRQ %d\n", rtc_irq);
          return -EIO;
    }

    
    static irqreturn_t rtc_interrupt(int irq, void *dev)
    {
        /*
        * Can be an alarm interrupt, update complete interrupt,
        * or a periodic interrupt. We store the status in the
        * low byte and the number of interrupts received since
        * the last read in the remainder of rtc_irq_data.
        */
        spin_lock(&rtc_lock);
        rtc_irq_data += 0x100;
        rtc_irq_data &= ~0xff;
        rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
        //更新状态
        if (rtc_status & RTC_TIMER_ON)
                mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
      
        spin_unlock(&rtc_lock);
        /*
        * Now do the rest of the actions
        */
        spin_lock(&rtc_task_lock);
        if (rtc_callback)
                rtc_callback->func(rtc_callback->private_data);
        spin_unlock(&rtc_task_lock);
      
        wake_up_interruptible(&rtc_wait);
        kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
        return IRQ_HANDLED;
    }

    中断上下文

    在执行一个中断处理程序的时候,内核处于中断上下文中。因为没有后备进程,所以中断上下文不可以睡眠。——不能在一个中断上下文中调用一个会睡眠的函数。

    以前和进程共用内核栈,现在独立出来。栈的大小为一页。

    中断处理机制的实现

    中断从硬件到内核的路由。设备产生中断,通过总线把电信号发送给中断控制器.如果中断线是激活的(‘白们是允许被屏蔽的),那么中断控制器就会把中断发往处理器。在大多数体系结构中,这个工作就是通过电信号给处理器的特定管脚发送一个信号。除非在处理器上禁止该中断,否则,处理器会立即停止它正在做的事,关闭中断系统,然后跳到内存中预定义的位置开始执行那里的代码口这个预定义的位置是由内核设置的,是中断处理程序的入口点。

    对于每条中断线,处理器都会跳到唯一的入口。

    
    unsigned int do_IRQ(struct pt_regs regs)

    计算出中断后,禁止该中断线。

    do_IRQ()需要确保中断线上有一个有效的处理程序。

    
    /**
    * handle_IRQ_event - irq action chain handler
    * @irq: the interrupt number
    * @action: the interrupt action chain for this irq
    *
    * Handles the action chain of an irq event
    */
    irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
    {
        irqreturn_t ret, retval = IRQ_NONE;
        unsigned int status = 0;
      
        if (!(action->flags & IRQF_DISABLED))
            local_irq_enable_in_hardirq();
        do {
          trace_irq_handler_entry(irq, action);
          ret = action->handler(irq, action->dev_id);
          trace_irq_handler_exit(irq, action, ret);
          
        switch (ret) {
          case IRQ_WAKE_THREAD:
          /*
          * Set result to handled so the spurious check
          * does not trigger.
          */
          ret = IRQ_HANDLED;
          /*
          * Catch drivers which return WAKE_THREAD but
          * did not set up a thread function
          */
          if (unlikely(!action->thread_fn)) {
          /*
          * Catch drivers which return WAKE_THREAD but
          * did not set up a thread function
          */
          if (unlikely(!action->thread_fn)) {
          warn_no_thread(irq, action);
          break;
        }
        /*
        * Wake up the handler thread for this
        * action. In case the thread crashed and was
        * killed we just pretend that we handled the
        * interrupt. The hardirq handler above has
        * disabled the device interrupt, so no irq
        * storm is lurking.
        */
        if (likely(!test_bit(IRQTF_DIED,
        &action->thread_flags))) {
        set_bit(IRQTF_RUNTHREAD, &action->thread_flags);
        wake_up_process(action->thread);
        }
        /* Fall through to add to randomness */
        case IRQ_HANDLED:
        status |= action->flags;
        break;
        default:
        break;
        }
        retval |= ret;
        action = action->next;
        } while (action);
        if (status & IRQF_SAMPLE_RANDOM)
        add_interrupt_randomness(irq);
        local_irq_disable();
        return retval;
    }

    First, because the processor disabled interrupts, they are turned back on unlessIRQF_DISABLED was specified during the handler’s registration. Recall that IRQF_DISABLED specifies that the handler must be run with interrupts disabled. Next, each potential handler is executed in a loop. If this line is not shared, the loop terminates after the first iteration. Otherwise, all handlers are executed.After that,add_interrupt_randomness() is called if IRQF_SAMPLE_RANDOM was specified during registration.This function uses the timing of the interrupt to generate entropy for the random number generator. Finally, interrupts are again disabled (do_IRQ() expects them still to be off) and the function returns. Back in do_IRQ(), the function cleans up and returnsto the initial entry point, which then jumps to ret_from_intr().

    /proc/interrupts

    procfs是个虚拟文件系统,只存在于内核中。存放相关interrupt信息。

    1. 中断线。

    2. 中断计数。

    3. 中断控制器。

    4. devname。

    中断控制

    以下一种是中断开关。一种可以存储状态,恢复操作。这是禁止所有的中断。

    
    local_irq_disable();
    /* interrupts are disabled .. */
    local_irq_enable();
    
    unsigned long flags;
    local_irq_save(flags); /* interrupts are now disabled */
    /* ... */
    local_irq_restore(flags); /* interrupts are restored to their previous state */

    控制中断线:

    
    void disable_irq(unsigned int irq);
    void disable_irq_nosync(unsigned int irq);/*不等待*/
    void enable_irq(unsigned int irq);
    void synchronize_irq(unsigned int irq);/*如果正在执行会等待退出*/


    展开全文
  • 中断及中断处理过程

    2020-07-09 10:36:09
    中断和异常的概念区别 Intel的官方文档里将中断和异常理解为两种中断当前程序执行的不同机制。这是中断和异常的共同点。...关于它们的区别两点是需要注意的: 平常所说的屏蔽中断是不包括异常的,即异常不会因

    中断和异常的概念区别

    Intel的官方文档里将中断和异常理解为两种中断当前程序执行的不同机制。这是中断和异常的共同点。不同点在于:

    中断(interrupt)是异步的事件,典型的比如由I/O设备触发;异常(exception)是同步的事件,典型的比如处理器执行某条指令时发现出错了等等。
    中断又可以分为可屏蔽中断和非可屏蔽中断,异常又分为故障、陷阱和异常中止3种,它们的具体区别很多书籍和官方文档都解释的比较清楚这里不再赘述。

    关于它们的区别有两点是需要注意的:

    1. 平常所说的屏蔽中断是不包括异常的,即异常不会因为CPU的IF位被清(关中断,指令:cli)而受影响,比如缺页异常,即使关了中断也会触发CPU的处理。
    2. 通常说的int 80h这种系统调用使用的中断方式实际上硬件上是理解为异常处理的,因此也不会被屏蔽掉,这也很好理解,int 80h这种中断方式是程序里主动触发的,对于CPU来说属于同步事件,因此也就属于异常的范畴。

    中断(异常)处理过程

    需要明确的一点是CPU对于中断和异常的具体处理机制本质上是完全一致的,即:

    当CPU收到中断或者异常的信号时,它会暂停执行当前的程序或任务,通过一定的机制跳转到负责处理这个信号的相关处理程序中,在完成对这个信号的处理后再跳回到刚才被打断的程序或任务中。这里只描述保护模式下的处理过程,搞清楚了保护模式下的处理过程(更复杂),实模式下的处理机制也就容易理解了。
    具体的处理过程如下:
    中断处理过程

    1. 中断响应的事前准备:
      系统要想能够应对各种不同的中断信号,总的来看就是需要知道每种信号应该由哪个中断服务程序负责以及这些中断服务程序具体是如何工作的。系统只有事前对这两件事都知道得很清楚,才能正确地响应各种中断信号和异常。

      1. 系统将所有的中断信号统一进行了编号(一共256个:0~255),这个号称为中断向量,具体哪个中断向量表示哪种中断有的是规定好的,也有的是在给定范围内自行设定的。
        中断向量和中断服务程序的对应关系主要是由IDT(中断向量表)负责。操作系统在IDT中设置好各种中断向量对应的中断描述符(一共有三类中断门描述符:任务门、中断门和陷阱门),留待CPU查询使用。而IDT本身的位置是由idtr保存的,当然这个地址也是由OS填充的。
      2. 中断服务程序具体负责处理中断(异常)的代码是由软件,也就是操作系统实现的,这部分代码属于操作系统内核代码。也就是说从CPU检测中断信号到加载中断服务程序以及从中断服务程序中恢复执行被暂停的程序,这个流程基本上是硬件确定下来的,而具体的中断向量和服务程序的对应关系设置和中断服务程序的内容是由操作系统确定的。
    2. CPU检查是否有中断/异常信号
      CPU在执行完当前程序的每一条指令后,都会去确认在执行刚才的指令过程中中断控制器(如:8259A)是否发送中断请求过来,如果有那么CPU就会在相应的时钟脉冲到来时从总线上读取中断请求对应的中断向量[2]。
      对于异常和系统调用那样的软中断,因为中断向量是直接给出的,所以和通过IRQ(中断请求)线发送的硬件中断请求不同,不会再专门去取其对应的中断向量。

    3. 根据中断向量到IDT表中取得处理这个向量的中断程序的段选择符
      CPU根据得到的中断向量到IDT表里找到该向量对应的中断描述符,中断描述符里保存着中断服务程序的段选择符。

    4. 根据取得的段选择符到GDT中找相应的段描述符
      CPU使用IDT查到的中断服务程序的段选择符从GDT中取得相应的段描述符,段描述符里保存了中断服务程序的段基址和属性信息,此时CPU就得到了中断服务程序的起始地址。

      这里,CPU会根据当前cs寄存器里的CPL和GDT的段描述符的DPL,以确保中断服务程序是高于当前程序的,如果这次中断是编程异常(如:int 80h系统调用),那么还要检查CPL和IDT表中中断描述符的DPL,以保证当前程序有权限使用中断服务程序,这可以避免用户应用程序访问特殊的陷阱门和中断门[3]。

    5. CPU根据特权级的判断设定即将运行的中断服务程序要使用的栈的地址
      CPU会根据CPL和中断服务程序段描述符的DPL信息确认是否发生了特权级的转换,比如当前程序正运行在用户态,而中断程序是运行在内核态的,则意味着发生了特权级的转换,这时CPU会从当前程序的TSS信息(该信息在内存中的首地址存在TR寄存器中)里取得该程序的内核栈地址,即包括ss和esp的值,并立即将系统当前使用的栈切换成新的栈。这个栈就是即将运行的中断服务程序要使用的栈。紧接着就将当前程序使用的ss,esp压到新栈中保存起来。

    6. 保护当前程序的现场
      CPU开始利用栈保护被暂停执行的程序的现场:依次压入当前程序使用的eflags,cs,eip,errorCode(如果是有错误码的异常)信息。

    7. 跳转到中断服务程序的第一条指令开始执行
      CPU利用中断服务程序的段描述符将其第一条指令的地址加载到cs和eip寄存器中,开始执行中断服务程序。这意味着先前的程序被暂停执行,中断服务程序正式开始工作。

    8. 中断服务程序处理完毕,恢复执行先前中断的程序
      在每个中断服务程序的最后,必须有中断完成返回先前程序的指令,这就是iret(或iretd)。程序执行这条返回指令时,会从栈里弹出先前保存的被暂停程序的现场信息,即eflags,cs,eip重新开始执行。

    展开全文
  • 中断 1.计算机处理器的速度和外围硬件设备(例如键盘)的速度往往不在一个数量级上 ...6.响应中断时,内核会执行不同的中断处理程序,中断处理程序是驱动的一部分,驱动也是内核的一部分 7.中断处理程序
  • 时间了,于是试着整理一下linux的中断处理机制,目的是起码从原理上能够说得通。  一、简单的中断机制  简单的中断机制是像芯片手册上讲的那样,在中断向量表中填入跳转到对应处理函数的指令,然后在处理...
  • 笔者在平常的项目开发中,会遇到有些程序执行时间过长的问题(比如查询数据库的时间过长,或者调用某一接口执行的时间过长),导致程序长时间卡死,因此,需要对程序进行超时中断处理,给程序的执行时间设定一个时间...
  • Linux中断处理为什么需要分为上下部分? linux中断处理不参与调度,所以中断处理事件过长会影响实时性; 中断处理函数(ISR)运行事件应尽可能短,但有些处理不可能再很短时间内处理完成,于是linux内核提供中断...
  • 中断处理的基本过程

    千次阅读 2020-03-24 15:07:49
    中断处理的基本过程包括中断请求、中断判优、中断响应、中断服务 和中断返回等五个阶段。 1.中断请求阶段 1)发生在CPU内部的中断(内部中断),不需要中断请求,CPU内部的中断控制逻辑直接接收处理。 2)外部中断...
  • 编写驱动的时候,一个中断产生之后,内核在中断处理函数中可能需要完成很多工作。但是中断处理函数的处理是关闭了中断的。也就是说在响应中断时,系统不能再次响应外部的其它中断。这样的后果会造成可能丢失外部...
  • 任何操作系统内核的核心任务,都包括对硬件设备进行有效的管理。我们知道处理器和硬件的速度不在一个数量级上,当内核向硬件发出请求的时候,...我们可以让硬件需要的时候向内核发送一个通知,这个就是中断机制。 ...
  • 1. 引言对Java中断没有一个全面的了解,可能会误以为被中断的线程将立马退出运行,但事实并非如此...什么情况下需要使用中断?本文将从以上几个方面进行描述。2. 中断的原理Java中断机制是一种协作机制,也就是说通...
  • 硬件处理最近解决一个关于Linux中断的问题,把相关机制整理了一遍,记录在此。不同的外部设备、不同的体系结构、不同的OS其中断实现机制都差别,本文对应的OS为linux3.4版本,外部设备为PCI设备、系统为X86。概览...
  • linux内核中断处理

    2017-10-12 13:48:06
    中断处理一般不是纯软件来实现的,需要硬件的支持。通过对中断的学习助于更深入的了解系统的一些底层原理,特别是驱动程序的开发。 1. 什么是中断 为了提高CPU和外围硬件(硬盘,键盘,鼠标等等)之间协同工作...
  • 中断机制让硬件在需要的时候再向内核发出信号。 7.1中断 概念:使得硬件得以发出通知给处理器 产生时机:随时可以产生,内核随时可能因为新到来的中断而被打断 流程:当接收到一个中断后,中断控制器会给处理器发送...
  • 手册说明 正常的读写DR寄存器都能达到清楚标志的效果.所以除了多缓存通信的情况下,没必要增加清除标志位. 两个清除函数.USART_ClearFlag清除完成标志位 USART_ClearITPendingBit清除中断标志位 据说...
  • 因此需要在异常中断处理程序中根据相应的中断号调用对应的中断服务函数。 一般两种处理方式: 1. 在汇编中保存现场,然后调用C语言编写的中断处理程序,任务处理完成之后,再返回到汇编中恢复现场,并...
  • 6410之中断处理

    2016-11-19 23:01:25
    在6410 arm体系中,很多模块可以产生中断,比如GPIO,UART,TS等都可以产生。在这些模块和CPU之间还有一个中断控制器。这个中断控制器就是用于协调这些模块和CPU之间的交互的。比如:GPIO和UART同时发出中断请求,...
  • 文章目录中断概念中断实现中断注册中断标志**共享中断**:中断处理程序释放中断 中断概念 为什么需要中断? 外设的处理速度一般慢于CPU ...实现中断处理函数 中断注册 request_irq 用于实现中断的注册...
  • 展开全部1)中断e69da5e6ba903231313335323631343130323136353331333431366338响应的事前准备:系统要想能够应对各种不同的中断信号,总的来看就是需要知道每种信号...2) CPU检查是否有中断/异常信号CPU在执行完当...
  • ●中断中断,在单片机中占有非常重要的地位。代码默认地从上向下执行,遇到...●关于STM32的中断几乎任何一款单片机都会有中断。以STM32F407VE来说,这是一款基于Cortex-M4内核的芯片,在CM4内核中有关于中断的一...
  • 中断处理浅析

    千次阅读 2011-06-01 23:04:00
    摘要:本章将向读者依次解释中断概念,解析Linux中的中断实现机理以及Linux下...举个日常生活中的例子,比如说我正在厨房用煤气烧一壶水,这样就只能守在厨房里,苦苦等着水开——如果水溢出来浇灭了煤气,可能就要
  • 1、在多处理器系统中,操作系统需要在多个处理器间协调操作,通常是通过处理期间中断(IPI)实现的。 2、IPI是一种特殊的硬件中断,由处理器发出,被其他处理器接收,以便于处理器间通信或同步。 3、通常并不明确区分...
  • Linux中断处理程序设计 中断概念   中断指当出现需要时,CPU暂时停止当前程序的执行转而执行处理新情况的程序和执行过程。  为什么需要中断? 1、 外设的处理速度一般慢于CPU 2、 CPU不能一直等待外部事件 ...
  • 单片机中的中断系统对电子工程师来说是解决突发事件和多任务实时处理的方法,熟练掌握中断技术的应用是一个合格电子工程师必备的能力。  PIC与51系列单片机一个显著的区别就是:PIC只有一个中断入口地址(为04H)...
  • LDD3 第10章 中断处理

    2018-09-17 14:26:00
    各种硬件和处理器打交道的周期不同,并且总是比处理器慢。...中断处理例程和其他代码并发运行,这样处理例程会不可避免的引起并发问题,并竞争数据结构和硬件。 一、安装和处理中断例程 中断信号线...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,651
精华内容 1,060
关键字:

中断处理需要有中断