我是靠谱客的博主 酷炫魔镜,最近开发中收集的这篇文章主要介绍Linux kernel -- 定时器/jiffies,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

0. 测试环境

Linux 2.6.39 AT91SAM9G45

1. 定时器简单的测试例子

#include <linux/timer.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");

struct timer_list tm;
static int num;
static void func()
{
    num++;
    mod_timer(&tm, jiffies + HZ);

    printk("Hello, timer :%dn", num);
}

static int timer_init(void)
{
    num = 0;

    init_timer(&tm);
    tm.expires = jiffies + HZ;
    tm.function = func;
    add_timer(&tm);

    return 0;
}

static void timer_exit(void)
{
    del_timer(&tm);

    printk("remove timern");
}

module_init(timer_init);
module_exit(timer_exit);                                                                                                                                                       
Makefile

obj-m := timer.o
KERNEL := /Android/linux-2.6.39-android_altus
PWD := $(shell pwd)
modules:
    $(MAKE) -C $(KERNEL) M=$(PWD) modules

.PHONEY:clean
clean:
    rm -f *.o *.ko


insmod timer.ko

使用命令cat /proc/kmsg查看效果


2. jiffies和jiffies_64变量定义的位置

http://bbs.chinaunix.net/archiver/tid-1982818.html?page=2

jiffies_64获取的驱动部分代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/timer.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>

#include <asm/uaccess.h>

#define JIFFIES_64_DEVICE_NODE_NAME  "jiffies_64"
#define JIFFIES_64_DEVICE_CLASS_NAME "jiffies_64"
#define JIFFIES_64_DEVICE_FILE_NAME  "jiffies_64"

static unsigned long long value_of_jiffies_64;
static dev_t devno;
static struct class *jiffies_64_class;
static struct cdev jiffies_64_dev;

static ssize_t jiffies_64_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos)
{
	if (buf == NULL || size != sizeof(value_of_jiffies_64))
		return -EINVAL;

	if (value_of_jiffies_64 == 0)
		value_of_jiffies_64 = get_jiffies_64();

	if (copy_to_user(buf, &value_of_jiffies_64, sizeof(value_of_jiffies_64))) 
		return -ENOMEM;

	memset(&value_of_jiffies_64, 0, sizeof(value_of_jiffies_64));

	return 0;
}

static ssize_t jiffies_64_open(struct inode *inode, struct file *filp)
{
	return 0;
}

static ssize_t jiffies_64_release(struct inode *inode, struct file *filp)
{
	return 0;
}

static struct file_operations jiffies_64_fops = {
	.owner = THIS_MODULE,
	.open = jiffies_64_open,
	.read = jiffies_64_read,
	.release = jiffies_64_release,
};

static ssize_t jiffies_64_val_show(struct device *dev, struct device_attribute *attr, char *buf);
static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, jiffies_64_val_show, NULL);

static ssize_t jiffies_64_val_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%lldn", value_of_jiffies_64);
}

static int __init jiffies_64_init(void)
{
	int err = -1;
	struct device *device = NULL;

	err = alloc_chrdev_region(&devno, 0, 1, JIFFIES_64_DEVICE_NODE_NAME);
	if (err < 0) {
		printk(KERN_ALERT"Failed to alloc char dev region.n");
		goto fail;
	}

	/* setup cdev */
	cdev_init(&jiffies_64_dev, &jiffies_64_fops);
	jiffies_64_dev.owner = THIS_MODULE;
	err = cdev_add(&jiffies_64_dev, devno, 1);
	if (err) {
		printk(KERN_ALERT"cdev_add failed.n");
		goto unregister;
	}

	jiffies_64_class = class_create(THIS_MODULE, JIFFIES_64_DEVICE_CLASS_NAME);
	if (IS_ERR(jiffies_64_class)) {
		err = PTR_ERR(jiffies_64_class);
		printk(KERN_ALERT"Failed to create jiffies_64 classn");
		goto destroy_cdev;
	}

	device = device_create(jiffies_64_class, NULL, devno, NULL, "%s", JIFFIES_64_DEVICE_FILE_NAME);
	if (IS_ERR(device)) {
		err = PTR_ERR(device);
		printk(KERN_ALERT"Failed to create jiffies_64 device.n");
		goto destroy_class;
	}

	err = device_create_file(device, &dev_attr_val);
	if (err < 0) {
		printk(KERN_ALERT"Failed to create attribute val.n");
		goto destroy_device;
	}

	return 0;

destroy_device:
	device_destroy(jiffies_64_class, devno);

destroy_class:
	class_destroy(jiffies_64_class);

destroy_cdev:
	cdev_del(&jiffies_64_dev);

unregister:
	unregister_chrdev_region(devno, 1);

fail:
	return err;
}

static void __exit jiffies_64_exit(void)
{
	if (jiffies_64_class) {
		device_destroy(jiffies_64_class, devno);
		class_destroy(jiffies_64_class);
	}

	cdev_del(&jiffies_64_dev);

	unregister_chrdev_region(devno, 1);
}

module_init(jiffies_64_init);
module_exit(jiffies_64_exit);
MODULE_LICENSE("GPL");

jiffies_64获取的应用部分代码

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define DEVICE_NODE_NAME "/dev/jiffies_64"

int main(int argc, char **argv)
{
	unsigned long long jiffies_64; /* It's in userspace, so without trouble */
	int fd = -1;

	fd = open(DEVICE_NODE_NAME, O_RDONLY);
	if (fd == -1) {
		perror(DEVICE_NODE_NAME);
		return -1;
	}

	read(fd, &jiffies_64, sizeof(jiffies_64));
	printf("jiffies_64 = %lldn", jiffies_64);
	
	close(fd);
	return 0;
}


3. 在Linux内核中打印日志时间戳

在编译Linux内核,配置时:make menuconfig ---> Kernel hacking --> show timing information on printks

 当选中这个选项后,启动内核,会在日志信息前面加上时间戳。

从linux启动信息可以看出,时间精确到微秒(us)。


讨论群:

Atmel技术交流讨论群
  群号是305940105

Linux驱动开发调试群
  群号是297141784


最后

以上就是酷炫魔镜为你收集整理的Linux kernel -- 定时器/jiffies的全部内容,希望文章能够帮你解决Linux kernel -- 定时器/jiffies所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部