一、概述
中断:是指由于接收到来自外围硬件(相对于中央处理器和内存)的异步信号或来自软件的同步信号,而进行相应的硬件/软件处理。
中断:中断其实可以分为同步中断(软中断)和异步中断(异步中断),软中断又叫异常
硬中断可以被另一个优先级比自己高的硬中断“中断”,不能被同级(同一种硬中断)或低级的硬中断“中断”,更不能被软中断“中断”。
软中断可以被硬中断“中断”,但是不会被另一个软中断“中断”。在一个CPU上,软中断总是串行执行,不需要做同步。
抢占分两种情况:用户抢占和内核抢占
内核不能抢占中断,中断例程中不允许进行进程调度,中断中不能使用睡眠和信号量,中断中不能向用户空间发送或接受数据。
中断对临界资源访问,禁止中断,多处理器还必须使用自旋锁来避免来自其他CPU的干扰,中断不会并行。
共享中断就是将不同的设备挂到同一个中断线上。
内核把中断处理分为两部分:上半部(top-half)和下半部(bottom-half),上半部 (就是中断服务程序)内核立即执行,而下半部(就是一些内核函数)留着稍后处理。
实现中断下半部(可以并发执行,谁触发谁执行):
- 软中断请求(softirq)机制,用于紧急场合、主要subsystem会用、驱动基本不用
- 小任务(tasklet)机制 不同片段可并发执行
- 工作队列机制 允许被重新调度甚至是睡眠
二、函数接口
中断函数:
gpio_to_irq
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)
IRQF_DISABLED 则表示中断处理程序是快速处理程序,快速处理程序被调用时屏蔽所有中断,慢速处理程序不屏蔽;
IRQF_SHARED 则表示多个设备共享中断,此时、dev_id不能为空
IRQF_SAMPLE_RANDOM 表示对系统熵有贡献,对系统获取随机数有好处
devname: 设置中断名称,cat /proc/interrupts中可以看到此名称。
返回0表示成功
int request_threaded_irq(unsigned int irq, irq_handler_t handler,
irq_handler_t thread_fn, unsigned long irqflags,
const char *devname, void *dev_id)
thread_fn : 中断线程,类似于中断下半部
IRQF_ONESHOT:表示threadirq线程中关闭该中断,不能与IRQF_SHARED共用
const void *free_irq(unsigned int irq, void *dev_id)
int irq_set_irq_type(unsigned int irq, unsigned int type)
使能或屏蔽中断源:
enable_irq(unsigned int irq);
disable_irq(unsigned int irq); //会等待中断处理完成,再返回
disable_irq_nosync(unsigned int irq);//立即返回
tasklet:
DECLARE_TASKLET(name, func, data)
DECLARE_TASKLET_DISABLED(name, func, data)
void tasklet_schedule(struct tasklet_struct *t)
tasklet_enable tasklet_disable tasklet_kill tasklet_disable_nosync
void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data);
local_bh_disable local_bh_enable :禁止或使能软中断和tasklet 底半部机制
软中断:
struct softirq_action
void open_softirq(int nr, void (*action) (struct softirq_action *))
void raise_softirq(unsigned int nr)
内核定义了10种软中断,一个软中断不会抢占另一个软中断,唯一可以抢占软中断的是硬中断
HI_SOFTIRQ=0,
TIMER_SOFTIRQ,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
BLOCK_SOFTIRQ,
IRQ_POLL_SOFTIRQ,
TASKLET_SOFTIRQ,
SCHED_SOFTIRQ,
HRTIMER_SOFTIRQ,
RCU_SOFTIRQ,
NR_SOFTIRQS
软中断的守护进程ksoftirqd
三、代码示例