为什么使用中断下半部?

中断执行的原则是要以最快的速度执行完,而且期间不能延时和休眠!

可是现实中,中断中可能没办法很快的处理完需要做的事,或者必须用到延时和休眠,因此引入了中断下半部。

中断中处理紧急事务,其余的交给中断下半部处理。

怎样将代码合理有效的分配给中断和中断下半部?(以后发现新的再添加)

与硬件有关的给中断处理程序(比如按键中断后判断电平),其余的给中断下半部;

紧急事务给中断处理程序,相对不紧急的给中断下半部;

不能被中断的给中断处理程序,剩余的给中断下半部;

没有延时或休眠的给中断处理程序,有休眠或延时的给中断下半部(延时只能用工作队列);

中断下半部有三种实现方法:软中断,小任务,工作队列

1、软中断---softirq

软中断一般用在内核级别的代码中,现在不讨论

2、小任务---tasklet

tasklet中不能延时或休眠

struct tasklet_struct
{struct tasklet_struct *next; unsigned long state;             // tasklet 状态atomic_t count;                     // 锁计数器void (*func)(unsigned long);  // tasklet 处理函数unsigned long data;               // 传递给 tasklet 处理函数的参数
};

// 功能:初始化 tasklet

// 参数1:被初始化的 tasklet

// 参数2:中断下半部函数入口

// 参数3:传递给中断下半部函数的参数

static inline void tasklet_init(struct tasklet_struct *tasklet, void (*func)(unsigned long), unsigned long data);

// 功能:启动下半部

// 参数:tasklet

static inline void tasklet_schedule(struct tasklet_struct *tasklet);

// 功能:释放 tasklet

// 参数: tasklet

void tasklet_kill(struct tasklet_struct *t);

struct key_event
{int name;int value;
};struct samsung
{int major;struct class *cls;struct device *dev;struct key_event key;struct tasklet_struct tasklet;
};static struct samsung *key_dev;void tasklet_key_irq(unsigned long data)
{printk("___^_^___ %s\n", __FUNCTION__);
}// 中断处理程序,多个按键可以根据 irqno 区分
irqreturn_t key_irq_handler(int irqno, void *dev_id)
{  int ret;  printk("------------%s-------------\n", __FUNCTION__);  ret = gpio_get_value(key_info[i].key_gpio);  ret ? (key_dev->key.value = 0) : (key_dev->key.value = 1);  printk("key = %d status = %d\n", key_dev->key.name, key_dev->key.value);  tasklet_schedule(&key_dev->tasklet);// 返回值一定要是 IRQ_HANDLED  return IRQ_HANDLED;
}  static int __init key_drv_init(void)
{  ... ...  key_dev->irqno = IRQ_EINT(2);  ret = request_irq(key_dev->irqno, key_irq_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "key_eint", NULL);tasklet_init(&key_dev->tasklet, tasklet_key_irq, 110);... ...
}  static int __exit key_drv_exit(void)
{  ... ...  tasklet_kill(&key_dev->tasklet);free_irq(key_dev->irqno,NULL);  ... ...
} 

3、工作队列---work queue

work queue 中不能延时或休眠

// 功能:初始化work

// 参数1:被初始化的work

// 参数2:中断下半部的入口函数

INIT_WORK(_work, _func)

// 功能:启动下半部

// 参数:work

int schedule_work(struct work_struct *work);

// 功能:释放work

// 参数:work

bool cancel_work_sync(struct work_struct *work);

struct key_event
{int name;int value;
};struct samsung
{int major;struct class *cls;struct device *dev;struct key_event key;struct work_struct work;
};static struct samsung *key_dev;void work_key_irq(struct work_struct *work)
{printk("___^_^___ %s\n", __FUNCTION__);
}// 中断处理程序,多个按键可以根据 irqno 区分
irqreturn_t key_irq_handler(int irqno, void *dev_id)
{  int ret;  printk("------------%s-------------\n", __FUNCTION__);  ret = gpio_get_value(key_info[i].key_gpio);  ret ? (key_dev->key.value = 0) : (key_dev->key.value = 1);  printk("key = %d status = %d\n", key_dev->key.name, key_dev->key.value);  schedule_work(&key_dev->work);// 返回值一定要是 IRQ_HANDLED  return IRQ_HANDLED;
}  static int __init key_drv_init(void)
{  ... ...  key_dev->irqno = IRQ_EINT(2);  ret = request_irq(key_dev->irqno, key_irq_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "key_eint", NULL);INIT_WORK(&key_dev->work, work_key_irq);... ...
}  static int __exit key_drv_exit(void)
{  ... ...  cancel_work_sync(&key_dev->work);free_irq(key_dev->irqno,NULL);  ... ...
}

转载于:https://www.cnblogs.com/lialong1st/p/7756672.html

