인터럽트가 발생하면 인터럽트 핸들러에 들어갑니다.
그러나 인터럽트 핸들러는 하드웨어에 신속하게 응답하고 시간이 중요한 작업을 완료할 수 있도록 빠르고 비동기적이며 단순해야 합니다.
따라서 상대적으로 시간 요구 사항이 느슨한 다른 작업의 경우 실행하기 전에 인터럽트가 활성화될 때까지 연기해야 합니다.
이런 식으로 전체 인터럽트 처리 프로세스는 두 부분으로 나누어집니다:
하부의 작업은 주로 인터럽트 서비스 루틴에 의해 완료되지 않는 인터럽트 관련 작업을 수행하는 것이다. 그 자체.
하반기는 정확한 시간을 지정할 필요가 없습니다. 이러한 작업을 조금 연기하고 시스템이 너무 바쁘지 않을 때 및 중단이 복구된 후에 실행되도록 하세요.
상부와 하반부의 주요 차이점:
상부 는 인터럽트 핸들러를 나타내고, 하부는 인터럽트와 관련된 몇 가지 사항을 나타냅니다. 그러나 는 할 수 있습니다. 작업 실행을 연기합니다.
인터럽트의 위쪽 절반은 동일한 유형의 인터럽트로 중단될 수 없지만 하부 절반은 여전히 인터럽트로 중단될 수 있습니다.
보통 하위 절반은 인터럽트 핸들러가 반환되자마자 실행됩니다.
전반은 간단하고 빠르며 실행 중에는 일부 또는 전체 중단이 금지됩니다.
후반부는 나중에 실행될 예정이며, 실행 중에 모든 인터럽트에 응답할 수 있습니다.
Linux
中,对中断下半부적 实现主要유삼종:Linux
中,对中断下半部的实现主要有三种:
softirq
即软中断,代码位于kernel/softirq.c
文件中;
每个软中断由softirq_action
结构表示:
在softirq.c
中定义了一个软中断向量数组softirq_vec
:
static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp; enum { HI_SOFTIRQ=0, /*用于高优先级的tasklet*/ TIMER_SOFTIRQ, /*用于定时器的下半部*/ NET_TX_SOFTIRQ, /*用于网络层发包*/ NET_RX_SOFTIRQ, /*用于网络层收报*/ BLOCK_SOFTIRQ, BLOCK_IOPOLL_SOFTIRQ, TASKLET_SOFTIRQ, /*用于低优先级的tasklet*/ SCHED_SOFTIRQ, HRTIMER_SOFTIRQ, RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */ NR_SOFTIRQS };
数组的成员数由NR_SOFTIRQS
决定,是一个枚举常量。
新增一个软中断时,需要在文件include/linux/interrupt.h
softirq
即软中断,代码位于kernel/softirq.c
文件中; 🎜🎜每个软中断由softirq_action 코드>结构表示:🎜<figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align- 항목: 센터;"><img .php.cn alt="Linux 드라이버의 하위 절반을 중단하는 세 가지 방법" ></img.php.cn></figure>🎜재<code style="max-width:90%" mono consolas monaco menlo monospace break-all rgb>softirq.c
중정义了一个软中断向weight数组softirq_vec:🎜void open_softirq(int nr, void (*action)(struct softirq_action *))🎜数组的成员数由
NR_SOFTIRQS
决定,是一个枚举常weight。🎜🎜 새로운 增一个软中断时,需要 文件include/linux /interrupt.h
中添加一个枚举常weight。🎜🎜🎜软中断使사용용几个要点🎜:🎜相关接口
void open_softirq(int nr, void (*action)(struct softirq_action *))
即注册对应类型的处理函数到全局数组softirq_vec
中。
void raise_softirq(unsigned int nr)
实际上即以软中断类型nr
作为偏移量会置位irq_stat[cpu_id]
的成员变量__softirq_pending
.
__softirq_pending
字段中的每一个bit
,对应着某一个软中断,某个bit
被置位,说明有相应的软中断等待处理。
这也是同一类型软中断可以在多个cpu
上并行运行的根本原因。
以一个按键驱动的中断处理为例,将按键驱动的中断处理分成上下两部分:
소프트 인터럽트 등록, 드라이버 입력 기능에 소프트 인터럽트 등록 :
열거 상수 추가:
보시다시피 소프트 인터럽트를 사용하려면 커널을 수정하고 열거를 추가해야 하는데 이는 약간 번거롭습니다.
따라서 일반적으로 승인 없이 소프트 인터럽트 수를 늘리는 것을 권장하지 않습니다. 새로운 소프트 인터럽트가 필요한 경우 소프트 인터럽트를 기반으로tasklet
형식. tasklet
形式。
tasklet是利用软中断实现的一种下半部机制。
那是用软中断还是tasklet
好呢?
选择到底是用软中断还是tasklet
tasklet 코드> 그렇죠? 🎜🎜🎜소프트 인터럽트🎜를 사용할지 <code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px; background-color: rgba)를 사용할지 선택하세요. (27, 31, 35, 0.05);글꼴군: " operator mono consolas monaco menlo monospace break-all rgb>tasklet실제로는 매우 간단합니다. 🎜<ul class="list-paddingleft-1" data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;">
<li><section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"><strong style="color: black;">通常你应该用<code style='font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);'>tasklet
。tasklet
效果都不错,而且它们还非常容易使用。tasklet
的使用步骤如下:
1、编写tasklet
处理函数(下半部)
void my_tasklet_fun (unsigned long data)
2、声明tasklet
//静态 DECLARE_TASKLET(my_tasklet,my_tasklet_fun,data); //动态 Struct tasklet_struct xxx; tasklet_init(&xxx,tasklet_handler,dev)
3、调度 tasklet
tasklet_schedule(&my_tasklet);
登记my_tasklet
, 然后允许系统在合适的时间调度它。
以按键中断驱动为例:
먼저 DECLARE_TASKLET
정적 선언 atasklet
, 하위 절반 기능 지정 btn_tasklet_func
, 인터럽트 서비스 기능에서(on half) 키 값을 얻으려면 tasklet_schedule
일정. DECLARE_TASKLET
静态声明一个tasklet
,指定其下半部函数为btn_tasklet_func
,在中断服务函数(上半部)获取按键值后,调用tasklet_schedule
调度。
work queue
即工作队列,也是中断下半部的一种。
Work queue
将下半部工作推迟给一个内核线程去执行 ——work
작업 대기열
은 작업 대기열이며, 이것도 하반부에 있는 일종의 인터럽트입니다. 작업 대기열
하반부 작업 연기work 항상 🎜프로세스 컨텍스트🎜에서 실행됩니다.🎜🎜🎜두 가지 중요한 점🎜: 🎜<ul class="list-paddingleft-1" data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;">
<li><section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);">如果推迟的工작품需要<strong style="color: black;">睡眠</strong>,则使用<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px; background- 색상: rgba(27, 31, 35, 0.05); 글꼴 계열: " operator mono consolas monaco menlo monospace break-all rgb>작업 대기열
。否则使用softirq 코드>或tasklets
.work queues
。否则使用softirq
或tasklets
.
Work queues
适用于需要分配大量的内存,获得一个信号量,或者执行阻塞的I/O
的情况.工作队列的相关接口函数:
在使用上,工作队列与tasklet
工작품队列적상상关接口函数: 현재 사용상,工作队列tasklet
是类似的:
위 내용은 Linux 드라이버의 하위 절반을 중단하는 세 가지 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!