S3C6410实时时钟RTC 秒字符设备

/*《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");
  }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值