LINUX 产生PPM 驱动例子

APP:

[cpp] view plain copy
 
  1. //author:DriverMonkey  
  2. //phone:13410905075  
  3. //mail:bookworepeng@Hotmail.com  
  4. //qq:196568501  
  5.   
  6.   
  7. #include<stdio.h>  
  8. #include<string.h>  
  9. #include<sys/types.h>  
  10. #include<sys/stat.h>  
  11. #include<fcntl.h>  
  12. #include<unistd.h>  
  13.   
  14. #define US (1000)  
  15.   
  16. #define PPM_CHANEL 8  
  17. #define FIX_LOW_TIME 100*US  
  18. #define FIX_SYNC_TIME 5000  
  19.   
  20. static long long ppm_values[(PPM_CHANEL + 1)*2] =   
  21.        {FIX_LOW_TIME,1000*US,   // 1  
  22.        FIX_LOW_TIME,1000*US,    // 2  
  23.        FIX_LOW_TIME,1000*US,    // 3  
  24.        FIX_LOW_TIME,1000*US,    // 4  
  25.        FIX_LOW_TIME,1000*US,    // 5  
  26.        FIX_LOW_TIME,1000*US,    // 6  
  27.        FIX_LOW_TIME,1000*US,    // 7  
  28.        FIX_LOW_TIME,1000*US,    // 8  
  29.        FIX_LOW_TIME,FIX_SYNC_TIME*US, };    // 9  
  30.   
  31.   
  32. int main(int argc,char *args[])  
  33. {  
  34.     int fd;  
  35.     int channel = 0;  
  36.     long long value = 0;  
  37.       
  38.     fd=open("/dev/ppm",O_WRONLY|O_CREAT,0640);  
  39.     if(fd < 0)  
  40.         return 0;  
  41.   
  42.     if(argc > 3)   
  43.         return;  
  44.     channel = atol(args[1]);  
  45.     printf("input channle is: %d ", channel);  
  46.       
  47.     value  = atol(args[2]);  
  48.     printf("input value is: %d ", (int)value );  
  49.   
  50.     printf("old value is:%d ",(int)ppm_values[channel*2 + 1]);  
  51.     ppm_values[channel*2 + 1] = value*US;  
  52.     printf("new value is:%d ",(int)ppm_values[channel*2 + 1]);  
  53.       
  54.     write(fd,ppm_values,sizeof(ppm_values));  
  55.   
  56.     sleep(20);  
  57.     close(fd);  
  58. }  

Driver:

