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 继续使用这些基础概念,并进行了增强和优化,以实现更好的性能和可扩展性。

相关推荐
博语小屋2 小时前
设计一个简单的网络计算器并将其守护进程化
linux·网络·tcp/ip
星火开发设计2 小时前
枚举类 enum class:强类型枚举的优势
linux·开发语言·c++·学习·算法·知识
VX:Fegn08957 小时前
计算机毕业设计|基于ssm + vue超市管理系统(源码+数据库+文档)
前端·数据库·vue.js·spring boot·后端·课程设计
喜欢吃燃面7 小时前
Linux:环境变量
linux·开发语言·学习
佑白雪乐11 小时前
<Linux基础第10集>复习前面内容
linux·运维·服务器
春日见11 小时前
自动驾驶规划控制决策知识点扫盲
linux·运维·服务器·人工智能·机器学习·自动驾驶
暮云星影11 小时前
四、linux系统 应用开发:UI开发环境配置概述 (三)
linux·ui·arm
Java天梯之路12 小时前
Spring Boot 钩子全集实战(七):BeanFactoryPostProcessor详解
java·spring boot·后端
迷途知返-12 小时前
服务器——那些年我踩过的坑
linux
wr20051412 小时前
第二次作业,渗透
java·后端·spring