jiffies计数器

概述:

**********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;
}
























































jiffies计数器

上一篇:错误:One or more post-processing actions failed. Consult the OPP service log for details


下一篇:[知识学习]java中clone()的机制