7.2. 获知当前时间【转】

简介: 转自:http://blog.csdn.net/heanyu/article/details/6552578 内核代码能一直获取一个当前时间的表示, 通过查看 jifies 的值. 常常地, 这个值只代表从最后一次启动以来的时间, 这个事实对驱动来说无关, 因为它的生命周期受限于系统的 uptime.

内核代码能一直获取一个当前时间的表示, 通过查看 jifies 的值. 常常地, 这个值只代表从最后一次启动以来的时间, 这个事实对驱动来说无关, 因为它的生命周期受限于系统的 uptime. 如所示, 驱动可以使用 jiffies 的当前值来计算事件之间的时间间隔(例如, 在输入驱动中从单击中区分双击或者计算超时). 简单地讲, 查看 jiffies 几乎一直是足够的, 当你需要测量时间间隔. 如果你需要对短时间流失的非常精确的测量, 处理器特定的寄存器来帮忙了( 尽管它们带来严重的移植性问题 ).

它是非常不可能一个驱动会需要知道墙上时钟时间, 以月, 天, 和小时来表达的; 这个信息常常只对用户程序需要, 例如 cron 和 syslogd. 处理真实世界的时间常常最好留给用户空间, 那里的 C 库提供了更好的支持; 另外, 这样的代码常常太策略相关以至于不属于内核. 有一个内核函数转变一个墙上时钟时间到一个 jiffies 值, 但是:

#include <linux/time.h> 
unsigned long mktime (unsigned int year, unsigned int mon,
 unsigned int day, unsigned int hour,
 unsigned int min, unsigned int sec); 

重复:直接在驱动中处理墙上时钟时间往往是一个在实现策略的信号, 并且应当因此而被置疑.

虽然你不会一定处理人可读的时间表示, 有时你需要甚至在内核空间中处理绝对时间. 为此, <linux/time.h> 输出了 do_gettimeofday 函数. 当被调用时, 它填充一个 struct timeval 指针 -- 和在 gettimeofday 系统调用中使用的相同 -- 使用类似的秒和毫秒值. do_gettimeofday 的原型是:

 #include <linux/time.h>
 void do_gettimeofday(struct timeval *tv);

这段源代码声明 do_gettimeofday 有" 接近毫秒的精度", 因为它询问时间硬件当前 jiffy 多大比例已经流失. 这个精度每个体系都不同, 但是, 因为它依赖实际使用中的硬件机制. 例如, 一些 m68knommu 处理器, Sun3 系统, 和其他 m68k 系统不能提供大于 jiffy 的精度. Pentium 系统, 另一方面, 提供了非常快速和精确的小于嘀哒的测量, 通过读取本章前面描述的时戳计数器.

当前时间也可用( 尽管使用 jiffy 的粒度 )来自 xtime 变量, 一个 struct timespec 值. 不鼓励这个变量的直接使用, 因为难以原子地同时存取这 2 个字段. 因此, 内核提供了实用函数 current_kernel_time:

#include <linux/time.h>
struct timespec current_kernel_time(void);

用来以各种方式获取当前时间的代码, 可以从由 O' Reilly 提供的 FTP 网站上的源码文件的 jit ("just in time") 模块获得. jit 创建了一个文件称为 /proc/currentime, 当读取时, 它以 ASCII 码返回下列项:

  • 当前的 jiffies 和 jiffies_64 值, 以 16 进制数的形式.

  • 如同 do_gettimeofday 返回的相同的当前时间.

  • 由 current_kernel_time 返回的 timespec.

我们选择使用一个动态的 /proc 文件来保持样板代码为最小 -- 它不值得创建一整个设备只是返回一点儿文本信息.

这个文件连续返回文本行只要这个模块加载着; 每次 read 系统调用收集和返回一套数据, 为更好阅读而组织为 2 行. 无论何时你在少于一个时钟嘀哒内读多个数据集, 你将看到 do_gettimeofday 之间的差别, 它询问硬件, 并且其他值仅在时钟嘀哒时被更新.

phon% head -8 /proc/currentime
0x00bdbc1f 0x0000000100bdbc1f 1062370899.630126
 1062370899.629161488
0x00bdbc1f 0x0000000100bdbc1f 1062370899.630150
 1062370899.629161488
0x00bdbc20 0x0000000100bdbc20 1062370899.630208
 1062370899.630161336
0x00bdbc20 0x0000000100bdbc20 1062370899.630233
 1062370899.630161336