[cpp] view plain copy
 
  1. //author:DriverMonkey  
  2. //phone:13410905075  
  3. //mail:bookworepeng@Hotmail.com  
  4. //qq:196568501  
  5.   
  6.   
  7. #include <linux/kernel.h>    
  8. #include <linux/module.h>    
  9. #include <linux/cdev.h>    
  10. #include <linux/fs.h>    
  11. #include <linux/device.h>    
  12. #include <linux/syscalls.h>  
  13. #include <linux/interrupt.h>   
  14. #include <linux/gpio.h>  
  15. #include <linux/of_gpio.h>  
  16. #include <linux/of_platform.h>  
  17. #include <linux/uaccess.h>    
  18. #include <linux/string.h>   
  19.   
  20. #include <mach/gpio.h>  
  21. #include <mach/irqs.h>  
  22.   
  23. #define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))  
  24.   
  25. #define US (1000)  
  26.   
  27. #define PPM_CHANEL 8  
  28. #define FIX_LOW_TIME 100*US  
  29.   
  30.   
  31. struct ppm_dev    
  32. {    
  33.     struct cdev cdev;    
  34.     dev_t devno;    
  35.     struct class *ppm_class;   
  36.     int message_cdev_open;    
  37. };   
  38.   
  39. struct ppm_dev ppm_dev;    
  40.   
  41.   
  42. static long long ppm_values[(PPM_CHANEL + 1)*2] =   
  43.        {FIX_LOW_TIME,1000*US,   // 1  
  44.        FIX_LOW_TIME,1000*US,    // 2  
  45.        FIX_LOW_TIME,1000*US,    // 3  
  46.        FIX_LOW_TIME,1000*US,    // 4  
  47.        FIX_LOW_TIME,1000*US,    // 5  
  48.        FIX_LOW_TIME,1000*US,    // 6  
  49.        FIX_LOW_TIME,1000*US,    // 7  
  50.        FIX_LOW_TIME,1000*US,    // 8  
  51.        FIX_LOW_TIME,5000*US, }; // 9  
  52.   
  53. ktime_t ktime;  
  54. static struct hrtimer hr_timer;  
  55.   
  56. static enum hrtimer_restart hrtimer_callback(struct hrtimer *timer)  
  57. {  
  58.     static int index = 0;  
  59.     static ktime_t ktime;  
  60.     if(index == ((PPM_CHANEL + 1)*2))  
  61.         index = 0;  
  62.     ktime.tv64 = ppm_values[index];  
  63.     hrtimer_forward(timer, timer->base->get_time(), ktime);  
  64.     index++;  
  65.     if(ktime.tv64 == FIX_LOW_TIME)  
  66.         gpio_direction_output(GPIO_TO_PIN(0,27), 0);  
  67.     else  
  68.         gpio_direction_output(GPIO_TO_PIN(0,27), 1);  
  69.   
  70.     //printk("%d ",(int)ktime.tv64);  
  71.       
  72.     return HRTIMER_RESTART;  
  73. }  
  74.   
  75.   
  76. static int ppm_open(struct inode *node, struct file *fd)    
  77. {    
  78.     int ret = 0;  
  79.       
  80.     printk("ppm_open()++ ");   
  81.       
  82.     ktime = ktime_set( 0, 200*1000);                   // 200us  
  83.     hrtimer_init( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );  
  84.     hr_timer.function = &hrtimer_callback;  
  85.     hrtimer_start( &hr_timer, ktime, HRTIMER_MODE_REL );  
  86.   
  87.   
  88.     printk("ppm_open()-- ");    
  89.     
  90.     return ret;    
  91. }     
  92.   
  93.  ssize_t ppm_write(struct file *pfile,   
  94.                     const char __user *buffer,   
  95.                     size_t size,   
  96.                     loff_t *pnull)  
  97.    
  98. {     
  99.   
  100.     printk("ppm_write()++ ");  
  101.       
  102.     if(size != sizeof(ppm_values))  
  103.         return 0;  
  104.   
  105.     copy_from_user(ppm_values, buffer, size);  
  106.   
  107.     printk("ppm_write()-- ");  
  108.       
  109.     return size;  
  110. }  
  111. static int ppm_fasync(int fd, struct file *filp, int mode)  
  112. {  
  113.   
  114.     printk("ppm_fasync()++ ");  
  115.       
  116.   
  117.     printk("ppm_fasync()-- ");  
  118.       
  119.     return 0;  
  120. }  
  121.   
  122. static int ppm_release(struct inode *node, struct file *fd)    
  123. {    
  124.     printk("ppm_release()++ ");   
  125.   
  126.     hrtimer_cancel(&hr_timer);    
  127.     printk("ppm_release()-- ");    
  128.     return 0;    
  129. }   
  130.   
  131.   
  132. struct file_operations meassage_operatons =    
  133. {    
  134.     .owner = THIS_MODULE,    
  135.     .open = ppm_open,    
  136.       
  137.     .write = ppm_write,  
  138.     .fasync = ppm_fasync,  
  139.     .release = ppm_release,    
  140. };    
  141.     
  142. static int __init ppm_init(void)    
  143. {    
  144.     struct ppm_dev * dev;    
  145.     int ret = 0;  
  146.     
  147.   
  148.     dev = &ppm_dev;    
  149.   
  150.     alloc_chrdev_region(&dev->devno, 0, 1, "out_ppm");    
  151.   
  152.     dev->ppm_class = class_create(THIS_MODULE, "ppm_class");    
  153.     if(IS_ERR(dev->ppm_class)) {    
  154.          printk(KERN_ERR"Err: failed in creating class./n");    
  155.          goto fail1;     
  156.      }    
  157.     device_create(dev->ppm_class, NULL, dev->devno, NULL, "ppm");    
  158.   
  159.       
  160.     //init irq  
  161.     ret = gpio_request(GPIO_TO_PIN(0,27), "ppm_inter");  
  162.     if(ret){  
  163.         printk(KERN_ERR"gpio_request() failed ! ");  
  164.         goto fail1;  
  165.     }  
  166.     ret = gpio_direction_output(GPIO_TO_PIN(0,27), 1);  
  167.     if(ret){  
  168.         printk(KERN_ERR"gpio_direction_input() failed ! ");  
  169.         goto fail2;   
  170.     }  
  171.       
  172.     cdev_init(&dev->cdev, &meassage_operatons);    
  173.     cdev_add(&dev->cdev, dev->devno, 1);    
  174.   
  175.       
  176.     if(ret){  
  177.         printk(KERN_ERR"request_irq() failed ! %d ", ret);  
  178.         goto fail2;  
  179.     }  
  180.       
  181.    printk("ppm_to_app_init(void)-- ");        
  182.     return 0;    
  183.   
  184. fail2:    
  185.     gpio_free(GPIO_TO_PIN(0,27));     
  186. fail1:      
  187.     device_destroy(dev->ppm_class, dev->devno);    
  188.     class_destroy(dev->ppm_class);     
  189.     cdev_del(&dev->cdev);    
  190.     unregister_chrdev_region(dev->devno, 1);    
  191.   
  192.     return ret;  
  193. }    
  194. static void __exit ppm_exit(void)    
  195. {    
  196.     struct ppm_dev *dev = &ppm_dev;    
  197.     
  198.    // printk("ppm_to_app_exit(void)++ ");   
  199.     gpio_free(GPIO_TO_PIN(0,27));  
  200.   
  201.     device_destroy(dev->ppm_class, dev->devno);    
  202.     class_destroy(dev->ppm_class);     
  203.     cdev_del(&dev->cdev);    
  204.     unregister_chrdev_region(dev->devno, 1);    
  205.          
  206.    // printk("ppm_to_app_exit(void)-- ");    
  207. }    
  208. module_init(ppm_init);    
  209. module_exit(ppm_exit);    
  210.     
  211. MODULE_LICENSE("GPL");    
  212. MODULE_AUTHOR("Driver Monkey");    
  213. MODULE_DESCRIPTION("Test ppm");  
原文地址:https://www.cnblogs.com/Ph-one/p/6015688.html