Linux 中断下半部相关推荐

  1. linux中断下半部

    linux中断下半部 6.1下半部 下半部的任务就是执行与中断处理密切相关但中断处理程序本身不执行的工作.对于在上半部和下半部之间划分工作,尽管不存在某种严格的规则,但还是有一些提示可供借鉴:(1)如 ...

  2. 【Linux驱动编程】Linux中断上半部和下半部

    前言   cpu在执行程序时,如果有外部中断触发时,如定时器中断.串行总线中断等,cpu停止当前任务从而转去响应中断处理.对于中断函数的处理,原则是尽快处理完事务并退出中断,这一点也比较好理解,尽快处 ...

  3. linux中断的上半部和下半部

    原文地址:linux中断的上半部和下半部 作者:td1442911376 http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=246 ...

  4. Linux内核深入理解中断和异常(7):中断下半部:Softirq, Tasklets and Workqueues

    Linux内核深入理解中断和异常(7):中断下半部:Softirq, Tasklets and Workqueues rtoax 2021年3月 0x00-0x1f architecture-defi ...

  5. Linux网络协议栈:中断下半部处理

    <Linux中断处理:上半部和下半部> <Linux网络协议栈:中断下半部处理> 目录 数据包上送 网络中断下半部处理 总结 推荐阅读 在<Linux网络协议栈:网络包接 ...

  6. linux设备驱动归纳总结(六):3.中断下半部之tasklet

    CU首页 ┊ fh265>>博客 微博 相册 个人中心 好友 消息 [退出] ┊ 随便看看 公告:缅怀Dennis Ritchie活动开赛啦! 小白的博客--提升自已,分享别人 xiaob ...

  7. linux AArch64中断下半部之软中断softirq

    linux AArch64中断下半部之软中断softirq 1 软中断的概念 2 软中断执行的时机 2.1 软中断执行时机 2.2 irq_exit 2.3 invoke_softirq 3 软中断关 ...

  8. vrml场景实例代码_高并发的中断下半部tasklet实例解析

    本文转自AliDataOps 最近为了解决一个技术问题,需要用到内核里中断下半部的tasklet机制,使用过程遇到了非常有趣的问题.在解决问题过程中,也逐步加深了对tasklet机制的理解.本文把这些 ...

  9. arm Linux 中断管理机制

    关键词:GIC.IAR.EOI.SGI/PPI/SPI.中断映射.中断异常向量.中断上下文.内核中断线程.中断注册. 1.1 ARM支持中断类型 ARM GIC-v2支持三种类型的中断: SGI:软件 ...

  10. Linux 中断实验

    目录 Linux 中断简介 Linux 中断API 函数 上半部与下半部 设备树中断信息节点 获取中断号 硬件原理图分析 实验程序编写 修改设备树文件 按键中断驱动程序编写 编写测试APP 运行测试 ...

最新文章

  1. Parser Generator Tips翻译(中英对译) by Joshua Xu
  2. mysql 导出dmp文件_Mysql数据库的各种命令:
  3. phphstudy运行不了网站_网站SEO优化之如何维护网站权重?
  4. 苏炫杰全国计算机等级考试,高二升高三的主题班会
  5. 死磕Android_App 启动过程(含 Activity 启动过程)
  6. java开始到熟悉100-102
  7. PHP获取当前域名的记录
  8. 同步电机是如何达到同步的?工作原理是什么?
  9. 李峋同款爱心代码!跳动的心,给你爱的人一个惊喜!
  10. 如何设置或关闭访客进来的铃声
  11. 【推荐】1657- 灵活可扩展,2023年值得尝试的13款富文本编辑器
  12. 手机投屏到电脑_低延迟,传声音
  13. 期权、期货及其他衍生产品 第四章读书笔记 利率
  14. 【数据结构】Java版
  15. C语言中常用的占位符
  16. vue使用常见问题及解决方案
  17. kodi直播电视,电视台分类管理,想看哪个一目了然
  18. A ConvNet for the 2020s 论文笔记
  19. 不念过往,不畏将来——告别曾经
  20. 应届生,找java后端开发要什么水平才算合格?

热门文章

  1. 手机突然变卡,不得不重置
  2. LINUX下载编译libks
  3. LINUX C获取并设置环境变量
  4. CSDN终端数据更新不同步?
  5. 由数字规律谈历史的前定
  6. python中把输出结果写到一个文件中_python 文件中字符串过滤,并将结果输出到另一个文件中(源码)...
  7. VS C# string 字符包含判断
  8. 用C#代码实现求两条线段的交点并判断各种情况
  9. linux ssl 脚本 51cto,升级opensslopenssh的shell脚本
  10. php yii vendor,Yii2的安装--解决无Vendor目录的问题