IRQ in Linux 5.4

在 Linux 内核中,中断请求 (IRQ) 对于管理硬件中断至关重要,它允许硬件设备向处理器发出信号,表示它们需要注意。IRQ 的处理对于响应迅速且高效的系统性能至关重要。以下是 Linux 内核 5.4 中 IRQ 的详细说明,涵盖了它们的注册、处理和相关数据结构:

1. IRQ 基础知识

IRQ是发送给处理器的硬件信号,用于中断当前代码执行并处理特定事件,例如来自键盘的输入或到达的网络数据包。

中断控制器是一种对这些中断进行优先排序并将其分派给 CPU 的硬件。

2. IRQ 数据结构

Linux Kernel 5.4 中用于处理 IRQ 的关键数据结构包括:

  • struct irq_desc:代表每个中断的描述符,包含 IRQ 编号、处理程序、状态和亲和性等信息。
  • struct irq_chip:代表中断控制器硬件操作。
  • struct irqaction:表示发生中断时要采取的操作,包括处理函数和标志。

3. IRQ 注册

设备使用类似 的函数注册其中断处理程序request_irq()。以下是 IRQ 处理程序注册的简化视图:

arduino 复制代码
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)
  • irq:中断号。
  • handler:中断发生时调用的函数。
  • flags:控制中断行为的标志。
  • name:中断的名称。
  • dev:指向设备特定数据的指针。

例子:

arduino 复制代码
static irqreturn_t my_irq_handler(int irq, void *dev_id)
{
    // Handle the interrupt
    return IRQ_HANDLED;
}

int my_device_init(void)
{
    int irq = 10;  // Example IRQ number
    int ret;

    ret = request_irq(irq, my_irq_handler, IRQF_SHARED, "my_device", &my_device_data);
    if (ret) {
        pr_err("Failed to request IRQ %d\n", irq);
        return ret;
    }
    return 0;
}

4. IRQ 处理

当发生中断时,处理器停止执行当前指令并跳转到中断处理程序。流程如下:

  1. 中断发生:硬件设备发出中断信号。
  2. 中断控制器:控制器确定优先级并将中断发送给 CPU。
  3. 中断处理
    • CPU 确认中断并执行为特定 IRQ 注册的中断处理程序。
    • 处理程序执行后,控制权将返回给被中断的任务。

5. 上半部分和下半部分

Linux 将中断处理分为两部分:

  • 上半部:初始中断处理程序,它快速执行以确认中断并可能调度下半部。
  • 下半部:将大部分处理推迟到以后进行。类型包括软中断、小任务和工作队列。

6. IRQ 亲和性

IRQ 亲和性决定了哪些 CPU 处理特定中断。可以使用proc文件系统来控制:

bash 复制代码
echo 2 > /proc/irq/10/smp_affinity  # Set IRQ 10 to CPU 2

7. IRQ 管理功能

  • free_irq():释放先前分配的 IRQ。
  • disable_irq():禁用给定的 IRQ 线。
  • enable_irq():启用给定的 IRQ 线路。

8.示例演练

下面是一个简化的示例来说明 IRQ 注册和处理:

arduino 复制代码
#include <linux/module.h>
#include <linux/interrupt.h>

#define MY_IRQ 10

static irqreturn_t my_irq_handler(int irq, void *dev_id)
{
    pr_info("IRQ %d: Interrupt occurred\n", irq);
    // Handle the interrupt
    return IRQ_HANDLED;
}

static int __init my_module_init(void)
{
    int ret;

    ret = request_irq(MY_IRQ, my_irq_handler, IRQF_SHARED, "my_device", &my_device_data);
    if (ret) {
        pr_err("Failed to request IRQ %d\n", MY_IRQ);
        return ret;
    }

    pr_info("Module loaded, IRQ %d registered\n", MY_IRQ);
    return 0;
}

static void __exit my_module_exit(void)
{
    free_irq(MY_IRQ, &my_device_data);
    pr_info("Module unloaded, IRQ %d freed\n", MY_IRQ);
}

module_init(my_module_init);
module_exit(my_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Author");
MODULE_DESCRIPTION("IRQ handling example");

9.中断上下文和同步

中断处理程序在中断上下文中运行,这意味着它们不能阻塞、休眠或执行可能阻塞的操作。通常需要同步才能在中断处理程序和内核的其他部分之间安全地共享数据。自旋锁通常用于此目的。

10. 总结

  • 注册 :用于request_irq()注册中断处理程序。
  • 处理:上半部分快速处理,将较长的任务推迟到下半部分。
  • 亲和性(Affinity):控制哪个 CPU 处理中断。
  • 同步:确保中断处理程序和其他上下文之间的安全数据访问。

理解和管理 IRQ 对于开发高效且响应迅速的内核模块和设备驱动程序至关重要。Linux Kernel 5.4 继续使用这些基础概念,并进行了增强和优化,以实现更好的性能和可扩展性。

相关推荐
2202_754421542 分钟前
生成MPSOC以及ZYNQ的启动文件BOOT.BIN的小软件
java·linux·开发语言
运维&陈同学1 小时前
【zookeeper03】消息队列与微服务之zookeeper集群部署
linux·微服务·zookeeper·云原生·消息队列·云计算·java-zookeeper
代码吐槽菌2 小时前
基于SSM的毕业论文管理系统【附源码】
java·开发语言·数据库·后端·ssm
周末不下雨2 小时前
win11+ubuntu22.04双系统 | 联想 24 y7000p | ubuntu 22.04 | 把ubuntu系统装到1T的移动固态硬盘上!!!
linux·运维·ubuntu
豌豆花下猫2 小时前
Python 潮流周刊#78:async/await 是糟糕的设计(摘要)
后端·python·ai
YMWM_2 小时前
第一章 Go语言简介
开发语言·后端·golang
码蜂窝编程官方2 小时前
【含开题报告+文档+PPT+源码】基于SpringBoot+Vue的虎鲸旅游攻略网的设计与实现
java·vue.js·spring boot·后端·spring·旅游
hummhumm2 小时前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
哎呦喂-ll2 小时前
Linux进阶:环境变量
linux