linux添加中断处理,linux中断处理上下部分

一.linux中断处理为什么要分为上下部

1.1. 中断处理的上半部(top half,又叫顶半部)和处理的下半部(bottom half,又叫底半部)

1.1. linux中断处理不参与调度,故中断处理时间过长会影响实时性

1.2. ISR运行时间尽可能短,但有些处理没有部分很短处理完,于是linux内核提供中断处理上下部。

二. 两种处理机中

2.1 tasklet机制

2.1.1. 相关函数位于interrupt.h

2.1.2. DECLARE_TASKLET和tasklet_schedule很重要

44fbb2167301c3a4e2f54a93ac511707026.jpg

1dd51564582dc5d71ab5787aa2ff2d5fdf7.jpg

/*Tasklets --- multithreaded analogue of BHs.

Main feature differing them of generic softirqs: tasklet

is running only on one CPU simultaneously.

Main feature differing them of BHs: different tasklets

may be run simultaneously on different CPUs.

Properties:

* If tasklet_schedule() is called, then tasklet is guaranteed

to be executed on some cpu at least once after this.

* If the tasklet is already scheduled, but its excecution is still not

started, it will be executed only once.

* If this tasklet is already running on another CPU (or schedule is called

from tasklet itself), it is rescheduled for later.

* Tasklet is strictly serialized wrt itself, but not

wrt another tasklets. If client needs some intertask synchronization,

he makes it with spinlocks.*/

structtasklet_struct

{struct tasklet_struct *next;

unsignedlongstate;

atomic_t count;void (*func)(unsigned long);

unsignedlongdata;

};#define DECLARE_TASKLET(name, func, data) \

struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(0), func, data }#define DECLARE_TASKLET_DISABLED(name, func, data) \

struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(1), func, data }enum{

TASKLET_STATE_SCHED,/*Tasklet is scheduled for execution*/TASKLET_STATE_RUN/*Tasklet is running (SMP only)*/};

#ifdef CONFIG_SMPstatic inline int tasklet_trylock(struct tasklet_struct *t)

{return !test_and_set_bit(TASKLET_STATE_RUN, &(t)->state);

}static inline void tasklet_unlock(struct tasklet_struct *t)

{

smp_mb__before_clear_bit();

clear_bit(TASKLET_STATE_RUN,&(t)->state);

}static inline void tasklet_unlock_wait(struct tasklet_struct *t)

{while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { barrier(); }

}#else

#define tasklet_trylock(t) 1

#define tasklet_unlock_wait(t) do { } while (0)

#define tasklet_unlock(t) do { } while (0)

#endif

extern void __tasklet_schedule(struct tasklet_struct *t);static inline void tasklet_schedule(struct tasklet_struct *t)

{if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state))

__tasklet_schedule(t);

}

View Code

2.2. workqueue机制

2.2.1.  相关函数位于include/linux/workqueue.h

2.2.2. DECLARE_WORK和schedule_work很重要

921e5a67083c66e153455ecb9a1a886dcb0.jpg

237e8b48134a5f6ff58d3eb38a7c61d5781.jpg

#define DECLARE_WORK(n, f) \

struct work_struct n =__WORK_INITIALIZER(n, f)extern int schedule_work(struct work_struct *work);

View Code

2.3.中断上下半部处理原则

(1)必须立即进行紧急处理的极少量任务放入在中断的顶半部中,此时屏蔽了与自己同类型的中断,由于任务量少,所以可以迅速不受打扰地处理完紧急任务。

(2)需要较少时间的中等数量的急迫任务放在tasklet中。此时不会屏蔽任何中断(包括与自己的顶半部同类型的中断),所以不影响顶半部对紧急事务的处理;同时又不会进行用户进程调度,从而保证了自己急迫任务得以迅速完成。

(3)需要较多时间且并不急迫(允许被操作系统剥夺运行权)的大量任务放在workqueue中。此时操作系统会尽量快速处理完这个任务,但如果任务量太大,期间操作系统也会有机会调度别的用户进程运行,从而保证不会因为这个任务需要运行时间将其它用户进程无法进行。

(4)可能引起睡眠的任务放在workqueue中。因为在workqueue中睡眠是安全的。在需要获得大量的内存时、在需要获取信号量时,在需要执行阻塞式的I/O操作时,用workqueue很合适。

参考文献《朱老师.触摸屏驱动移植实战》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值