文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>外部中断原理分析

外部中断原理分析

时间:2005-09-09  来源:newnewxu

      linux的外部中断分为固定部分和可变部分,固定部分为0~~15号的系统本身定义的中断,而可变部分则是提供给用户自己定义设备驱动的中断相应的,前两天稍微写了一点这方面的分析

外部中断可变部分描述:

以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_id的irqaction结构

(3)       如果找到这样的结构,则将其从队列上摘下,同时释放其原本占用的内存空间

(4)       如果释放后,irq_desc[irq]上已经没有其他的irqaction结构,则释放irq_desc[irq]上的相应域,关掉中断

相关阅读 更多 +
排行榜 更多 +
毒药轮盘手机版下载

毒药轮盘手机版下载

休闲益智 下载
剑侠情缘零b服手游下载

剑侠情缘零b服手游下载

角色扮演 下载
惊魂动物园游戏手机版下载

惊魂动物园游戏手机版下载

冒险解谜 下载