• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

外部中断原理分析

发布: 2007-7-04 12:06 | 作者: admin | 来源:  网友评论 | 查看: 22次 | 进入软件测试论坛讨论

领测软件测试网       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]上的相应域,关掉中断

延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备2023014753号-2
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网