当前位置: 首页 > 科技观察

Linux设备驱动的定时和延迟

时间:2023-03-17 12:42:00 科技观察

Linux通过系统硬件定时器以固定的时间间隔(以HZ测量)产生定时器中断。每次中断都会导致一个内核计数器的值jiffies累加,所以这个jiffies记录了系统从开机开始经过的时间,内核相应地实现软件定时器和延时。jiffies和HZ的演示#includeunsignedlongj,stamp_1,stamp_half,stamp_n;j=jiffies;/*readthecurrentvalue*/stamp_1=j+HZ;/*1secondinthefuture*/stamp_half=j+HZ/2;/*halfasecond*/stamp_n=j+n*HZ/1000;/*nmilliseconds*/内核定时器硬件时钟中断处理程序将唤醒TIMER_SOFTIRQ软中断并运行当前处理器上所有到期的内核定时器。定时器定义/初始化在Linux内核中,timer_list结构体的一个实例对应一个定时器:/*当expires指定的定时器超时时间到期时,函数(data)将被执行*//*当expires指定后定时器超时时间到期,function(data)*/structtimer_list{unsignedlongexpires;/*定时器超时时间*/void(*function)(unsignedlong);/*定时器处理函数*/unsignedlongdata;/*函数参数*/...};/*定义*/structtimer_listmy_timer;/*初始化函数*/voidinit_timer(structtimer_list*timer);/*初始化宏*/TIMER_INITIALIZER(_function,_expires,_data)/*定义和初始化宏*/DEFINE_TIMER(_name,_function,_expires,_data)添加/删除定时器/*注册内核定时器,将定时器添加到内核动态定时器链表*/voidadd_timer(structtimer_list*timer);/*del_timer_sync()是del_timer()的同步版本。当删除一个定时器时,需要等待它被处理,所以这个函数的调用不能发生在中断上下文中*/voiddel_timer(structtimer_list*timer);voiddel_timer_sync(structtimer_list*timer);定时时间修改intmod_timer(structtimer_list*timer,unsignedlongexpires);延迟短延迟voidndelay(unsignedlongnsecs);voidudelay(未签名的longusecs);voidmdelay(unsignedlongmsecs);内核启动时,会运行一个延迟测试程序(delayloopcalibration)来计算lpj(loopsperjiffy),这些函数是根据lpj实现的,即busywaiting。长延迟的一种非常直观的方法是将当前jiffies与目标jiffies进行比较:inttime_after(unsignedlonga,unsignedlongb);/*aafterb,true*/inttime_before(unsignedlonga,unsignedlongb);/*abeforeb*/inttime_after_eq(unsignedlonga,unsignedlongb);/*aafterorequalb*/inttime_before_eq(unsignedlonga,unsignedlongb);/*abeforeorequalb*/睡眠延迟voidmsleep(unsignedintmillisecs);unsignedlongmsleep_interruptible(unsignedintmillisecs);voidssleep(unsignedintseconds);提示:msleep(),不可中断