Linux 中断下半部
为什么使用中断下半部?
中断执行的原则是要以最快的速度执行完,而且期间不能延时和休眠!
可是现实中,中断中可能没办法很快的处理完需要做的事,或者必须用到延时和休眠,因此引入了中断下半部。
中断中处理紧急事务,其余的交给中断下半部处理。
怎样将代码合理有效的分配给中断和中断下半部?(以后发现新的再添加)
与硬件有关的给中断处理程序(比如按键中断后判断电平),其余的给中断下半部;
紧急事务给中断处理程序,相对不紧急的给中断下半部;
不能被中断的给中断处理程序,剩余的给中断下半部;
没有延时或休眠的给中断处理程序,有休眠或延时的给中断下半部(延时只能用工作队列);
中断下半部有三种实现方法:软中断,小任务,工作队列
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 = ) : (key_dev->key.value = );
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();
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, );
... ...
} 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 = ) : (key_dev->key.value = );
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();
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);
... ...
}
Linux 中断下半部的更多相关文章
- linux中断的上半部和下半部 【转】
转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=24690947&id=3491821 一.什么是下半部 中断是一 ...
- 《Linux内核设计与实现》读书笔记(八)- 中断下半部的处理
在前一章也提到过,之所以中断会分成上下两部分,是由于中断对时限的要求非常高,需要尽快的响应硬件. 主要内容: 中断下半部处理 实现中断下半部的机制 总结中断下半部的实现 中断实现示例 1. 中断下半部 ...
- linux驱动学习笔记---实现中断下半部以及驱动编写规范(七)【转】
转自:https://blog.csdn.net/weixin_42471952/article/details/81609141 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协 ...
- linux中断申请之request_threaded_irq
转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=21977330&id=3755609 在linux里,中断处理分 ...
- 驱动: 中断【1】linux中断流程
通常情况下,当一个给定的中断处理程序正在执行时,所有其他的中断都是打开的,所以这些不同中断线上的其他中断都能被处理,但当前中断总是被禁止的. 将中断处理切为两个部分或两半.中断处理程序上半部(top ...
- Linux中断子系统:级联中断控制器驱动
Linux中断子系统 Linux中断子系统是个很大的话题,如下面的思维导图所示,包含硬件.驱动.中断上半部.中断下半部等等.本文着眼于中断控制器(PIC),特别是级联中断控制器驱动部分,对驱动的设计和 ...
- Linux中断管理
CPU和外设之间的交互,或CPU通过轮询机制查询,或外设通过中断机制主动上报. 对大部分外设中断比轮询效率高,但比如网卡驱动采取轮询比中断效率高. 这里重点关注ARM+Linux组合下中断管理,从底层 ...
- Linux中断管理 (1)Linux中断管理机制
目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机制> <Linux中断管理 (2)软中断和tasklet> <Linux中断管 ...
- Linux中断管理 (2)软中断和tasklet
目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机制> <Linux中断管理 (2)软中断和tasklet> <Linux中断管 ...
随机推荐
- LINUX系统运行查看
1.查看内存使用情况 free -m 2.查看内存,cpu等使用情况排序,使用ps -aux命令 ps -aux --sort=+rss :按内存升序排列 ps -aux --sort=-rss :按 ...
- 如何理解Hibernate的延迟加载机制?在实际应用中,延迟加载与Session关闭的矛盾是如何处理的?
延迟加载就是并不是在读取的时候就把数据加载进来,而是等到使用时再加载.Hibernate使用了虚拟代理机制实现延迟加载,我们使用Session的load()方法加载数据或者一对多关联映射在使用延迟加载 ...
- jQuery.fn.extend() jQuery.extend()
是jQuery为开发插件提拱了两个方法 jQuery.fn jQuery.fn = jQuery.prototype = { init: function( selector, context ) { ...
- Search insert position, 查找插入位置
问题描述:给定一个有序序列,如果找到target,返回下标,如果找不到,返回插入位置. 算法分析:依旧利用二分查找算法. public int searchInsert(int[] nums, int ...
- Apache顶级项目 Calcite使用介绍
什么是Calcite Apache Calcite是一个动态数据管理框架,它具备很多典型数据库管理系统的功能,比如SQL解析.SQL校验.SQL查询优化.SQL生成以及数据连接查询等,但是又省略了一些 ...
- js 格式化时间日期函数小结2
方法一: // 对Date的扩展,将 Date 转化为指定格式的String // 月(M).日(d).小时(h).分(m).秒(s).季度(q) 可以用 1-2 个占位符, // 年(y)可以用 ...
- IT技术栈、JAVA技术栈、游戏开发技术栈
一.形成IT思想,把各种技术融会贯通,使用时按需对技术选型. 二.对于每个知识点,框架的掌握依次分为三层. 1.会使用 2.熟悉原理 3.了解源码 三.思维导图
- Ajax-02 iframe实现伪“Ajax”
需求: 用户输入URL,使用iframe将目标URL的内容加载到页面指定位置(局部刷新) <!DOCTYPE html> <html lang="en"> ...
- HYSBZ - 2005 莫比乌斯反演
链接 对于gcd(i,j)的位置来说,对答案的贡献是2*(gcd(i,j)-1)+1,所以答案ans ans=Σ(1<=i<=n)(1<=j<=m)2*(gcd(i,j)-1) ...
- URL的编码
+ URL 中+号表示空格 %2B 空格 URL中的空格可以用+号或者编码 %20 / 分隔目录和子目录 %2F ? 分隔实际的 URL 和参数 %3F % 指定特殊字符 %25 # 表示书签 %23 ...