内核定时器使用(example)

来源:互联网 发布:剑网3正太捏脸数据 编辑:程序博客网 时间:2024/04/18 15:03
1.驱动程序
#include <linux/module.h>#include <linux/types.h>#include <linux/fs.h>#include <linux/errno.h>#include <linux/mm.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/cdev.h>#include <asm/io.h>#include <asm/system.h>#include <asm/uaccess.h>#include <linux/timer.h> /*包括timer.h头文件*/#include <asm/atomic.h> #define SECOND_MAJOR 252static int second_major = SECOND_MAJOR ;struct second_dev{  struct cdev cdev;  atomic_t counter;  struct timer_list s_timer;};struct second_dev *second_devp;static ssize_t second_read(struct file *filp,char __user *buf,   size_t count,loff_t *ppos){  int counter;  counter = atomic_read(&second_devp->counter);  if(put_user(counter,(int*)buf))    return - EFAULT;  else    return sizeof(unsigned int);}static void second_timer_handle(unsigned long arg){  mod_timer(&second_devp->s_timer,jiffies + HZ/4 );  atomic_inc(&second_devp->counter);  printk(KERN_NOTICE "hi,this is a timer executing...%ld\n",jiffies);}int second_open(struct inode *inode,struct file *filp){  init_timer(&second_devp->s_timer);  second_devp->s_timer.function = &second_timer_handle;  second_devp->s_timer.expires = jiffies + HZ ;  add_timer(&second_devp->s_timer);  atomic_set(&second_devp->counter,0);  return 0;}int second_release(struct inode *inode,struct file *filp){  del_timer(&second_devp->s_timer);  return 0;}static const struct file_operations second_fops =  {    .owner = THIS_MODULE,    .open = second_open,    .release = second_release,    .read = second_read,};int second_init(void){  int ret;  dev_t devno=MKDEV(second_major,0);  if(second_major)    {      ret = register_chrdev_region(devno,1,"second");    }  else    {      ret = alloc_chrdev_region(&devno,0,1,"second");      second_major = MAJOR(devno);    }  if(ret<0)    return ret;  second_devp = kmalloc(sizeof(struct second_dev),GFP_KERNEL);  if(!second_devp)    {      ret = -ENOMEM;      goto fail;    }  memset(second_devp,0,sizeof(struct second_dev));    cdev_init(&second_devp->cdev,&second_fops);  ret = cdev_add(&second_devp->cdev,devno,1);  if(ret)    {      printk(KERN_ALERT "ERROR ADDING CHAR DEVICE WHILE INITING TIMER.\n");      goto fail;    }  return 0;fail:  if(second_devp)    {      kfree(second_devp);      second_devp = NULL;    }  unregister_chrdev_region(devno,1);  return ret;  }void second_exit(void){  cdev_del(&second_devp->cdev);  kfree(second_devp);  unregister_chrdev_region(MKDEV(second_major,0),1);}MODULE_AUTHOR("ustc");MODULE_LICENSE("GPL");module_param(second_major,int,S_IRUGO);module_init(second_init);module_exit(second_exit);
2.测试文件
/*======================================================================    A test program to access /dev/second    This example is to help understand kernel timer         The initial developer of the original code is Baohua Song    <author@linuxdriver.cn>. All Rights Reserved.======================================================================*/#include <sys/types.h>#include <sys/stat.h>#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <sys/time.h>int main(int argc,char *argv[]){  int fd;  int counter = 0;  int old_counter = 0;  if(argc<2)    {      printf("wrong parameter !\n");      return -1;    }  fd = open(argv[1], O_RDONLY);  if (fd !=  - 1)  {    while (1)    {      read(fd,&counter, sizeof(unsigned int));//读目前经历的秒数      if(counter >= 20)break;      if(counter!=old_counter)      {      printf("1/4 seconds after open %s :%d\n",argv[1],counter);      old_counter = counter;      }    }    close(fd);  }  else  {    printf("Device open failure\n");  }  return 0;}
3. Makefile文件
KERNELDIR = /usr/src/linux-headers-$(shell uname -r)PWD := $(shell pwd)CC    = gccOBJ := hi_timerobj-m := $(OBJ).o DEVICE_NAME := secondMAJOR := 252TEST_FILENAME:=second_testmoudles:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesinstall:sudo insmod $(OBJ).kosudo mknod /dev/$(DEVICE_NAME) c $(MAJOR) 0sudo chmod ugo+rw /dev/$(DEVICE_NAME)exec:$(CC) -o $(TEST_FILENAME) $(TEST_FILENAME).c./$(TEST_FILENAME) /dev/$(DEVICE_NAME)uninstall:sudo rmmod $(OBJ)sudo rm -rf /dev/$(DEVICE_NAME)clean:rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions $(TEST_FILENAME) *symvers