百度
360搜索
搜狗搜索

linux中断如何使用详细介绍

在 Linux 中使用中断需要涉及内核驱动开发,主要包括中断的注册、处理函数的编写以及上下半部的分离处理。以下是核心步骤和方法的详细说明:

一、核心概念

  1. 中断分类

    • 上半部(Top Half):紧急处理(如清除中断标志、记录数据),需快速完成,禁止睡眠,运行在原子上下文。
    • 下半部(Bottom Half):耗时操作(如数据处理、用户空间通知),可延迟执行,支持睡眠,运行在进程上下文或软中断上下文。

  2. 触发类型

    • 边沿触发(IRQF_TRIGGER_RISING/IRQF_TRIGGER_FALLING
    • 电平触发(IRQF_TRIGGER_HIGH/IRQF_TRIGGER_LOW

二、使用步骤

1.
获取中断号

  • 固定中断号:如已知设备的中断号(如通过 dts 设备树描述),或使用内核预定义宏(如 IRQ_GPIO_N)。
  • GPIO 中断:通过 gpio_to_irq(gpio_num) 将 GPIO 编号转换为中断号(需先申请 GPIO:gpio_request)。
  • 设备树方式:在驱动中解析设备树节点获取中断信息:c
      node  pdevdevof_node

    irq node

2.
注册中断处理函数

使用 request_irq 函数注册中断,原型如下:
c

   irq  handler   flags

name dev

  • 参数说明
    • irq:中断号。
    • handler:上半部处理函数(返回值为 irqreturn_t,需返回 IRQ_HANDLEDIRQ_NONE)。
    • flags:中断触发类型(如 IRQF_TRIGGER_RISING)+ 选项(如 IRQF_SHARED 共享中断)。
    • name:中断名称(可通过 cat /proc/interrupts 查看)。
    • dev:共享中断时用于标识设备的指针(非共享时可设为 NULL)。

示例:注册非共享中断
c

   irq  dev_id 

my_work

IRQ_HANDLED

result irq_num my_irq_handler IRQF_TRIGGER_FALLING

result

KERN_ERR

result

3.
实现下半部

根据需求选择合适的下半部机制:

  • Tasklet(轻量级,非睡眠)
    c

    data

    my_tasklet my_tasklet

    my_tasklet

    data

  • 工作队列(支持睡眠)
    c

    my_work

    my_work my_work_handler

    my_work

    work

  • 线程化中断处理函数(Linux 2.6.30+)
    通过设置 IRQF_ONESHOTIRQF_SHARED 并将处理函数放在内核线程中(需配合 request_threaded_irq):
    c
       irq  dev_id

    dev_id

    irq_num my_irq_handler my_threaded_handler

    flags dev

    irq dev_id

    IRQ_HANDLED

    dev_id

4.
卸载中断

在驱动移除时调用 free_irq
c

irq_num dev 

三、注意事项

  1. 原子性与并发控制

    • 上半部禁止抢占和中断,需避免使用可能睡眠的函数(如 kmalloccopy_to_user)。
    • 下半部若使用 tasklet / 软中断,仍处于原子上下文;工作队列 / 线程化处理函数处于进程上下文,可使用锁(如 mutex)。

  2. 共享中断

    • 多个设备共享同一中断号时,需在 request_irq 中设置 IRQF_SHARED,并通过设备标识 dev 区分中断源。
    • 处理函数中需先检查当前设备是否为中断源(如读取硬件寄存器),若是返回 IRQ_HANDLED,否则 IRQ_NONE

  3. 设备树配置
    dts 中描述中断(示例):
    dts
    my_device {

    interrupts = <GIC_SPI 100 IRQ_TYPE_EDGE_FALLING>; // GIC 中断,SPI 类型,边沿触发

    interrupt-parent = <&gic>;

    };

  4. 调试工具

    • 查看中断状态:cat /proc/interrupts
    • 统计中断次数:通过 proc 文件系统或 irq_stat 数组(需内核配置支持)。

四、示例代码框架

c

my_work

irq_num

work

irq dev_id

my_work

IRQ_HANDLED

pdev

irq_num pdevdevof_node

irq_num

irq_num

my_work my_work_handler

ret irq_num my_irq_handler IRQF_TRIGGER_FALLING

ret

ret

pdev

irq_num

my_driver

probe my_probe

remove my_remove

driver

name

of_match_table my_of_ids

my_driver

五、总结

  1. 分离上下半部:确保上半部快速执行,下半部处理复杂逻辑。
  2. 选择合适的下半部
    • 高性能场景:tasklet / 软中断(不可睡眠)。
    • 需睡眠场景:工作队列 / 线程化中断处理函数。

  3. 错误处理:注册中断时检查返回值,避免资源泄漏。

通过以上步骤,可在 Linux 驱动中正确实现中断处理,平衡实时性与系统性能。

阅读更多 >>>  linux固定中断号如何分配
← 上一篇: 下一篇:

网站数据信息

"linux中断如何使用"浏览人数已经达到19次,如你需要查询该站的相关权重信息,可以点击进入"Chinaz数据" 查询。更多网站价值评估因素如:linux中断如何使用的访问速度、搜索引擎收录以及索引量、用户体验等。 要评估一个站的价值,最主要还是需要根据您自身的需求,如网站IP、PV、跳出率等!