为什么使用中断下半部?

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

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

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

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

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

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

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

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

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

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 中断下半部的更多相关文章

  1. linux中断的上半部和下半部 【转】

    转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=24690947&id=3491821 一.什么是下半部 中断是一 ...

  2. 《Linux内核设计与实现》读书笔记(八)- 中断下半部的处理

    在前一章也提到过,之所以中断会分成上下两部分,是由于中断对时限的要求非常高,需要尽快的响应硬件. 主要内容: 中断下半部处理 实现中断下半部的机制 总结中断下半部的实现 中断实现示例 1. 中断下半部 ...

  3. linux驱动学习笔记---实现中断下半部以及驱动编写规范(七)【转】

    转自:https://blog.csdn.net/weixin_42471952/article/details/81609141 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协 ...

  4. linux中断申请之request_threaded_irq

    转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=21977330&id=3755609 在linux里,中断处理分 ...

  5. 驱动: 中断【1】linux中断流程

    通常情况下,当一个给定的中断处理程序正在执行时,所有其他的中断都是打开的,所以这些不同中断线上的其他中断都能被处理,但当前中断总是被禁止的. 将中断处理切为两个部分或两半.中断处理程序上半部(top ...

  6. Linux中断子系统:级联中断控制器驱动

    Linux中断子系统 Linux中断子系统是个很大的话题,如下面的思维导图所示,包含硬件.驱动.中断上半部.中断下半部等等.本文着眼于中断控制器(PIC),特别是级联中断控制器驱动部分,对驱动的设计和 ...

  7. Linux中断管理

    CPU和外设之间的交互,或CPU通过轮询机制查询,或外设通过中断机制主动上报. 对大部分外设中断比轮询效率高,但比如网卡驱动采取轮询比中断效率高. 这里重点关注ARM+Linux组合下中断管理,从底层 ...

  8. Linux中断管理 (1)Linux中断管理机制

    目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机制> <Linux中断管理 (2)软中断和tasklet> <Linux中断管 ...

  9. Linux中断管理 (2)软中断和tasklet

    目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机制> <Linux中断管理 (2)软中断和tasklet> <Linux中断管 ...

随机推荐

  1. JS复制内容到剪贴板: 兼容IE、Firefox、Chrome、Safari所有浏览器【转】

    正 文: 现在浏览器种类也越来越多,诸如 IE.Firefox.Chrome.Safari等等,因此现在要实现一个js复制内容到剪贴板的小功能就不是一件那么容易的事了. 在FLASH 9 时代,有一个 ...

  2. java父类调用被子类重写的方法

    [转][原文]  1.如果父类构造器调用了被子类重写的方法,且通过子类构造函数创建子类对象,调用了这个父类构造器(无论显示还是隐式),就会导致父类在构造时实际上调用的是子类覆盖的方法(你需要了解jav ...

  3. 平滑重启php

    kill -USR2 `cat /usr/local/webserver/php/var/run/php-fpm.pid`

  4. springboot处理session生命周期

    在使用springboot开发过程中发现用户登陆后60s后session就自动失效了,需要重新登陆,明明 application.yml  文件里已经配置了 server.session.timeou ...

  5. tyvj 1067 合唱队形 dp LIS

    P1067 合唱队形 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 NOIP2004 提高组 第三道 描述     N位同学站成一排,音乐老师要请其中的(N ...

  6. NumPy数据类型

    NumPy - 数据类型 NumPy 支持比 Python 更多种类的数值类型. 下表显示了 NumPy 中定义的不同标量数据类型. 序号 数据类型及描述 1. bool_存储为一个字节的布尔值(真或 ...

  7. scjp考试准备 - 8 - final关键字

    题目,如下代码的执行结果: import java.util.ArrayList; class Pizza{ ArrayList toppings; public final void addTopp ...

  8. python 爬虫001-http请求过程

    HTTP 请求流程 一次完整的HTTP请求过程从TCP三次握手建立连接成功后开始,客户端按照指定的格式开始向服务端发送HTTP请求,服务端接收请求后,解析HTTP请求,处理完业务逻辑,最后返回一个HT ...

  9. WebService是什么?以及工作原理

    WebService 就是一个应用程序,向外界暴露出公开的API使别人其能在WEB对其进行远程调用,具有跨平台和跨语言的等特点,采用Internet的Http协议进行客户端与服务器之间的交互 由XML ...

  10. 十一 web爬虫讲解2—Scrapy框架爬虫—Scrapy使用

    xpath表达式 //x 表示向下查找n层指定标签,如://div 表示查找所有div标签 /x 表示向下查找一层指定的标签 /@x 表示查找指定属性的值,可以连缀如:@id @src [@属性名称= ...