驱动开发------->第五天,中断处理和同步互斥机制

中断处理:

进程和中断上下文的区别:
1. 内核栈不同(进程栈,中断栈)
2. 中断上下文中不允许睡眠(睡眠会触发调度,即引起进程切换)

查看系统中的中断源和中断次数: cat   /proc/interrupts

使用request_irq()注册中断处理函数,使用的中断号是逻辑中断号

irqreturn_t irq_handler(int irq, void *arg)-------->irq_handler(指向中断处理函数的指针),irq(IRQ号),arg(对应的设备ID),该函数指针用于初始化struct irqaction对象中的handler成员
中断处理函数的返回值:处理完成返回IRQ_HANDLED(中断被正常处理),不是本设备产生的中断IRQ_NONE(用于共享中断)

中断处理分为2个部分:
上半部:中断处理函数
下半部(BH):处理复杂或不紧急的任务

实现下半部的方式:
1. SoftIRQ(软中断):不会直接使用
2.   Tasklet(小任务,特定的软中断):回调函数,立即执行
3.   定时器,延后执行
4. 工作队列:内核线程
      立即执行
      延后执行

软中断的执行时机:
1. 在中断处理函数执行完成后,中断返回之前
2. 在ksoftirqd内核线程中执行

区别:***
软中断处理函数也在中断上下文中,因此不能调用睡眠函数
工作队列处于进程上下文,可以调用睡眠函数

工作队列传递参数
struct T {
   struct work_struct work;------>工作队列节点
   int arg;------>节点的ID
};

jiffies时钟中断触发的计数器,每秒钟增加CONFIG_HZ(中断次数)的值。
32无符号长整形 2^32,系统启动5分钟后翻转

同步和互斥机制:


1. 关中断
local_irq_save 保存当前中断状态,并且关中断
local_irq_restore 恢复之前中断状态,开中断

2. 原子操作(单CPU时使用) ***
仅执行一次,在执行过程中不会中断也不会休眠,是最小的执行单元
atomic.h(在这一结构体中,定义的变量为原子变量(整形变量))中的操作
设置标志位或计数时使用

3. 自旋锁 ***
使用循环判断锁的状态,如果已经加锁,一直执行循环操作等待,直到锁被释放
多CPU间互斥时使用
spin_lock_irqsave----->获取自旋锁并关中断,保存当前中断状态到flags(标志寄存器)
spin_unlock_irqrestore----->释放自旋锁并开中断,恢复之前中断状态

4. 读写自旋锁
读读并发,读写和写写互斥
read_lock_irqsave----->获取读锁并关中断,保存当前中断状态flags
read_unlock_irqrestore----->释放读锁并开中断,恢复之前中断状态
write_lock_irqsave----->获取写锁并关中断,保存当前中断状态flags
write_unlock_irqrestore----->释放写锁并开中断,恢复之前中断状态

5. 顺序锁
读读和读写并发,写写互斥
do {
   read_seqbegin---->读之前获取顺序值,函数返回顺序值
while(read_seqretry)---->读完之后检查顺序值是否发生了变化,如果是,则要重读

write_seqlock---->写之前加锁
write_sequnlock----->写之后解锁

}

6. 信号量(睡眠,不能在中断上下文使用)***
down_interruptible------>获取信号量(信号量的值减1),当信号量的值不为0时,可以立即获取信号量,否则进程休眠,但是能够被信号唤醒
up------>释放信号量(信号量的值加1),如果有进程等待信号量,则唤醒这些进程

7. 读写信号量(睡眠)---->本质与信号量一样,这是将读和写分开
读读并发,读写和写写互斥
down_read
down_write

8. 互斥锁(睡眠)***
在进程上下文中给临界区加锁
mutex_lock----->访问共享资源之前获得互斥锁
mutex_unlock------>访问完共享资源后释放互斥锁

9. RCU(read copy update) ***
读读,读写,写写并发
rcu_read_lock----->读者(对共享资源发起读访问操作的代码)进入临界区
rcu_dereference----->读者用于获取共享资源的内存区指针
rcu_read_unlock----->读者退出临界区

10. 完成量(睡眠)***
用于同步,使用等待队列实现
wait_for_completion----->等待其他任务完成某个操作
complete------>某个操作完成后,唤醒等待的任务

11. 等待队列(睡眠)
wait_event(wq,condition)---->在条件condition不成立的情况下将当前进程放入到等待队列并休眠的基本操作
wake_up----->唤醒在等待队列中的进程

12.临界区的概念

每个进程中访问临界资源(共享资源)的那段代码称为临界区

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值