Linux的中断编程

Linux提供了很多API函数用于中断编程,同时提供了几种底半部机制用于中断函数的实现。正确的使用它们,有利于优化需要实现的中断机制。

.1         申请IRQ

static inline int __must_check

request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev)

{

         return request_threaded_irq(irq, handler, NULL, flags, name, dev);

}

irq为要申请的硬件中断号,handle为向系统登记的中断处理函数,中断发生时系统将调用它。flags为中断处理的属性。

request_irq()返回0表示 申请成功,返回-INVAL表示中断号无效或处理函数指针为NULL,返回-EBUSY表示中断已经被占用且不能共享。

.2         释放IRQ

void free_irq(unsigned int irq, void *dev_id)

{

         kfree(__free_irq(irq, dev_id));

}

它与request_irq()函数对应,用于释放IRQ中断。

.3         使能和屏蔽中断

void disable_irq(unsigned int irq)

{

         struct irq_desc *desc = irq_to_desc(irq);

         if (!desc)

                   return;

         disable_irq_nosync(irq);

         if (desc->action)

                   synchronize_irq(irq);

}

disable_irq函数用于屏蔽IRQ中断;

void enable_irq(unsigned int irq)

{

         struct irq_desc *desc = irq_to_desc(irq);

         unsigned long flags;

         if (!desc)

                   return;

         spin_lock_irqsave(&desc->lock, flags);

         __enable_irq(desc, irq, false);

         spin_unlock_irqrestore(&desc->lock, flags);

}

enable_irq函数用于使能IRQ中断,可以看到函数中加入了自旋锁。

#define local_irq_enable() /

         do { trace_hardirqs_on(); raw_local_irq_enable(); } while (0)

#define local_irq_disable() /

         do { raw_local_irq_disable(); trace_hardirqs_off(); } while (0)

#define local_irq_save(flags)                             /

         do {                                                 /

                   typecheck(unsigned long, flags);     /

                   raw_local_irq_save(flags);              /

                   trace_hardirqs_off();                       /

         } while (0)

#define local_irq_restore(flags)                         /

         do {                                                 /

                   typecheck(unsigned long, flags);     /

                   if (raw_irqs_disabled_flags(flags)) {       /

                            raw_local_irq_restore(flags); /

                            trace_hardirqs_off();              /

                   } else {                                   /

                            trace_hardirqs_on();               /

                            raw_local_irq_restore(flags); /

                   }                                             /

         } while (0)

local_irq_enablelocal_irq_restore函数用于恢复中断,local_irq_disablelocal_irq_save用于屏蔽所有中断。local_irq_save将目前的中断状态保留在flags中,而local_irq_disable直接禁止中断。这里的local表明作用范围在本CPU内。

.4         底半部机制

    Linux实现底半部中断的机制主要有tasklet,工作队列和软中断。通常我们使用前两种。

.4.1     tasklet

定义tasklet及其处理函数,并将两者关联:

void my_tasklet_func(unsigned long);

DECLARE_TASKLET(my_tasklet,my_tasklet_func,data);

DECLARE_TASKLET定义名称为my_tasklettasklet并将其与my_tasklet_func函数绑定,传入这个函数的参数为data。在需要调度tasklet的时候引用tasklet_schedule函数就能使系统在适当时候运行:

tasklet_schedule(&my_tasklet);

.4.2     工作队列

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值