在上面的屏幕快照中, 由 2 件有趣的事情要注意. 首先, 这个 current_kernel_time 值, 尽管以纳秒来表示, 只有时钟嘀哒的粒度; do_gettimeofday 持续报告一个稍晚的时间但是不晚于下一个时钟嘀哒. 第二, 这个 64-位的 jiffies 计数器有 高 32-位字集合的最低有效位. 这是由于 INITIAL_JIFFIES 的缺省值, 在启动时间用来初始化计数器, 在启动时间后几分钟内强加一个低字溢出来帮助探测与这个刚好溢出相关的问题. 这个在计数器中的初始化偏好没有效果, 因为 jiffies 与墙上时钟时间无关. 在 /proc/uptime 中, 这里内核从计数器中抽取 uptime, 初始化偏好在转换前被去除.

 

 

1、使用rtc设备,这个时钟可以用于各种模式
2、借鉴系统调用adjtimex
这里使用第二种方式

系统调用adjtimex

一直跟下去,会发现最后调用
void do_gettimeofday(struct timeval *tv)

那么直接使用do_gettimeofday,能够得到struct timeval

struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};

那么就需要将这个tv_sec,即1970年开始至今的秒数转换为年月日时分秒
其实内核已经有这样的函数
/*
* Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
*/
void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)

唯一的不足是转换得到的是UTC时间,同北京时间差8小时。要想达到用户态localtime()的效果,必须获得/etc/localtime 中的时区信息。

示例代码:

#include <linux/timer.h>
#include <linux/timex.h>
#include <linux/rtc.h>

/*添加到合适位置*/

struct timex  txc;
struct rtc_time tm;
do_gettimeofday(&(txc.time));
rtc_time_to_tm(txc.time.tv_sec,&tm);
printk(“UTC time :%d-%d-%d %d:%d:%d /n”,tm.tm_year+1900,tm.tm_mon, tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec);

【作者】 张昺华
【新浪微博】 张昺华--sky
【twitter】 @sky2030_
【facebook】 张昺华 zhangbinghua
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
目录
相关文章
|
JSON 前端开发 JavaScript
JSON 必知必会
JSON 必知必会
768 0
|
测试技术
McCabe度量法
McCabe度量法
613 0
|
机器学习/深度学习 传感器 算法
【图像压缩】基于霍夫曼+行程+算术编码多种算法得灰色图像无损+有损压缩附Matlab代码
【图像压缩】基于霍夫曼+行程+算术编码多种算法得灰色图像无损+有损压缩附Matlab代码
|
存储 前端开发 Android开发
GB28181设备接入侧录像查询和录像下载技术探究之实时录像
我们在对接GB28181设备接入侧的时候,除了常规实时音视频按需上传外,还有个重要的功能,就是本地实时录像,录像后的数据,在执法记录仪等前端设备留底,然后,到工作站拷贝到专门的平台。
376 1
|
存储 编译器 程序员
【C/C++ this指针 20240105更新】探索C++编程之旅:深入理解this指针的魅力与应用
【C/C++ this指针 20240105更新】探索C++编程之旅:深入理解this指针的魅力与应用
262 0
|
Shell
Shell VSCode 基本开发插件(语法提示、错误检测、格式化、运行代码)
Shell VSCode 基本开发插件(语法提示、错误检测、格式化、运行代码)
2410 0
基于Java+SpringBoot+vue的租房网站设计与实现(附源码,使用教程)下
基于Java+SpringBoot+vue的租房网站设计与实现(附源码,使用教程)
|
jenkins Java 持续交付
软件开发常说的CI/CD是什么
任何软件项目的主要目标都是通过业务流程快速更新迭代来赚钱。我们越快向客户发布新版本,对我们的公司就约有好处。但如何快速实现版本更新迭代呢?我们可以手动完成。例如可以通过 SSH 连接到远程服务器。然后我们可以使用新代码克隆代码库、构建它并使用命令行运行它。尽管这个方式确实有效,但这并不是一种便捷的方法。
259 0
|
数据采集 存储 机器学习/深度学习
针对Cookie和GDPR违规的检测工具
欧盟的通用数据保护条例 (GDPR) 要求网站告知用户有关个人数据收集的信息并请求同意其使用 cookie。然而,大多数网站并没有给用户任何选择,还有一些网站试图欺骗他们接受所有的 cookie。本研究通过分析近 3 万个网站的 cookie弹窗中潜在的 GDPR 违规行为来记录这种情况的严重性。
576 2
ChatGPT: 读PDF、生成思维导图几种方案
ChatGPT: 读PDF、生成思维导图几种方案
1762 0
ChatGPT: 读PDF、生成思维导图几种方案