> 운영 및 유지보수 > 리눅스 운영 및 유지 관리 > Linux 드라이버의 하위 절반을 중단하는 세 가지 방법

Linux 드라이버의 하위 절반을 중단하는 세 가지 방법

풀어 주다: 2023-07-31 14:57:18
앞으로
1015명이 탐색했습니다.

인터럽트 후반이란

인터럽트가 발생하면 인터럽트 핸들러에 들어갑니다.

그러나 인터럽트 핸들러는 하드웨어에 신속하게 응답하고 시간이 중요한 작업을 완료할 수 있도록 빠르고 비동기적이며 단순해야 합니다.

따라서 상대적으로 시간 요구 사항이 느슨한 다른 작업의 경우 실행하기 전에 인터럽트가 활성화될 때까지 연기해야 합니다.

이런 식으로 전체 인터럽트 처리 프로세스는 두 부분으로 나누어집니다:

  • 첫 번째 부분은 인터럽트 핸들러(상반부)이며, 커널은 비동기 실행을 통해 하드웨어 인터럽트 처리를 완료합니다. 즉각적인 응답.
  • 인터럽트 처리 과정의 또 다른 부분인 하부(하부)

하부의 작업은 주로 인터럽트 서비스 루틴에 의해 완료되지 않는 인터럽트 관련 작업을 수행하는 것이다. 그 자체.

Linux 드라이버의 하위 절반을 중단하는 세 가지 방법

하반기는 정확한 시간을 지정할 필요가 없습니다. 이러한 작업을 조금 연기하고 시스템이 너무 바쁘지 않을 때중단이 복구된 후에 실행되도록 하세요.

상부와 하반부의 주요 차이점:

  • 상부 인터럽트 핸들러를 나타내고, 하부는 인터럽트와 관련된 몇 가지 사항을 나타냅니다. 그러나 는 할 수 있습니다. 작업 실행을 연기합니다.

  • 인터럽트의 위쪽 절반은 동일한 유형의 인터럽트로 중단될 수 없지만 하부 절반은 여전히 ​​인터럽트로 중단될 수 있습니다.

  • 보통 하위 절반은 인터럽트 핸들러가 반환되자마자 실행됩니다.

  • 전반은 간단하고 빠르며 실행 중에는 일부 또는 전체 중단이 금지됩니다.

  • 후반부는 나중에 실행될 예정이며, 실행 중에 모든 인터럽트에 응답할 수 있습니다.

Linux中,对中断下半부적 实现主要유삼종:Linux中,对中断下半部的实现主要有三种:

  • 软中断
  • tasklet
  • 工作队列

softirq

softirq即软中断,代码位于kernel/softirq.c文件中;

每个软中断由softirq_action结构表示:

Linux 드라이버의 하위 절반을 중단하는 세 가지 방법

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

  • 软中断

  • tasklet

    🎜
  • > 테두리 하단: 1px 단색 rgb(239, 112, 96); 글꼴 크기: 1.3em;">softirq 🎜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/upload/article/001/275/014/b22f370513bb14011ce70289a459a54b-1.png"/ alt="Linux 드라이버의 하위 절반을 중단하는 세 가지 방법" ></Figure>🎜재<code style="max-width:90%"연산자 Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">softirq.c중정义了一个软中断向weight数组<코드 스타일 ="글꼴 크기: 14px; 패딩: 2px 4px; 테두리 반경: 4px; 여백 오른쪽: 2px; 여백 왼쪽: 2px; 배경 색상: rgba(27, 31, 35, 0.05); 글꼴 계열: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">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上并行运行的根本原因。

    软中断实例

    以一个按键驱动的中断处理为例,将按键驱动的中断处理分成上下两部分:

    • 상부: 키 값을 읽고 소프트 인터럽트 실행
    • 하부: 프로세스 깨우기
    Linux 드라이버의 하위 절반을 중단하는 세 가지 방법

    소프트 인터럽트 등록, 드라이버 입력 기능에 소프트 인터럽트 등록 :

    Linux 드라이버의 하위 절반을 중단하는 세 가지 방법

    열거 상수 추가:

    Linux 드라이버의 하위 절반을 중단하는 세 가지 방법

    보시다시피 소프트 인터럽트를 사용하려면 커널을 수정하고 열거를 추가해야 하는데 이는 약간 번거롭습니다.

    따라서 일반적으로 승인 없이 소프트 인터럽트 수를 늘리는 것을 권장하지 않습니다. 새로운 소프트 인터럽트가 필요한 경우 소프트 인터럽트를 기반으로tasklet 형식. tasklet形式。

    tasklet

    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;color: rgb(239, 112, 96);">tasklet< /code>실제로는 매우 간단합니다. 🎜<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效果都不错,而且它们还非常容易使用。
  • 因为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, 然后允许系统在合适的时间调度它。

tasklet实例

以按键中断驱动为例:

Linux 드라이버의 하위 절반을 중단하는 세 가지 방법

먼저 DECLARE_TASKLET정적 선언 atasklet, 하위 절반 기능 지정 btn_tasklet_func, 인터럽트 서비스 기능에서(on half) 키 값을 얻으려면 tasklet_schedule 일정. DECLARE_TASKLET静态声明一个tasklet,指定其下半部函数为btn_tasklet_func,在中断服务函数(上半部)获取按键值后,调用tasklet_schedule调度。

work queue

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。否则使用softirqtasklets.
  • Work queues适用于需要分配大量的内存,获得一个信号量,或者执行阻塞的I/O的情况.
  • 工作队列的相关接口函数:

    Linux 드라이버의 하위 절반을 중단하는 세 가지 방법

    在使用上,工作队列tasklet

    작업 대기열
    适用于需要分配大용량의 内存,获得一个信号weight,或者执行阻塞的 I/O적감정.Linux 드라이버의 하위 절반을 중단하는 세 가지 방법

    工작품队列적상상关接口函数:

    Linux 드라이버의 하위 절반을 중단하는 세 가지 방법

    현재 사용상,工作队列

    tasklet是类似的:


    🎜🎜🎜🎜🎜🎜🎜

    위 내용은 Linux 드라이버의 하위 절반을 중단하는 세 가지 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    관련 라벨:
    원천:嵌入式Linux充电站
    본 웹사이트의 성명
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
    인기 튜토리얼
    더>
    최신 다운로드
    더>
    웹 효과
    웹사이트 소스 코드
    웹사이트 자료
    프론트엔드 템플릿