<什么是中断>
计算停下当前处理任务,并保存现场,转而去处理其他是任务,当完成任务后再回到原来的任务中去。
<中断的分类>
a:软中断
    软中断时执行中断指令产生的,软中断不用施加中断请求信号,因此中断的产生的不是随机的而是由程序安排的。内核线程是实现软中断的助手。
b:硬中断
    硬中断时由外部硬件产生的,具有随机性。
 
<中断的实现>
int request_irq(unsigned int irq,irq_handler_t handler,unsigned long intflags,const char devname, void *dev_id)
解释:
irq:申请的中断号。
handler:中断处理函数指针
irqflags:中断处理属性,与上半段和下半段有关系
devname:中断设备名字
dev_id:与共享中断号有关系。
注:该函数的主要作用是在内核中的一个重要的结构体"irq_desc"中注册中断号与对应的中断处理函数。
 
<释放中断线>
void free_irq(unsigned int irq ,void dev_id);
注:一般操作硬件的端口都会调用ioremap()函数,该函数用来将计算实际的物理地址映射成虚拟地址,这样系统才能访问。
 
<中断处理机制之上半部分和下半部>
a:Linux中中断处理是一种很霸道的东西,只要没有屏蔽中断,CPU就会立即相应。为了加开处理的数据,Linux中通常将 中断处理中的硬件相关的操作放在上半部分,耗时的操作放在下半部分——linux 内核一般将中断处理分为两不份:上半部(top_half)和下半部(bottom_half)。
b:上半部分
    一般调用中断处理函数,一进入中断处理函数就是进行相应的硬件操作,这些都是放在上半部分。然后将耗时的操作放在下半部分中。
c:下半部分
Linux中实现下半部分的处理有:softirq机制,tasklist机制(小任务片段),workqueue机制
----tasklet将任务延迟到安全时间执行,每个tasklet都和一个函数相关联,当tasklet运行时,
----该函数就被调用,并且tasklet可以调度自己。
d:Tasklet的实现
(1)定义一个处理函数:
void tasklet_func(unsigned  long);
定义一个tasklet结构my_tasklet与tasklet_func(data)函数关联
struct tasklet_struct  my_tasklet;
DECLARE_TASKLET(my_tasklet,tasklet_func,data);
调度tasklet
tasklet_schedule(&my_tasklet);
e:工作队列和下半部处理
工作队列使用方法和tasklet非常相似
(1)定义一个工作队列:
(2)struct work_struct  my_wq;
定义一个处理函数
void my_wq_func(struct work_struct  *work);
(3)初始化工作队列并将其处理函数绑定
INIT_WORK(&my_wq,my_wq_func);
(4)调度工作队列执
schedule_work(&my_wq);//该函数将其提交给内核默认工作者队列线程
queue_work();//该函数会将其提交给专用的工作者线程(可以是自己定义的)
f:Tasklet和工作队列的区别
(1)tasklet工作在中断上下文
(2)工作队列工作在进程上下文
(3)tasklet处理函数中不能睡眠
(4)工作队列中允许有睡眠
 
