- Linux系统中通过add_timer(①) 添加的timer是( A)
[A] 一次的 [B] 循环的 [C ] 以上两种都可以
2.tasklet和workqueue区别?(②)
tasklet运行于中断上下文,不允许阻塞 、休眠,而workqueue运行与进程上下文,可以休眠和阻塞。
3.为什么要区分上半部和下半部?
中断服务程序异步执行,可能会中断其他的重要代码,包括其他中断服务程序。因此,为了避免被中断的代码延迟太长的时间,中断服务程序需要尽快运行,而且执行的时间越短越好,所以中断程序只作必须的工作,其他工作推迟到以后处理。所以Linux把中断处理切为两个部分:上半部和下半部。上半部就是中断处理程序,它需要完成的工作越少越好,执行得越快越好,一旦接收到一个中断,它就立即开始执行。像对时间敏感、与硬件相关、要求保证不被其他中断打断的任务往往放在中断处理程序中执行;而剩下的与中断有相关性但是可以延后的任务,如对数据的操作处理,则推迟一点由下半部完成。下半部分延后执行且执行期间可以响应所有中断,这样可使系统处于中断屏蔽状态的时间尽可能的短,提高了系统的响应能力。实现了程序运行快同时完成的工作量多的目标。
4.中断的申请及何时执行(何时执行中断处理函数)?
中断的响应流程:cpu接受中断->保存中断上下文跳转到中断处理历程->执行中断上半部->执行中断下半部->恢复中断上下文。 中断的申请request_irq的正确位置:应该是在第一次打开 、硬件被告知终端之前。
- 中断和轮询哪个效率高?怎样决定是采用中断方式还是采用轮询方式去实现驱动?
中断是CPU处于被动状态下来接受设备的信号,而轮询是CPU主动去查询该设备是否有请求。凡事都是两面性,所以,看效率不能简单的说那个效率高。如果是请求设备是一个频繁请求cpu的设备,或者有大量数据请求的网络设备,那么轮询的效率是比中断高。如果是一般设备,并且该设备请求cpu的频率比较底,则用中断效率要高一些。主要是看请求频率。
- 写一个中断服务需要注意哪些?如果中断产生之后要做比较多的事情你是怎么做的?
第一: 中断处理例程应该尽量短,把能放在后半段(tasklet,等待队列等)的任务尽量放在后半段。
注意哪些:写一个中断服务程序要注意快进快出,在中断服务程序里面尽量快速采集信息,包括硬件信息,然后退出中断,要做其它事情可以使用工作队列或者tasklet方式。也就是中断上半部和下半部。
第二:中断服务程序中不能有阻塞操作。应为中断期间是完全占用CPU的(即不存在内核调度),中断被阻塞住,其他进程将无法操作;
第三:中断服务程序注意返回值,要用操作系统定义的宏做为返回值,而不是自己定义的OK,FAIL之类的。
- jiffies是用来做什么的?
linux通过时钟中断来确定时间间隔。时钟中断的发生频率为HZ(③),HZ是一个与体系结构无关的常数,在文件<linux/param.h>中定义为100(即1秒中jiffies值就加100)。当时钟中断发生时,jiffies值就加1。
因此,jiffies值就是自linux启动后的时钟滴答的次数;jiffies在头文件<linux/sched.h>中被定义为数据类型为unsigned long (32位无符号长整型)的变量,连续累加一年又四个多月后就会溢出(假定HZ=100,1个jiffies等于1/100秒,jiffies可记录的最大秒数为42949672.96秒,约合1.38年)。
- 请写出struct timer_list结构描述?
struct timer_list {
struct list_head entry; /*不要直接修改它 */
unsigned long expires; /* timeout超时值,以jiffies值为单位 */
void (*function)(unsigned long); /* 超时时调用的定时器处理程序 */
unsigned long data; /* 传递给定时器处理函数的参数 */
struct tvec_base *base;
}
相关学习资料:
1️⃣:https://www.cnblogs.com/hjj801006/p/4551378.html
2️⃣:https://blog.csdn.net/lee244868149/article/details/80635411
3️⃣:https://www.cnblogs.com/hjslovewcl/articles/2314322.html
综合使用例子:https://blog.csdn.net/jidonghui/article/details/7449546
(感谢大佬)