内核定时器使用例子
来源:互联网 发布:企业会计核算软件 编辑:程序博客网 时间:2024/03/29 13:43
1.王工例子+#include <linux/timer.h>
+#include <linux/reboot.h>
#define EHCI_WATCHDOG_MSECS 5000
static struct timer_list pxau2h_watchdog;
static void pxau2h_watchdog_handler(unsigned long param)
+{
+ struct usb_hcd *hcd=(struct usb_hcd *)param;
+ //check
+ if(hcd->state==HC_STATE_HALT){
+ printk("\n\nEHCI halted,restart\n\n");
+ /*
+ * This will not be a clean reboot, with everything
+ * shutting down. But if there is a chance of
+ * rebooting the system it will be rebooted.
+ */
+ emergency_restart();
+ }else {
+ mod_timer(&pxau2h_watchdog,
+ jiffies + msecs_to_jiffies(EHCI_WATCHDOG_MSECS));
+ }
+}
static int pxau2h_ehci_clk_set(int en)
{
struct clk *clk = NULL;
@@ -229,6 +252,13 @@ static int pxau2h_ehci_probe(struct platform_device *pdev)
goto err2;
}
platform_set_drvdata(pdev, hcd);
+
+ init_timer(&pxau2h_watchdog);
+ pxau2h_watchdog.function = pxau2h_watchdog_handler;
+ pxau2h_watchdog.data = (unsigned long)hcd;
+ mod_timer(&pxau2h_watchdog,
+ jiffies + msecs_to_jiffies(EHCI_WATCHDOG_MSECS));
+
return retval;
@@ -245,6 +275,8 @@ static int pxau2h_ehci_remove(struct platform_device *pdev)
if (HC_IS_RUNNING(hcd->state))
hcd->state = HC_STATE_QUIESCING;
+ del_timer_sync(&pxau2h_watchdog);
+
usb_disconnect(&hcd->self.root_hub);
hcd->driver->stop(hcd);
2.另外一种实现方式
Linux内核定时器
下面看看一个实现轮询操作的小例子:
struct timer_list polling_timer;
void polling_handler(unsigned long data) {
...
polling_timer.expires = jiffies + 2 * HZ;
add_timer(&polling_timer);
init_timer(&polling_timer);
polling_timer.data = (unsigned long)something;
polling_timer.function = polling_handler;
polling_timer.expires = jiffies + 2 * HZ;
add_timer(&polling_timer);
jiffies是Linux内核中的一个全局变量,用来记录自系统启动以来产生的节拍的总数。启动时,内核将该变量初始化为0,此后,每次时钟中断处理程序都会增加该变量的值。
HZ是内核定义的宏,在i386体系结构中定义为:
#define HZ 1000
2.6内核的时钟中断频率是1000,也就是说,在1秒里jiffies会被增加1000。因此jiffies + 2 * HZ表示推后2秒钟。
有时,需要更改已经激活的定时器,当一个定时器已经被插入到内核动态定时器链表中后,我们还可以修改该定时器的expires值。采用如下函数:
mod_timer(&polling_timer, jiffies + new_delay);
如果需要在定时器超时前停止定时器,可以使用del_timer()函数:
del_timer(&polling_timer);
int mod_timer(struct timer_list *timer, unsigned long expires)
{
int ret;
unsigned long flags;
spin_lock_irqsave(&timerlist_lock, flags);
timer->expires = expires;
ret = detach_timer(timer);
internal_add_timer(timer);
spin_unlock_irqrestore(&timerlist_lock, flags);
return ret;
}
在多处理器的情况下使用:
del_timer_sync(&polling_timer);
注意,不需要为已经超时的定时器调用该函数,因为它们会自动被删除。
内核定时器是在时钟中断发生后,作为软中断在下半部的上下文钟执行的。所有的定时器结构都以链表的形式存储。时钟中断发生后,内核按链表顺序依次执行。一般来说,定时器在超时后会立即执行,但是也有可能被推迟到下一个时钟节拍才能运行,所以不能用定时器来实现硬实时的操作。又因为内核定时器发生在软中断中,因此,定时器执行函数不能够睡眠,也不能够持有信号量。如果对硬件的访问需要使用信号量同步,或者可能睡眠(比如需要调用kmalloc内存分配,但是由于某种原因不能使用GFP_ATOMIC标志),就不能直接通过定时器来实现了。一个变通的做法是在内核定时器执行函数里调用工作队列,在工作队列处理函数中实现对硬件的访问。
- 内核定时器使用例子
- linux内核定时器的使用例子
- 内核定时器的例子
- 内核定时器 的简单例子
- Spring定时器使用例子
- 【内核】: 内核定时器的使用
- 内核定时器的使用
- 内核定时器的使用
- 内核定时器使用
- 内核定时器的使用
- 内核定时器的使用
- 内核定时器的使用
- 【内核】:定时器的使用
- 内核定时器的使用
- 内核定时器的使用
- 内核定时器的使用
- 内核定时器的使用
- 内核定时器的使用
- 设计模式
- 日本語勉強40
- java 深入研究Synchronize 和 Lock 的区别与用法
- 利用JSTL标签在网页中显示后台传来的数组数据
- Codeforces Round #109 (Div. 2) A (简单模拟)
- 内核定时器使用例子
- Linux 引导过程内幕
- centos安装openssl
- 云平台仿真框架cloudsim介绍
- pat解题报告【1078】
- OSI七层模型详解
- ubuntu下安装配置resin服务器
- poj 3254
- 【索引】Binary Trees