注:软中断和tasklet
(1)软中断定义
struct softirq_action{
Void(*action)(struct softirq_action *)
并且当前内核中的软中断总数固定为32个,由数组Static struct softirq_action softirq_vec[NR_SOFTIRQS]来表示。
目前只用到了其中的9个。包括定时器、网络、tasklet等。一旦有软中断产生就会查询soft_vec[]看查看哪个软中断被挂起了。然后执行:
h=softirq_vec;
h->action(h) ;//执行对应的软中断action函数。
(2)软中断的使用
open_softirq()挂起软中断处理函数:
open_softirq(TASKLET_SOFTIRQ,tasklet_action);//tasklet_action位软中断处理函数
(3)触发软中断
rase_softirq(TASKLET_SOTFIRQ);//处理器就会在适当的时候执行软中断处理函数tasklet_action
总结:tasklet(小任务)是对软中断的一种个封装。
 

linux 驱动中的中断处理程序:

当发生中断的时候,无论是裸机程序还是Linux系统都会有一个统一的入口.

裸机中的中断入口是代码:ldr pc,_irq;

linux 系统中的统一入口:irq_svc

向Linux系统注册中断处理程序想:

requst_irq(unsigned int irq ,void(*handler)(int ,void *,struct pt_regs*),unsigned long flags,const char *devname ,void *dev_id )

参数分析:

unsigned long flags:参数还是一个宏,用于决定是快速中断还是慢速中断,或者表明该中断是多少个设备共享。

unsigned int irq:

向Linux系统注销中断处理程序:

void free_irq(unsigned int irq ,void *dev_id)

参数分析:

int irq:中断号,注意这里的中断号和裸机中的中断号有一定的不同,因为系统预留了16个的软中断号,所以硬件中断号需要加上16,系统通过中断号找到相应的描述符表,在描述符表中找到相应个处理函数。

dev_id:对于共享中断号的设备,需要提供相应的中断号才能准确的注销掉。

中断嵌套:

为了解决中断处理速度,Linux中将硬件处理函数和非硬件处理函数进行了分开,将非硬件操作放到工作队列中。

注意:工作队列中的结构体数组名都是使用一个struct 在后面

定义和描述中断队列:

struct workqueue_struct {

struct cpu_workqueue_struct *cpu_wq;

struct list_head list;

const char *name; /*workqueue name*/

int singlethread;

int freezeable; /* Freeze threads during suspend */

int rt;

}

定义和描述一个工作:

struct work_struct {

atomic_long_t data;

struct list_head entry;

work_func_t func;

};

创建一个工作队列:
srtuct workqueue_struct * =create_workqueue(“workqueue_name”)

初始化工作:

INIT_WORK(struct work_struct *,func)

注意:创建工作实质是将创建的工作和相应的操作函数关联起来

向Linux系统提交工作

queue_work(struct workqueue_struct , func)

在大多数情况下,并把需要定义工作队列,Linux内核中已经有一个默认的工作队列keventd_wq,所以只需要创建工作,并初始化工作。

提交默认工作队列:

schedule_work()

按键去抖之内核定时器:

定义并描述定时器:

struct timer_list {

struct list_head entry;

unsigned long expires;

void (*function)(unsigned long);

unsigned long data;

struct tvec_base *base;

};

初始化定时器:

init_timer(struct list_timer * keytimer)

keytimer.function = key_timerfunc()

找一个地方定义timerfunc()

想Linux注册定时器:

add_timer(struct timer_list *)

启动定时器:

mod_timer(struct list_timer * ,jiffes+Hz/2)

阻塞型驱动:

背景:

当计算机驱动访问一个硬件的时候发现访问条件不满足,称之为阻塞,这时就需要将该驱动放入到等待队列中。

定义等待队列:

wait_queue_head_t  my_queue

初始化等待队列:

init_waitqueue_head( wai_queue_head_t* )

备注:定义并初始化等待队列

DECLARE_WAIT_QUEUE_HEAD(wait_queue_head_t  my_queue)

进入等待队列:

wait_event(queue,condition)  //TASK_UNINTERRUPT 模式

wait_event_interrupt(queue,condition)//TASK_INTERRUPT  模式

int wait_event_killable(queue,condition) //TASK_KILLABLE 模式

函数分析:

以上两个函数,在条件满足时,直接返回,并继续执行相应的下面的程序,当条件不满足时则挂载到等待队列中,知道被唤醒。

唤醒等待队列:

wake_up(wait_queue_t *q)  //从等待队列中唤醒,所有TASK_UNINTERRUPT ,TASK_INTERRUPT ,TASK_KILLABLE 状态的所有进程。

wake_up_intterruptible(wait_queue_t *q)//从等待队列q中唤醒状态仅为INTERRUPTIBLE 状态的队列。

设备驱动在内存中开辟内存:

kmalloc()

注意:该函数返回的是物理地址

释放内存:

kfree()

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

 
 
 
 

Linux内核中断处理机制的更多相关文章

  1. [内核同步]浅析Linux内核同步机制

    转自:http://blog.csdn.net/fzubbsc/article/details/37736683?utm_source=tuicool&utm_medium=referral ...

  2. Linux内核同步机制--转发自蜗窝科技

    Linux内核同步机制之(一):原子操作 http://www.wowotech.net/linux_kenrel/atomic.html 一.源由 我们的程序逻辑经常遇到这样的操作序列: 1.读一个 ...

