歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

S3C6410實時時鐘RTC 秒字符設備

/*《Linux 設備驅動開發詳解》 http://www.linuxidc.com/Linux/2011-07/38211.htm

驅動程序

*/

  1. #include <linux/module.h>  
  2. #include <linux/types.h>  
  3. #include <linux/fs.h>  
  4. #include <linux/errno.h>  
  5. #include <linux/mm.h>  
  6. #include <linux/sched.h>  
  7. #include <linux/init.h>  
  8. #include <linux/cdev.h>  
  9. #include <asm/io.h>  
  10. #include <asm/system.h>  
  11. #include <asm/uaccess.h>  
  12.   
  13. #define SECOND_MAJOR 248    /*預設的second的主設備號*/                        
  14.                                                                               
  15. static int second_major = SECOND_MAJOR;                                       
  16.                                                                               
  17. /*second設備結構體*/                                                          
  18. struct second_dev {                                                           
  19.   struct cdev cdev; /*cdev結構體*/                                            
  20.   atomic_t counter;/* 一共經歷了多少秒?*/                                    
  21.   struct timer_list s_timer; /*設備要使用的定時器*/                           
  22. };                                                                            
  23.                                                                               
  24. struct second_dev *second_devp; /*設備結構體指針*/                            
  25.                                                                               
  26. /*定時器處理函數*/                                                            
  27. static void second_timer_handle(unsigned long arg)                            
  28. {                                                                             
  29.   mod_timer(&second_devp->s_timer,jiffies + HZ);                              
  30.   atomic_inc(&second_devp->counter);                                          
  31.                                                                               
  32.   printk(KERN_NOTICE "current jiffies is %ld\n", jiffies);                    
  33. }                                                                             
  34.                                                                               
  35. /*文件打開函數*/                                                              
  36. int second_open(struct inode *inode, struct file *filp)                       
  37. {                                                                             
  38.   /*初始化定時器*/                                                            
  39.   init_timer(&second_devp->s_timer);                                          
  40.   second_devp->s_timer.function = &second_timer_handle;                       
  41.   second_devp->s_timer.expires = jiffies + HZ;                                
  42.                                                                               
  43.   add_timer(&second_devp->s_timer); /*添加(注冊)定時器*/                    
  44.                                                                               
  45.   atomic_set(&second_devp->counter,0); //計數清0                              
  46.                                                                               
  47.   return 0;                                                                   
  48. }                                                                             
  49. /*文件釋放函數*/                                                              
  50. int second_release(struct inode *inode, struct file *filp)                    
  51. {                                                                             
  52.   del_timer(&second_devp->s_timer);                                           
  53.                                                                               
  54.   return 0;                                                                   
  55. }                                                                             
  56.                                                                               
  57. /*讀函數*/                                                                    
  58. static ssize_t second_read(struct file *filp, char __user *buf, size_t count,  
  59.   loff_t *ppos)                                                               
  60. {                                                                             
  61.   int counter;                                                                
  62.                                                                               
  63.   counter = atomic_read(&second_devp->counter);                               
  64.   if(put_user(counter, (int*)buf))                                            
  65.    return - EFAULT;                                                          
  66.   else                                                                        
  67.    return sizeof(unsigned int);                                              
  68. }                                                                             
  69.                                                                               
  70. /*文件操作結構體*/                                                            
  71. static const struct file_operations second_fops = {                           
  72.   .owner = THIS_MODULE,                                                       
  73.   .open = second_open,                                                        
  74.   .release = second_release,                                                  
  75.   .read = second_read,                                                        
  76. };                                                                            
  77.                                                                               
  78. /*初始化並注冊cdev*/                                                          
  79. static void second_setup_cdev(struct second_dev *dev, int index)              
  80. {                                                                             
  81.   int err, devno = MKDEV(second_major, index);                                
  82.                                                                               
  83.   cdev_init(&dev->cdev, &second_fops);                                        
  84.   dev->cdev.owner = THIS_MODULE;                                              
  85.   err = cdev_add(&dev->cdev, devno, 1);                                       
  86.   if (err)                                                                    
  87.     printk(KERN_NOTICE "Error %d adding LED%d", err, index);                  
  88. }                                                                             
  89.                                                                               
  90. /*設備驅動模塊加載函數*/                                                      
  91. int second_init(void)                                                         
  92. {                                                                             
  93.   int ret;                                                                    
  94.   dev_t devno = MKDEV(second_major, 0);                                       
  95.                                                                               
  96.   /* 申請設備號*/                                                             
  97.   if (second_major)                                                           
  98.     ret = register_chrdev_region(devno, 1, "second");                         
  99.   else { /* 動態申請設備號 */                                                 
  100.     ret = alloc_chrdev_region(&devno, 0, 1, "second");                        
  101.     second_major = MAJOR(devno);                                              
  102.   }                                                                           
  103.   if (ret < 0)                                                                
  104.     return ret;                                                               
  105.   /* 動態申請設備結構體的內存*/                                               
  106.   second_devp = kmalloc(sizeof(struct second_dev), GFP_KERNEL);               
  107.   if (!second_devp) {   /*申請失敗*/                                          
  108.     ret =  - ENOMEM;                                                          
  109.     goto fail_malloc;                                                         
  110.   }                                                                           
  111.   
  112.   memset(second_devp, 0, sizeof(struct second_dev));                          
  113.   
  114.   second_setup_cdev(second_devp, 0);                                          
  115.   
  116.   return 0;                                                                   
  117.   
  118. fail_malloc:  
  119.   unregister_chrdev_region(devno, 1);  
  120.   return ret;                            
  121. }                                                                             
  122.   
  123. /*模塊卸載函數*/                                                              
  124. void second_exit(void)                                                        
  125. {                                                                             
  126.   cdev_del(&second_devp->cdev);   /*注銷cdev*/                                
  127.   kfree(second_devp);     /*釋放設備結構體內存*/                              
  128.   unregister_chrdev_region(MKDEV(second_major, 0), 1); /*釋放設備號*/         
  129. }                                                                             
  130.                                                                               
  131. MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");                              
  132. MODULE_LICENSE("Dual BSD/GPL");                                               
  133.                                                                               
  134. module_param(second_major, int, S_IRUGO);                                     
  135.                                                                               
  136. module_init(second_init);                                                     
  137. module_exit(second_exit);       

/*應用程序*/

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <fcntl.h>  
  5. #include <signal.h>  
  6. #include <sys/stat.h>  
  7.   
  8. main()  
  9. {  
  10.   int fd;  
  11.   int counter = 0;  
  12.   int old_counter = 0;  
  13.    
  14.   /*打開/dev/second設備文件*/  
  15.   fd = open("/dev/second", O_RDONLY);  
  16.   if (fd != - 1) {  
  17.     while (1) {  
  18.       read(fd,&counter, sizeof(unsigned int));/* 讀目前經歷的秒數 */  
  19.       if(counter!=old_counter) {   
  20.        printf("seconds after open /dev/second :%d\n",counter);  
  21.        old_counter = counter;  
  22.       }   
  23.     }     
  24.   } else {  
  25.     printf("Device open failure\n");  
  26.   }  
  27. }  

Copyright © Linux教程網 All Rights Reserved