|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
研究 linux 内核 - 软中断& \( `0 Z# s p. j0 k+ F' |
* k, y" J3 R- g
9 i5 G# A7 @- A1 R" n# U* ~2 ?1 m: H9 [' S
& {$ A% l; M8 y. Y- L- a6 \- \1,说在前面4 o$ N' A1 N V+ }, T
% e. |! v3 e, A D, y# ?/ d! v6 [- m
; v1 w& B- p @9 R" L. B; B* O1》此“软中断”非彼“软中断”,这里说的不是针对硬件中断的那个,而是中断处理流程的下半部分机制之一。! C: J$ Z. O0 H% A
2》2.6内核有三种下半部机制:软中断,tasklet,work queue。
$ W& e- I, @, L4 ]' t3》老的内核使用的BH,task queue,现在都已经不用了。) q4 ~; k+ M! J _. ?
4》tasklet 需要软中断的帮助。
/ ~. H- t7 s' u5》软中断不能抢占其它软中断,但是不同CPU上的可以同时执行。
9 ]+ S0 f2 K$ j6》软中断只能被中断抢占。' E* |! a. B9 o9 |8 H) T
7》要用软中断,需要在内核编译前做一些事情,不能完全动态创建。
6 t0 w4 [# B/ H) o) t3 Y: d" }/ C# N
6 Z9 }% @9 w( B0 m% m+ y1 W' e
2,软中断工作原理和过程
2 k9 K- W2 h* M3 K/ u) g2 L; ], A. x5 l0 ?' H9 K
$ T: Y8 N; n: D5 O" e
1》内核里有一个32个成员的数组。
9 ]& z, F7 O8 g: Z) O! m数组成员包含软中断处理函数指针,和处理函数的参数。在/kernel/softirq.c里面。
: Q5 A" ?& Q6 s# k& }7 q) p( ]" H. f0 E
, H; d ~3 Z$ @4 B# G+ V0 K
static struct softirq_action softirq_vec[32] _xx__xx。
% X% o; S1 h/ @3 H) q: r# C
7 ~5 V* K) e: h% [! S
' Q! n l. e1 f/ ~ D# ~(我们公司有套加密系统,从source insight里面不能直接copy,必须手输,所以就把后面的变量名称省掉了,见谅。),这个数组的成员定义在interrupt.h里面:
& B8 K5 L! y$ Q1 ?
; J2 ~+ D& ]9 @8 R( ~$ T/ G& [- V# F2 y7 d
struct softirq_action" L0 N% t6 ~/ A( h2 z# _+ G
{
; v1 r* i& B p, V3 lvoid (*action)(struct softirq_action*);
$ p7 d) F1 o, I3 T/ D6 F+ L1 M5 gvoid *data;
: C/ a+ ^% [1 G8 A8 s: z. j}
; p5 S4 J7 |+ Y; X8 Q3 w8 E9 M7 R1 f
$ `( g8 Z6 E% ?' @3 W+ w4 I* I- z9 g. M8 f5 V! S
! M2 t4 M( @( _' S: m
: {; K& a; ]0 p' e: ^' V4 u2》内核里面有个内核线程(叫:ksoftirqd)。" _. Q& ]) v- @. H
2 k6 f* |0 c5 w
3 x, {) ~3 Q+ Z2 @6 v0 ]
6 S& x4 T( Q; U5 T$ X7 J5 a
: i2 d2 |1 B/ \! F) c# ~
) S% l/ e; r; o5 i7 R3,软中断工作流程
! ?! b. k3 v. U6 a
2 O+ N _7 I" _+ |2 _- X Z8 P( S( ~7 v2 z
1》ksoftirqd循环检查32位数组。- i7 K6 r$ |7 H) ]
2》发现某一位被标记,就执行它对应的软中断处理函数。
7 b# `) a( V! z# C/ ~; z$ Y9 S1 a% ^% B" m. P0 Q5 B8 Q4 F7 T
* {& q' T; e& H9 z. u& t8 ^# X4,在驱动中如何使用软中断
1 J6 {5 i4 J5 {7 V6 w. K! D d; E7 h3 K+ C0 u# ~9 n: F/ f
% c' d. ~$ l$ h: W% {: N
1》请确认一定要用软中断(或许可以考虑tasklet,呵呵)。4 r5 n7 S d4 j8 L+ U4 r1 P" s& m
2》在内核编译前,分配索引:4 a# |9 P1 X* o: ~* r3 s
在linux/interrupt.h里面的232行有个枚举,在里面加入一行(比如叫:RILL_SOFTIRQ)。注意,不能简单的加到最后,要根据你想要的优先级来加。想高点,就加到前面一点,反之,你懂的。# o: }0 ~5 D; d/ ?
3》编译内核' {1 z. l, [6 B. f. |
4》在你的驱动里注册软中断处理函数- [/ y7 B) N; c- T
open_softirq(RILL_SOFTIRQ,rill_softirq_func,NULL);
" t7 H4 |3 d! x; ?3 ^5》在你的中断处理程序返回前触发软中断(加标记)8 z' ^0 H+ |; J1 Z; f" G
raise_softirq(RILL_SOFTIRQ);这个函数会先禁止中断,返回前恢复;4 z- l9 J0 S4 \2 a) o5 {& z
如果你知道中断已经禁止了就用下面这个函数:
* T3 p) _3 F4 G% n! Y0 [raise_softirq_irqoff(RILL_SOFTIRQ);! O. g0 i I+ D
6 s) n! L4 L) U1 ^( H( K4 w) g# N
" `7 }/ X2 @+ x
" i5 g* M9 E+ k# A6 a: p# u: S
; i' \6 j1 F1 o, p8 y7 }* x |
|