Linux 中断实战全览:从硬件到高效处理代码

Linux中断实战:从硬件到高效代码

📖 推荐阅读:《Yocto项目实战教程:高效定制嵌入式Linux系统
🎥 更多学习视频请关注 B 站:嵌入式Jerry


Linux 中断实战全览:从硬件到高效处理代码

继续第一篇中断概念文章,本文将全面解析 Linux 中断实战进程,从设备树配置、高效代码绑定、到上下文处理分离,基于规范化的方式给出一个可复用的中断处理模板。


在这里插入图片描述
在这里插入图片描述

一、硬件实例:GPIO 中断触发

较为普遍的中断源为 GPIO 触发式,例如按键或外部事件通过 GPIO 下降边触发。

设备树配置

button@0 {
    compatible = "myvendor,mybutton";
    gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
    interrupt-parent = <&gpio1>;
    interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
    status = "okay";
};

二、高效代码绑定

处理函数声明

static irqreturn_t mybutton_irq_handler(int irq, void *dev_id)
{
    struct mybutton_data *data = dev_id;

    pr_info("[IRQ] button pressed!\n");

    // 记录事件或调用 workqueue
    schedule_work(&data->work);

    return IRQ_HANDLED;
}

注册中断

ret = devm_request_threaded_irq(&pdev->dev,
            irq, NULL, mybutton_irq_handler,
            IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
            dev_name(&pdev->dev), data);
  • IRQF_TRIGGER_FALLING:下降边触发
  • IRQF_ONESHOT:确保 thread handler 处理完前禁止再次触发

配合 workqueue 实现静态操作

static void mybutton_work_func(struct work_struct *work)
{
    struct mybutton_data *data =
        container_of(work, struct mybutton_data, work);

    pr_info("[WORK] reporting event to user space\n");

    input_report_key(data->input, KEY_ENTER, 1);
    input_sync(data->input);
    input_report_key(data->input, KEY_ENTER, 0);
    input_sync(data->input);
}

三、设备初始化和 input 注册

static int mybutton_probe(struct platform_device *pdev)
{
    struct mybutton_data *data;
    int irq, ret;

    data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
    ...
    INIT_WORK(&data->work, mybutton_work_func);

    data->input = devm_input_allocate_device(&pdev->dev);
    data->input->name = "mybutton";
    data->input->phys = "button/input0";
    data->input->id.bustype = BUS_HOST;

    __set_bit(EV_KEY, data->input->evbit);
    __set_bit(KEY_ENTER, data->input->keybit);

    ret = input_register_device(data->input);
    ...

    irq = platform_get_irq(pdev, 0);
    ret = devm_request_threaded_irq(...);

    platform_set_drvdata(pdev, data);
    return 0;
}

四、中断处理流程总结

[GPIO 下降边]
   ↓
[IRQ Trigger] → irq/xx-mybutton 线程被唤醒
   ↓
mybutton_irq_handler()
   ↓
schedule_work(&data->work)
   ↓
mybutton_work_func()
   ↓
input_report_key() + input_sync()

五、实战经验简要分析

  • 如果需要长时间操作,优先考虑 workqueue 而非硬中断
  • 只要使用 threaded irq,部署违转回代码的风险更小
  • 接入 input 系统可以实现与十分多的应用端打通

综合开发效率模板

步骤要点
设备树interrupts / gpios 配置完整
probeinput_allocate_device, INIT_WORK
注册irqdevm_request_threaded_irq + IRQF_ONESHOT
IRQ handler快速完成,引入 workqueue
work函数input_report_key/input_sync


📖 推荐阅读:《Yocto项目实战教程:高效定制嵌入式Linux系统
🎥 更多学习视频请关注 B 站:嵌入式Jerry


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值