Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4523978
  • 博文数量: 1148
  • 博客积分: 25453
  • 博客等级: 上将
  • 技术积分: 11949
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-06 21:14
文章分类

全部博文(1148)

文章存档

2012年(15)

2011年(1078)

2010年(58)

分类: LINUX

2012-01-02 14:34:52

linux设备驱动开发详解p207内核定时器---秒字符设备
代码附件:  timer_me.rar   将rar修改为tar.bz2
=====================================================================

  1. #include <linux/module.h>
  2. #include <linux/init.h>
  3. #include <linux/kernel.h>
  4. #include <linux/fs.h>//container_of
  5. #include <linux/types.h>//atomic_t
  6. #include <linux/cdev.h>//cdev
  7. #include <asm/uaccess.h>//put_user
  8. #include <linux/slab.h>//kmalloc
  9. #include <linux/moduleparam.h>//moudule_param

  10. static int second_major =240;
  11. module_param(second_major,int,00644);//

  12. struct second_dev{
  13.     struct cdev cdev;
  14.     atomic_t counter;
  15.     struct timer_list s_timer;
  16. };
  17. struct second_dev *second_devp;

  18. static void second_timer_handler(unsigned long arg)
  19. {
  20.     mod_timer(&second_devp->s_timer,jiffies+HZ);
  21.     atomic_inc(&second_devp->counter);//puls 1
  22.     printk(KERN_NOTICE"currretn jiffies is %ld\n",jiffies);
  23. }

  24. int second_open(struct inode *inode,struct file *filp)
  25. {
  26.     struct second_dev *dev;
  27.     dev = container_of(inode->i_cdev,struct second_dev,cdev);
  28.     filp->private_data = dev;
  29.     
  30.     init_timer(&second_devp->s_timer);
  31.     second_devp->s_timer.function = &second_timer_handler;
  32.     second_devp->s_timer.expires = jiffies + HZ;
  33.     add_timer(&second_devp->s_timer);
  34.     atomic_set(&second_devp->counter,0);
  35.     return 0;
  36. }

  37. int second_release(struct inode *inode,struct file *filp)
  38. {
  39.     del_timer(&second_devp->s_timer);
  40.     return 0;
  41. }

  42. static ssize_t second_read(struct file *filp, char __user *buf,size_t count,off_t *ppos)
  43. {
  44.     int counter;
  45.     struct second_dev *dev = filp->private_data;

  46. //    counter = atomic_read(&second_devp->counter);
  47.     counter = atomic_read(&dev->counter);
  48.     if(put_user(counter,(int *)buf))
  49.         return -EFAULT;
  50.     else
  51.         return sizeof(unsigned int);
  52. }

  53. static const struct file_operations second_fops={
  54.     .owner = THIS_MODULE,
  55.     .open = second_open,
  56.     .release = second_release,
  57.     .read = second_read,
  58. };

  59. static void second_setup_cdev(struct second_dev *dev ,int index)
  60. {
  61.     int err;
  62.     int devno = MKDEV(second_major,index);
  63.     cdev_init(&dev->cdev,&second_fops);
  64.     dev->cdev.owner = THIS_MODULE;
  65.     err = cdev_add(&dev->cdev,devno,1);
  66.     if(err)
  67.         printk(KERN_INFO"error %d adding LED %d\n",err,index);
  68. }

  69. static int __init second_init(void)
  70. {
  71.     int ret;
  72.     dev_t devno = MKDEV(second_major,0);

  73.     if(second_major)
  74.     {
  75.         ret = register_chrdev_region(devno,1,"second");
  76.     }
  77.     else
  78.     {
  79.         ret = alloc_chrdev_region(&devno,0,1,"second");
  80.         second_major = MAJOR(devno);
  81.     }

  82.     if(ret < 0)
  83.         return ret;

  84.     second_devp = kmalloc(sizeof(struct second_dev),GFP_KERNEL);
  85.     if(!second_devp)
  86.     {
  87.         ret = -ENOMEM;
  88.         goto fail_malloc;
  89.     }

  90.     memset(second_devp,0,sizeof(struct second_dev));
  91.     second_setup_cdev(second_devp,0);
  92.     return 0;
  93. fail_malloc:
  94.     unregister_chrdev_region(devno,1);
  95.     return ret;
  96. }

  97. static void __exit second_exit(void)
  98. {
  99.     cdev_del(&second_devp->cdev);
  100.     kfree(second_devp);
  101.     unregister_chrdev_region(MKDEV(second_major,0),1);
  102. }

  103. MODULE_LICENSE("GPL");
  104. module_init(second_init);
  105. module_exit(second_exit);
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>//O_RDONLY

  5. int main(int argc, char **argv)
  6. {
  7.     int fd;
  8.     int counter = 0;
  9.     int old_counter = 0;

  10.     fd = open("/dev/second",O_RDONLY);
  11.     if(fd != -1)
  12.     {
  13.         while(1)
  14.         {
  15.             read(fd,&counter,sizeof(unsigned int));
  16.             if(counter != old_counter)
  17.             {
  18.                 printf("secons after open /dev/second:%d\n",counter);
  19.                 old_counter = counter;
  20.             }
  21.         }
  22.     }
  23.     else
  24.     {
  25.         printf("device open faile\n");
  26.         exit(EXIT_FAILURE);
  27.     }
  28. }

使用方法:
  1. ywx@ywx:~/Desktop/module/baohua/timer/timer_me$ ls
  2. app modules.order timer.c timer.mod.c timer.o
  3. Makefile Module.symvers timer.ko timer.mod.o
  4. ywx@ywx:~/Desktop/module/baohua/timer/timer_me$ sudo insmod ./timer.ko
  5. ywx@ywx:~/Desktop/module/baohua/timer/timer_me$ cat /proc/devices | grep second
  6. 240 second
  7. ywx@ywx:~/Desktop/module/baohua/timer/timer_me$ sudo mknod /dev/second c 240 0
  1. root@ywx:/home/ywx/desktop/module/baohua/timer/timer_me/app# ls
  2. app app.c app.c.old app.o Makefile
  3. root@ywx:/home/ywx/desktop/module/baohua/timer/timer_me/app# ./app
  4. secons after open /dev/second:1
  5. secons after open /dev/second:2
  6. secons after open /dev/second:3
  7. ^C
  8. root@ywx:/home/ywx/desktop/module/baohua/timer/timer_me/app#
  1. root@ywx:/home/ywx/desktop/module/baohua/timer/timer_me/app# dmesg | tail -20
  2. [ 6977.244239] currretn jiffies is 1669311
  3. [ 6978.245753] currretn jiffies is 1669561
  4. [ 6979.244045] currretn jiffies is 1669811
  5. [ 6980.244742] currretn jiffies is 1670061
  6. [ 6981.244750] currretn jiffies is 1670311
  7. [ 7448.756231] currretn jiffies is 1787189
  8. [ 7449.756231] currretn jiffies is 1787439


阅读(1979) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~