S3C6410实时时钟RTC 秒字符设备

来源:互联网 发布:淘宝男t恤店推荐 编辑:程序博客网 时间:2024/04/29 08:13

/*《linux 设备驱动开发详解》

驱动程序

*/

 

#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>#define SECOND_MAJOR 248    /*预设的second的主设备号*/                                                                                                  static int second_major = SECOND_MAJOR;                                                                                                                 /*second设备结构体*/                                                        struct second_dev {                                                           struct cdev cdev; /*cdev结构体*/                                            atomic_t counter;/* 一共经历了多少秒?*/                                    struct timer_list s_timer; /*设备要使用的定时器*/                         };                                                                                                                                                      struct second_dev *second_devp; /*设备结构体指针*/                                                                                                      /*定时器处理函数*/                                                          static void second_timer_handle(unsigned long arg)                          {                                                                             mod_timer(&second_devp->s_timer,jiffies + HZ);                              atomic_inc(&second_devp->counter);                                                                                                                      printk(KERN_NOTICE "current jiffies is %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); //计数清0                                                                                                          return 0;                                                                 }                                                                           /*文件释放函数*/                                                            int second_release(struct inode *inode, struct file *filp)                  {                                                                             del_timer(&second_devp->s_timer);                                                                                                                       return 0;                                                                 }                                                                                                                                                       /*读函数*/                                                                  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 const struct file_operations second_fops = {                           .owner = THIS_MODULE,                                                       .open = second_open,                                                        .release = second_release,                                                  .read = second_read,                                                      };                                                                                                                                                      /*初始化并注册cdev*/                                                        static void second_setup_cdev(struct second_dev *dev, int index)            {                                                                             int err, devno = MKDEV(second_major, index);                                                                                                            cdev_init(&dev->cdev, &second_fops);                                        dev->cdev.owner = THIS_MODULE;                                              err = cdev_add(&dev->cdev, devno, 1);                                       if (err)                                                                      printk(KERN_NOTICE "Error %d adding LED%d", err, index);                }                                                                                                                                                       /*设备驱动模块加载函数*/                                                    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_malloc;                                                         }                                                                           memset(second_devp, 0, sizeof(struct second_dev));                          second_setup_cdev(second_devp, 0);                                          return 0;                                                                 fail_malloc:  unregister_chrdev_region(devno, 1);  return ret;                          }                                                                           /*模块卸载函数*/                                                            void second_exit(void)                                                      {                                                                             cdev_del(&second_devp->cdev);   /*注销cdev*/                                kfree(second_devp);     /*释放设备结构体内存*/                              unregister_chrdev_region(MKDEV(second_major, 0), 1); /*释放设备号*/       }                                                                                                                                                       MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");                            MODULE_LICENSE("Dual BSD/GPL");                                                                                                                         module_param(second_major, int, S_IRUGO);                                                                                                               module_init(second_init);                                                   module_exit(second_exit);             

 

 

/*应用程序*/

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <signal.h>#include <sys/stat.h>main(){  int fd;  int counter = 0;  int old_counter = 0;   /*打开/dev/second设备文件*/  fd = open("/dev/second", O_RDONLY);  if (fd != - 1) {    while (1) {      read(fd,&counter, sizeof(unsigned int));/* 读目前经历的秒数 */      if(counter!=old_counter) {        printf("seconds after open /dev/second :%d\n",counter);       old_counter = counter;      }     }     } else {    printf("Device open failure\n");  }}


原创粉丝点击