链接:https://blog.csdn.net/yhb1047818384/article/details/69811542
linux内核笔记之时间管理(二) : 低精度timer
## linux 内核笔记之时间管理(三) : 高精度timer
时间获取
驱动程序中一般不需要知道墙钟时间(也就是年月日的时间)。但驱动可能需要处理绝对时间。
为此,内核提供了两个结构体,都定义在
(1) struct timeval {
time_t tv_sec; /* seconds /
suseconds_t tv_usec; / microseconds /
};
(2)采用秒和纳秒值保存时间。
struct timespec {
time_t tv_sec; / seconds /
long tv_nsec; / nanoseconds */
};
(3)用do_gettimeofday()用于获得timeval
include <linux/time.h>
void do_gettimeofday(struct timeval *tv);
(4) current_kernel_time() 用于获得timespec
include <linux/time.h>
struct timespec current_kernel_time(void);
(5)rtc_time_to_tm(unsigned long time, struct rtc_time *tm) 将上面获得的sec转换为年月日...
include <linux/rtc.h>
延迟操作
1.长延迟
(1)忙等待
如果对延迟的精确度要求不高,最简单的方法是实现一个监视jiffies计时器的循环。
unsigned long delay = jiffies + 5*HZ;
while(time_before(jiffies, delay))
cpu_relax();
(2)超时
include <linux/sched.h>
signed long schedule_timeout(signed long timeout);
timeout是用jiffies表示的延迟时间,正常值返回0.
schedule_timeout在使用前需要设置当前进程状态。
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(2HZ); / 睡2秒 */
进程经过2秒后会被唤醒。
第一行调用set_current_state已设置当前进程状态,调度器只有在超时到期且其状态为TASK_RUNNING时才会运行这个进程。如果不希望被用户空间打断,可以将进程状态设置为TASK_UNINTERRUPTIBLE。
(3)让出处理器
while(time_before(jiffies, j1))
schedule();
在等待期间可以让出处理器,减少CPU的负担。
2.短延迟
对于那些最多几十个毫秒的延迟,不需要依赖时间滴答
include <Linux/delay.h>
void ndelay(unsigned long nsecs); /*延迟纳秒 /
void udelay(unsigned long usecs); /延迟微秒 /
void mdelay(unsigned long msecs); /延迟毫秒 */
这三个延迟函数均是忙等待函数,在延迟过程中无法运行其他任务。 它们的实现使用了软件循环。
实现毫秒级(或者更长)延迟还有一种方法,这种方法不涉及忙等待
include <Linux/delay.h>
void msleep(unsigned int millisecs); /休眠毫秒 /
void ssleep(unsigned int seconds); /休眠秒 /
unsigned long msleep_interruptible(unsigned int millisecs);/休眠毫秒,中断可以唤醒/