概述:
**********jiffies在英语中是"瞬间,一会儿"的意思
**********jiffies是一个计数器,记录了系统从刚开始启动到关闭系统时所运行的秒数,系统初始化时jiffies是0
**********内核是通过定时器中断来使jiffies计数器的值增加的,每次产生一个时钟中断,jiffies就会+1
**********产生中断的频率是由HZ(中断间隔,时钟滴答数)来决定的.HZ包含在<linux/param.h>头文件中的
**********内核计数器jiffies或jiffies_64都是一个64位变量,并且都是只读的,可以对jiffies计数器直接存取,而对jiffies_64不能直接存取需要借助函数
u64 get_jiffies_64(void);
在内核中的定义
extern u64 __jiffy_data jiffies_64;
extern unsigned long volatile __jiffy_data jiffies;
**********jiffies计数器和操作这个计数器的函数都在头文件<linux/jiffies.h>中,(<linux/sched.h>包含<linux/jiffies.h>文件)
操作jiffies计数器的宏函数:
int time_after(unsigned long a, unsigned long b); //jiffies a在jiffies b之后,即 a > b
int time_before(unsigned long a, unsigned long b); //jiffies a在jiffies b之后,即 a < b
int time_after_eq(unsigned long a, unsigned long b); // a >= b
int time_before_eq(unsigned long a, unsigned long b); // a <= b
**********time_after的宏定义
#define time_after(a,b) \
(typecheck(unsigned long, a) && \
typecheck(unsigned long, b) && \
((long)(b) - (long)(a) < 0))
//returns true if the time a is after time b
**********time_before的宏定义
#define time_before(a,b) time_after(b,a)
**********time_after_eq的宏定义
#define time_after_eq(a,b) \
(typecheck(unsigned long, a) && \
typecheck(unsigned long, b) && \
((long)(a) - (long)(b) >= 0))
**********time_before_eq的宏定义
#define time_before_eq(a,b) time_after_eq(b,a)
在用户空间,用来表示jiffies值的方法:
**********使用结构体,struct timeval或使用结构体struct timespec,这些结构体在内核空间包含在<linux/time.h>中,在用户空间包含在<sys/time.h>头文件中
*****struct timeval结构的原型是
struct timeval {
time_t tv_sec; /* seconds */ //秒
suseconds_t tv_usec; /* microseconds */ //毫秒
};
*****struct timespec结构的原型是
struct timespec {
time_t tv_sec; /* seconds */ //秒
long tv_nsec; /* nanoseconds */ //纳秒
};
jiffies和这两个结构体之间转换的函数:
unsigned long timespec_to_jiffies(struct timespec *value); //将timespec转换成jiffies
void jiffies_to_timespec(unsigned long jiffies, struct timespec *value); //将jiffies装换成timespec
unsigned long timeval_to_jiffies(struct timeval *value); //将timeval转换成jiffies
void jiffies_to_timeval(unsigned long jiffies, struct timeval *value); //将jiffies转换成timeval
##################################################################################################################################
模块实例:(jiffies.c)
# include <linux/module.h>
# include <linux/init.h>
# include <linux/kernel.h>
# include <linux/fs.h>
# include <linux/cdev.h>
# include "jiffies.h"
/**
* The descriptions for the module
**/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Bruce.Wang");
MODULE_DESCRIPTION("Test the char device");
MODULE_VERSION("1.0");
MODULE_ALIAS("CHRDEV");
//MODULE_DEVICE_TABLE("for device of char ");
/**
*the major device number
**/
static int major = 66;
static int minor = 88;
static int count = 2;
static dev_t cdevno;
static char chrdev_name[] = "Dediprog";
/**
*char device
**/
static struct cdev mycdev;
int my_open(struct inode *inodep, struct file *filep)
{
}
size_t my_read(struct file *filep, char __user *buf, size_t count, loff_t *offset)
{
struct time_jiffies tj;
unsigned long j;
unsigned stamp_60;
j = jiffies;
stamp_60 = j + 60 * HZ;
printk("HZ----------->%d\n",HZ);
jiffies_to_timeval(j, &tj.old_tj);
jiffies_to_timeval(stamp_60, &tj.new_tj);
copy_to_user(buf,&tj,sizeof(tj));
printk("current jiffies is------------>%ld\n stamp_60--------->%ld\nstamp_60 - j------------>%ld\n", j, stamp_60, stamp_60 - j);
if (time_after(stamp_60,j)){
printk("stamp_60 > j\n that is stamp_60 after j\n");
}
if (time_before(j,stamp_60)){
printk("j < stamp_60\n that is j before stamp_60\n");
}
return 66;
}
ssize_t my_write(struct file *filp, const char __user *buf, size_t count, loff_t *off)
{
}
int my_release(struct inode *inodp, struct file *filp)
{
printk("%s %d\n", __func__, __LINE__);
return 40;
}
/**
*Operations for the character device
**/
static struct file_operations fops = {
.owner = THIS_MODULE,
.open = my_open,
.read = my_read,
.write = my_write,
.release = my_release,
};
/**
*The init function of the module
**/
static int __init chrdev_init(void)
{
int ret;
/**
*Combined major and minor device numbers
**/
cdevno = MKDEV(major, minor);
/**
*static register the number of the char device into the kernel
**/
ret = register_chrdev_region(cdevno, count, chrdev_name);
if (ret < 0){
goto ERROR1;
}
/**
*Allocate space for character devices and init it
**/
cdev_init(&mycdev, &fops);
/**
*Add the char device into the kernel(that is,relate with device number)
**/
ret = cdev_add(&mycdev, cdevno, count);
if (ret < 0){
goto ERROR2;
}
return 0;
ERROR1:
printk("register char device number failed!\n");
return ret;
ERROR2:
printk("relate char device with number failed!");
unregister_chrdev_region(cdevno, count);
return ret;
}
/**
*Function executed when the module exits
**/
static void __exit chrdev_exit(void)
{
/**
*Cancellation the char device number from the kernel
**/
unregister_chrdev_region(cdevno, count);
/**
*Remove the char device from the kernel
**/
cdev_del(&mycdev);
printk("See you later,guys!!\n");
}
module_init(chrdev_init);
module_exit(chrdev_exit);
##################################################################################################################################
jiffies.h头文件(我自己写的)
#ifndef __TIME_JIFFIES__
#define __TIME_JIFFIES__
#include <linux/jiffies.h>
#include <linux/param.h>
#include <linux/time.h>
# include <asm/uaccess.h>
struct time_jiffies
{
struct timeval old_tj;
struct timeval new_tj;
};
#endif
####################################################################################################################################
app.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
struct time_jiffies
{
struct timeval old_tj;
struct timeval new_tj;
};
int main(int argc, char *argv[])
{
int fd;
int ret;
struct time_jiffies tj;
if(argc != 2){
fprintf(stderr, "Usage: %s dev_file\n", argv[0]);
return -1;
}
fd = open(argv[1], O_RDWR | O_NDELAY);
if(fd < 0){
perror("open");
return -2;
}
ret = read(fd, &tj, sizeof(tj));
printf("old_tj--------------->%ld\n new_tj------------->%ld\n", tj.old_tj.tv_sec, tj.new_tj.tv_sec);
printf("ret----------->%d\n",ret);
printf("new_tj - old_tj---------->%ld\n",tj.new_tj.tv_sec - tj.old_tj.tv_sec);
return 0;
}