概述
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所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复