Linux内核设备驱动之内核的时间管理笔记整理

2019-01-16 20:43:40丽君

c.定时器的执行函数

超时处理函数的原型如下:

void my_timer_function(unsigned long data);

可以利用data参数用一个处理函数处理多个定时器。可以将data设为0

d.激活定时器

add_timer(&my_timer);

定时器一旦激活就开始运行。

e.更改已激活的定时器的超时时间

mod_timer(&my_timer, jiffies+ney_delay);

可以用于那些已经初始化但还没激活的定时器,如果调用时定时器未被激活则返回0,否则返回1。一旦mod_timer返回,定时器将被激活。

f.删除定时器

del_timer(&my_timer);

被激活或未被激活的定时器都可以使用,如果调用时定时器未被激活则返回0,否则返回1。不需要为已经超时的定时器调用,它们被自动删除

g.同步删除

del_time_sync(&my_timer);

在smp系统中,确保返回时,所有的定时器处理函数都退出。不能在中断上下文使用。

/******************** *不确定时间的延迟执行 *******************/

(1)什么是不确定时间的延迟

前面介绍的是确定时间的延迟执行,但在写驱动的过程中经常遇到这种情况:用户空间程序调用read函数从设备读数据,但设备中当前没有产生数据。此时,驱动的read函数默认的操作是进入休眠,一直等待到设备中有了数据为止。

这种等待就是不定时的延迟,通常采用休眠机制来实现。

(2)休眠

休眠是基于等待队列实现的,前面我们已经介绍过wait_event系列函数,但现在我们将不会有确定的休眠时间。

当进程被置入休眠时,会被标记为特殊状态并从调度器的运行队列中移走。

直到某些事件发生后,如设备接收到数据,则将进程重新设为运行态并进入运行队列进行调度。

休眠函数的头文件是<linux/wait.h>,具体的实现函数在kernel/wait.c中。

a.休眠的规则

*永远不要在原子上下文中休眠 *当被唤醒时,我们无法知道睡眠了多少时间,也不知道醒来后是否获得了我们需要的资源 *除非知道有其他进程会在其他地方唤醒我们,否则进程不能休眠

b.等待队列的初始化

见前文

c.休眠函数

linux最简单的睡眠方式为wait_event宏。该宏在实现休眠的同时,检查进程等待的条件。

1. void wait_event( wait_queue_head_t q, int condition); 2. int wait_event_interruptible( wait_queue_head_t q, int condition);
q: 是等待队列头,注意是采用值传递。 condition: 任意一个布尔表达式,在条件为真之前,进程会保持休眠。 注意!进程需要通过唤醒函数才可能被唤醒,此时需要检测条件。 如果条件满足,则被唤醒的进程真正醒来; 如果条件不满足,则进程继续睡眠。