  3. Linux内核同步机制

    http://blog.csdn.net/bullbat/article/details/7376424 Linux内核同步控制方法有很多,信号量.锁.原子量.RCU等等,不同的实现方法应用于不同的环 ...

  4. 浅析Linux内核同步机制

    非常早之前就接触过同步这个概念了,可是一直都非常模糊.没有深入地学习了解过,最近有时间了,就花时间研习了一下<linux内核标准教程>和<深入linux设备驱动程序内核机制>这 ...

  5. Linux内核同步机制之(四):spin lock【转】

    转自:http://www.wowotech.net/kernel_synchronization/spinlock.html 一.前言 在linux kernel的实现中,经常会遇到这样的场景:共享 ...

  6. Linux内核OOM机制的详细分析(转)

    Linux 内核 有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了 防止内存耗尽而内核会把该进程杀掉.典 ...

  7. Linux内核同步机制之(五):Read Write spin lock【转】

    一.为何会有rw spin lock? 在有了强大的spin lock之后,为何还会有rw spin lock呢?无他,仅仅是为了增加内核的并发,从而增加性能而已.spin lock严格的限制只有一个 ...

  8. Linux内核同步机制之completion【转】

    Linux内核同步机制之completion 内核编程中常见的一种模式是,在当前线程之外初始化某个活动,然后等待该活动的结束.这个活动可能是,创建一个新的内核线程或者新的用户空间进程.对一个已有进程的 ...

  9. Linux内核NAPI机制分析

    转自:http://blog.chinaunix.net/uid-17150-id-2824051.html 简介:NAPI 是 Linux 上采用的一种提高网络处理效率的技术,它的核心概念就是不采用 ...

随机推荐

  1. 微服务深入浅出(8)-- 配置中心Spring Cloud Config

    Config Server从本地读取配置文件 将所有的配置文件统一写带Config Server过程的目录下,Config Server暴露Http API接口,Config Client调用Conf ...

  2. 天梯赛 L2-022. (数组模拟链表) 重排链表

    题目链接 题目描述 给定一个单链表 L1→L2→...→Ln-1→Ln,请编写程序将链表重新排列为 Ln→L1→Ln-1→L2→....例如:给定L为1→2→3→4→5→6,则输出应该为6→1→5→2 ...

  3. Postman和Selenium IDE开局自带红蓝BUFF属性,就问你要还是不要

    话不多说,下面给大家介绍两款工具,selenium IDE和Postman. 为什么说是自带红蓝Buff,因为想做UI自动化和接口自动化的同学,很多时候,都难在了开头. 比如你要学习语言,你要学习框架 ...

  4. TableView 的那些坑

    1. 分割线填满cell宽度, 并且设置分割线的颜色 1.1 利用系统的分割线填充 1.1.1 tableView 设置如下属性 // 给tableView设置如下属性值 tableView.layo ...

  5. js中字符串的常用方法

    一.普通方法 1.字符方法 动态方法:1.str.charAt(index);  返回子字符串,index为字符串下标,index取值范围[0,str.length-1] 动态方法:2.str.cha ...

  6. [shell]shell中if语句的使用

    转自:http://lovelace.blog.51cto.com/1028430/1211353 bash中如何实现条件判断?条件测试类型:    整数测试    字符测试    文件测试 一.条件 ...

  7. echarts一些笔记

    console.log();  浏览器显示 $.ajax({ url : "ajax/echartWelcome.action", type : "post", ...

  8. HTML网页自动跳转

    <meta http-equiv="refresh" content="3;URL=res.html">

  9. 如何使用 JMeter 调用你的 Restful Web Service?进行简单的压力测试和自动化测试

    表述性状态传输(REST)作为对基于 SOAP 和 Web 服务描述语言(WSDL)的 Web 服务的简单替代,在 Web 开发上得到了广泛的接受.能够充分证明这点的是主流 Web 2.0 服务提供商 ...

  10. 毕设demo写好

    2015年1月20日 14:41:47 阶段性暂停!! 把运行结果截图给了老师,老师说先整理下文档,然后下学期来了再部署到服务器上. 那么,下学期来了,估计也要把Epm和CR1000什么的搞好了. 先 ...