Linux中断处理(二)
与Linux设备驱动中中断处理相关的首先是申请与释放IRQ的API request_irq()和free_irq(),request_irq()的原型为:
int request_irq(unsigned int irq,void (*handler)(int irq, void *dev_id, struct pt_regs *regs), unsigned long irqflags, const char * devname, void *dev_id);
irq是要申请的硬件中断号;
handler是向系统登记的中断处理函数,是一个回调函数,中断发生时,系统调用这个函数,dev_id参数将被传递;
irqflags是中断处理的属性,若设置SA_INTERRUPT,标明中断处理程序是快速处理程序,快速处理程序被调用时屏蔽所有中断,慢速处理程序不屏蔽;若设置SA_SHIRQ,则多个设备共享中断;
dev_id在中断共享时会用到,一般设置为这个设备的device结构本身或者NULL。
free_irq()的原型为:
void free_irq(unsigned int irq,void *dev_id);
另外,与Linux中断息息相关的一个重要概念是Linux中断分为两个半部:上半部(top half)和下半部(bottom half)。上半部的功能是"登记中断",当一个中断发生时,它进行相应地硬件读写后就把中断例程的下半部挂到该设备的下半部执行队列中去。因此,上半部执行的速度就会很快,可以服务更多的中断请求。但是,仅有"登记中断"是远远不够的,因为中断的事件可能很复杂。因此,Linux引入了一个下半部,来完 成中断事件的绝大多数使命。下半部和上半部最大的不同是下半部是可中断的,而上半部是不可中断的,下半部几乎做了中断处理程序所有的事情,而且可以被新的中断打断!下半部则相对来说并不是非常紧急的,通常还是比较耗时的,因此由系统自行安排运行时机,不在中断服务上下文中执行。
Linux实现下半部的机制主要有tasklet和工作队列。
tasklet基于Linux softirq,其使用相当简单,我们只需要定义tasklet及其处理函数并将二者关联:
void my_tasklet_func(unsigned long); //定义一个处理函数:
DECLARE_TASKLET(my_tasklet,my_tasklet_func,data); //定义一个tasklet结构my_tasklet,与my_tasklet_func(data)函数相关联;然后,在需要调度tasklet的时候引用一个简单的API就能使系统在适当的时候进行调度运行:
tasklet_schedule(&my_tasklet);
此外,Linux还提供了另外一些其它的控制tasklet调度与运行的API:
DECLARE_TASKLET_DISABLED(name,function,data); //与DECLARE_TASKLET类似,但等待tasklet被使能
tasklet_enable(struct tasklet_struct *); //使能tasklet
tasklet_disble(struct tasklet_struct *); //禁用tasklet
tasklet_init(struct tasklet_struct *,void (*func)(unsigned long),unsigned long); //类似DECLARE_TASKLET()
tasklet_kill(struct tasklet_struct *); // 清除指定tasklet的可调度位,即不允许调度该tasklet
我们先来看一个tasklet的运行实例,这个实例没有任何实际意义,仅仅为了演示。它的功能是:在globalvar被写入一次后,就调度一个tasklet,函数中输出"tasklet is executing":
代码:
tasklet使用模板
//定义tasklet和底半部函数并关联
void xxx_do_tasklet(unsigned long);
DECLARE_TASKLET(xxx_tasklet, xxx_do_tasklet, 0);
//中断底半部处理
void xxx_do_tasklet(unsigned long)
{
……………
}
//中断处理顶半部
irqreturn_t xxx_interrupt(int irq, void * dev_id, struct pt_regs * regs)
{
……
tasklet_schedule(&xxx_tasklet);
……
}
//设备驱动模块加载函数
int __init xxx_init(void)
{
…………
//申请中断
result = request_irq(xxx_irq, xxx_interrupt, SA_INTERRUPT, “xxx”, NULL);
…………
}
//设备驱动模块卸载函数
void __exit xxx_exit(void)
{
……………
//释放中断
free_irq(xxx_irq, xxx_interrupt);
……………
}
工作队列使用模板
//定义工作队列和关联函数
struct work_struct xxx_wq;
void xxx_do_work(unsigned long);
//中断处理底半部
void xxx_do_work(unsigned long)
{
………………
}
//中断处理顶半部
irqreturn_t xxx_interrupt( int irq, void * dev_id, struct pt_regs * regs)
{
…………
schedule_work(&xxx_wq);
…………
}
//设备驱动模块加载函数
int xxx_int(void)
{
…………
result = request_irq(xxx_irq, xxx_interrupt, SA_INTERRUPT, “xxx”, NULL);
//初始化工作队列
INIT_WORK(&xxx_wq, (void (*) (void *)) xxx_do_work, NULL);
…………….
}
//设备驱动模块卸载函数
void xxx_exit(void)
{
……………
free_irq(xxx_irq, xxx_interrupt);
………….
}
共享中断编程模板
//中断处理顶半部
irqreturn_t xxx_interrupt(int irq, void * dev_id, struct pt_regs * regs)
{
………………
int status = read_int_status();//获知中断源
if(!(is_myint(dev_id, status))//判断时候是本设备中断
{
return IRQ_NONE;
}
………….
return IRQ_HANDLED;
}
//设备驱动模块加载函数
int xxx_init(void)
{
……………
//申请共享中断
result = request_irq( sh_irq, xxx_interrupt, SA_SHIRQ, “xxx”, xxx_dev);
………………
}
//卸载函数
void xxx_exit(void)
{
………………
free_irq(xxx_irq, xxx_interrupt);
……………
}
参考链接:http://blog.chinaunix.net/uid-20583479-id-1920131.html
Linux中断处理(二)的更多相关文章
- linux中断处理原理分析
Tasklet作为一种新机制,显然可以承担更多的优点.正好这时候SMP越来越火了,因此又在tasklet中加入了SMP机制,保证同种中断只能在一个cpu上执行.在软中断时代,显然没有这种考虑.因此同一 ...
- Linux中断处理体系结构分析
Linux中断处理体系结构分析(一) 异常,就是可以打断CPU正常运行流程的一些事情,比如外部中断.未定义指令.试图修改只读的数据.执行swi指令(Software Interrupt Instruc ...
- linux中断处理上下部分
一.linux中断处理为什么要分为上下部 1.1. 中断处理的上半部(top half,又叫顶半部)和处理的下半部(bottom half,又叫底半部) 1.1. linux中断处理不参与调度,故中断 ...
- Linux.中断处理.入口x86平台entry_32.S
Linux.中断处理.入口x86平台entry_32.S Linux.中断处理.入口x86平台entry_32.S 在保护模式下处理器是通过中断号和IDTR找到中断处理程序的入口地址的.IDTR存的是 ...
- [国嵌攻略][119][Linux中断处理程序设计]
裸机中断: 1.中断统一入口. 2.注册中断处理程序. 3.根据中断源编号,调用中断处理程序. Linux中断 1.在entry-armv.S中的_irq_svc是中断统一入口. 2.获取产生中断源的 ...
- Linux(二)—— Unix&Linux 的基本概念
Linux(二)-- Unix&Linux 的基本概念 计算机 = 主机(host)+ 终端(terminal) 主机 = 内核 + 实用工具 内核(kernel) 当计算机启动时,计算机要经 ...
- 一、Linux概述 二、Linux的安装 三、Linux的常用命令(重点)
一.Linux概述###<1>操作系统 OS,管理和控制 计算机的 硬件和软件资源的 计算机程序. 最基本的系统软件. 是用户和计算机交互的桥梁,是硬件和软件交互的桥梁. 操作系统:she ...
- Linux(二):VMware虚拟机中Ubuntu安装详细过程
Linux(二):VMware虚拟机中Ubuntu安装详细过程 目录 1 准备 2 安装 2.1 虚拟机的建立 2.2 虚拟机安装Ubuntu系统 2.3 虚拟机设置 3 完成 1 准备 1.操作系统 ...
- Linux中断处理驱动程序编写【转】
转自:http://blog.163.com/baosongliang@126/blog/static/1949357020132585316912/ 本章节我们一起来探讨一下Linux中的中断 中断 ...
随机推荐
- 运行vb写的程序,有些电脑上会弹出一个与office相关的窗口
到网上搜索了一下,找了几个解决方案,不过我的电脑上没出现过,所以先收藏一下,或许以后能用上. 来自:http://bbs.csdn.net/topics/380204412 今天将注册表的项一个个删除 ...
- vi怎么查找关键字
进入vi的命令模式,具体操作:编辑模式下键入“:”,此时进入命令模式 在命令模式下键入“/”.
- mac 终端输入带空格的路径 cd
mac 在终端如何进入名称带空格的目录? 后来找到原因,是因为要对空格转义或者输入“ ”或‘ ’,方案如下: 1. cd Appications/Android\Studio.app/sdk 这个好 ...
- Celery配置实践笔记
说点什么: 整理下工作中配置celery的一些实践,写在这里,一方面是备忘,另外一方面是整理成文档给其他同事使用. 演示用的项目,同时也发布在Github上: https://github.com/b ...
- Java跨平台(系统)的主要原理
Java是可以在系统运行的,主要是Java在执行的时候先通过Java虚拟机JVM,对应不同的操作系统,JVM会采用对应的翻译机制.
- UVALive 4254 Processor(二分)
题目链接 题意 有n个任务,每个任务有三个参数ri,di和wi,表示必须在时刻[ri,di]之内执行,工作量为wi.处理器执行速度可以变化,当执行速度为s时,工作量为wi.处理器的速度可以变化,当执行 ...
- python 小程序,打印数字
要求如下: 指定一个数字 x ,然后打印 1到x 的所有数字,并问是否继续打印,否退出程序,是就继续.再指定一个数字 y ,如果 y> x 就显示 x+1 到 y 的所有数字,y <= x ...
- Element link doesn't have required attribute property
前端标准http://validator.w3.org/ 拒绝你的代码时报 Element link doesn't have required attribute property 把样式链接 &l ...
- 【BZOJ4827】【HNOI2017】礼物
强省HN弱省HA……(读作强省湖南弱省蛤 原题: 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一 个送给她.每个手环上各有 n 个装饰物,并且每个 ...
- 第18月第19天 masonry等分 uilabel sizetofit
1.masonry等分 mas_distributeViewsAlongAxis MASAxisTypeHorizontal 2.uilabel sizetofit +(CGSize)labSizeW ...