• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 外部中斷原理分析

    發表于:2007-07-04來源:作者:點擊數: 標簽:
    linux 的外部中斷分為固定部分和可變部分,固定部分為0~~15號的系統本身定義的中斷,而可變部分則是提供給用戶自己定義設備驅動的中斷相應的,前兩天稍微寫了一點這方面的分析 MI LY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-famil
          linux的外部中斷分為固定部分和可變部分,固定部分為0~~15號的系統本身定義的中斷,而可變部分則是提供給用戶自己定義設備驅動的中斷相應的,前兩天稍微寫了一點這方面的分析

    MILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">外部中斷可變部分描述:

    irq_desc[]數組描述

    Irq_desc_t:

    typedef struct {

           unsigned int status;        /* IRQ status */

           hw_irq_controller *handler;

           struct irqaction *action;  /* IRQ action list */

           unsigned int depth;        /* nested irq disables */

           spinlock_t lock;

    } ____cacheline_aligned irq_desc_t;

     

     

    Irq狀態是由以下各標志組合的:

    unsigned int status;        /* IRQ status */

    #define IRQ_INPROGRESS 1     /* IRQ handler active - do not enter! */

    #define IRQ_DISABLED      2     /* IRQ disabled - do not enter! */

    #define IRQ_PENDING       4     /* IRQ pending - replay on enable */

    #define IRQ_REPLAY   8     /* IRQ has been replayed but not acked yet */

    #define IRQ_AUTODETECT       16    /* IRQ is being autodetected */

    #define IRQ_WAITING 32    /* IRQ not yet seen - for autodetection */

    #define IRQ_LEVEL     64    /* IRQ level triggered */

    #define IRQ_MASKED 128  /* IRQ masked - shouldn't be seen again */

    #define IRQ_PER_CPU 256  /* IRQ is per CPU */

     

    struct irqaction *action;  /* IRQ action list */

    描述外部中斷的可變部分,對一個外部中斷的所有處理將以irqaction結構掛在action隊列上

    Interrupt.hàirqaction:

    struct irqaction {

           void (*handler)(int, void *, struct pt_regs *);

           unsigned long flags;

           unsigned long mask;

           const char *name;

           void *dev_id;

           struct irqaction *next;

    };

    Handler中斷處理函數,dev_id設備標識,用于標記多個設備共享同一個irq

     

    時間中斷處理程序為timer_interrupt

     

    外部設備的驅動程序在初始化時都要創建自己的irqaction結構

    Irq.càrequest_irq:

    int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),

                   unsigned long irq_flags, const char * devname, void *dev_id)

    {

           unsigned long retval;

           struct irqaction *action;

     

           if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler ||

               (irq_flags & SA_SHIRQ && !dev_id))

                  return -EINVAL;

     

           action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);

           if (!action)

                  return -ENOMEM;

     

           action->handler = handler;

           action->flags = irq_flags;

           action->mask = 0;

           action->name = devname;

           action->next = NULL;

           action->dev_id = dev_id;

     

           retval = setup_arm_irq(irq, action);

     

           if (retval)

                  kfree(action);

           return retval;

    }

     

    調用setup_arm_irq向內存申請一塊內存填寫irqaction結構,返回irq

    該函數完成以下工作:

    (1)       在數組irq_desc[]中找到程序申請的irq號對應的action隊列

    (2)       如果該隊列不為空,說明該irq號被多個設備共享,檢查這種共享是否允許(由老的irqaction結構的flags標識),如果合法,則將新的irqaction結構插到對應的action隊列的末尾

    (3)       如果隊列為空,則將irqaction結構插在對應action隊列的頭部,填寫irq_desc[irq]的其他域

     

    至此外部設備驅動向系統注冊中斷完成

     

    中斷釋放:

    void free_irq(unsigned int irq, void *dev_id)

    完成以下工作:

    (1)       檢查irq的合法性

    (2)       action隊列irq_desc[irq].action上,查找action->dev_id == dev_idirqaction結構

    (3)       如果找到這樣的結構,則將其從隊列上摘下,同時釋放其原本占用的內存空間

    (4)       如果釋放后,irq_desc[irq]上已經沒有其他的irqaction結構,則釋放irq_desc[irq]上的相應域,關掉中斷

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>