6. 中断
-
概念:
中断是指CPU在执行程序的过程中,出现了某些突发事件急待处理,CPU必须暂停当前程序的执行,转去处理突发事件,处理完毕后又返回原程序被中断的位置继续执行。中断可以分为:内部中断和外部中断,内部中断来源于CPU内部,外部中断来源自CPU外部。
-
中断上半部:
-
也称为中断顶半部,用于完成尽量少的比较紧急的功能,通常被设置为不可被新中断打断。
-
使用场景:
-
要处理的内容不希望被其他中断打断
-
要处理的任务对时间敏感
-
要处理的任务与硬件有关
-
-
-
中断下半部:
-
也称为中断底半部,用来完成中断事件绝大多数任务,可以被新的中断打断,底半部相对来说并不是非常紧急,而且相对比较耗时。
-
使用场景:
-
完成并不是非常紧急的耗时的任务
-
可以被打断
-
-
中断下半部四种实现方式:
-
软中断:软中断和tasklet运行于中断上下文,不允许睡眠
-
tasklet:tasklet的实现是靠软中断,因为中断中不能长时间执行某个任务所以要快进快出,且不允许睡眠
-
工作队列:工作队列运行在进程上下文,所以允许睡眠,哪怕中断执行完后,有可能工作队列还未执行
-
-
7. 内核定时器
-
**概念:**在内核中表示系统一秒所对应的节拍数量,目前为100。在内核中的.config中定义,jiffies表示系统节拍,记录系统启动到当前累加的数字,如果想通过内核定时器计时则定时时间为:jiffers + (N*100)定时时间到达后可以调用回调函数。
-
定时器驱动代码
#include <linux/fs.h> #include <linux/module.h> #include <linux/cdev.h> #include <linux/init.h> #include <linux/timer.h> static void timeout(unsigned long data) { pr_info("timeout ok!\n"); return; } static DEFINE_TIMER(mtimer, timeout, 0, 0); static int __init kernel_timer_init(void) { init_timer(&mtimer);//初始化定时器 add_timer(&mtimer);//激活定时器 mod_timer(&mtimer, jiffies + msecs_to_jiffies(200));//jiffies表示的是当前时间,当前时间超过1s pr_info("add timer success\n"); return 0; } static void __exit kernel_timer_exit(void) { del_timer(&mtimer);//删除定时器 pr_info("del timer success\n"); return; } module_init(kernel_timer_init); module_exit(kernel_timer_exit); MODULE_LICENSE("GPL"); -
延时与睡眠的区别
Linux内核实现了延时函数,delay相关函数是忙等待,一直占用CPU资源。sleep相关函数不会一直占用CPU资源,会在睡眠的过程中释放CPU,让进程挂起,但是Linux系统是非实时操作系统,所以当CPU切换出该进程到CPU切换回该进程中间的时间一般大于睡眠设定的时间。
函数名 功能 ndelay 忙等待延时ns udelay 忙等待延时us mdelay 忙等待延时ms msleep 睡眠ms msleep_interruptible 可中断睡眠ms ssleep 睡眠s