//author:DriverMonkey//phone:13410905075//mail:bookworepeng@Hotmail.com//qq:196568501#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))#define US (1000)#define PPM_CHANEL 8#define FIX_LOW_TIME 100*USstruct ppm_dev { struct cdev cdev; dev_t devno; struct class *ppm_class; int message_cdev_open; }; struct ppm_dev ppm_dev; static long long ppm_values[(PPM_CHANEL + 1)*2] = {FIX_LOW_TIME,1000*US, // 1 FIX_LOW_TIME,1000*US, // 2 FIX_LOW_TIME,1000*US, // 3 FIX_LOW_TIME,1000*US, // 4 FIX_LOW_TIME,1000*US, // 5 FIX_LOW_TIME,1000*US, // 6 FIX_LOW_TIME,1000*US, // 7 FIX_LOW_TIME,1000*US, // 8 FIX_LOW_TIME,5000*US, }; // 9ktime_t ktime;static struct hrtimer hr_timer;static enum hrtimer_restart hrtimer_callback(struct hrtimer *timer){ static int index = 0; static ktime_t ktime; if(index == ((PPM_CHANEL + 1)*2)) index = 0; ktime.tv64 = ppm_values[index]; hrtimer_forward(timer, timer->base->get_time(), ktime); index++; if(ktime.tv64 == FIX_LOW_TIME) gpio_direction_output(GPIO_TO_PIN(0,27), 0); else gpio_direction_output(GPIO_TO_PIN(0,27), 1); //printk("%d\n",(int)ktime.tv64); return HRTIMER_RESTART;}static int ppm_open(struct inode *node, struct file *fd) { int ret = 0; printk("ppm_open()++\n"); ktime = ktime_set( 0, 200*1000); // 200us hrtimer_init( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); hr_timer.function = &hrtimer_callback; hrtimer_start( &hr_timer, ktime, HRTIMER_MODE_REL ); printk("ppm_open()--\n"); return ret; } ssize_t ppm_write(struct file *pfile, const char __user *buffer, size_t size, loff_t *pnull) { printk("ppm_write()++\n"); if(size != (PPM_CHANEL * sizeof(long long))) return 0; //copy_from_user(ppm_values, buffer, size); printk("ppm_write()--\n"); return size;}static int ppm_fasync(int fd, struct file *filp, int mode){ printk("ppm_fasync()++\n"); printk("ppm_fasync()--\n"); return 0;}static int ppm_release(struct inode *node, struct file *fd) { printk("ppm_release()++\n"); hrtimer_cancel(&hr_timer); printk("ppm_release()--\n"); return 0; } struct file_operations meassage_operatons = { .owner = THIS_MODULE, .open = ppm_open, .write = ppm_write, .fasync = ppm_fasync, .release = ppm_release, }; static int __init ppm_init(void) { struct ppm_dev * dev; int ret = 0; dev = &ppm_dev; alloc_chrdev_region(&dev->devno, 0, 1, "out_ppm"); dev->ppm_class = class_create(THIS_MODULE, "ppm_class"); if(IS_ERR(dev->ppm_class)) { printk(KERN_ERR"Err: failed in creating class./n"); goto fail1; } device_create(dev->ppm_class, NULL, dev->devno, NULL, "ppm"); //init irq ret = gpio_request(GPIO_TO_PIN(0,27), "ppm_inter"); if(ret){ printk(KERN_ERR"gpio_request() failed !\n"); goto fail1; } ret = gpio_direction_output(GPIO_TO_PIN(0,27), 1); if(ret){ printk(KERN_ERR"gpio_direction_input() failed !\n"); goto fail2; } cdev_init(&dev->cdev, &meassage_operatons); cdev_add(&dev->cdev, dev->devno, 1); if(ret){ printk(KERN_ERR"request_irq() failed ! %d\n", ret); goto fail2; } printk("ppm_to_app_init(void)--\n"); return 0; fail2: gpio_free(GPIO_TO_PIN(0,27)); fail1: device_destroy(dev->ppm_class, dev->devno); class_destroy(dev->ppm_class); cdev_del(&dev->cdev); unregister_chrdev_region(dev->devno, 1); return ret;} static void __exit ppm_exit(void) { struct ppm_dev *dev = &ppm_dev; // printk("ppm_to_app_exit(void)++\n"); gpio_free(GPIO_TO_PIN(0,27)); device_destroy(dev->ppm_class, dev->devno); class_destroy(dev->ppm_class); cdev_del(&dev->cdev); unregister_chrdev_region(dev->devno, 1); // printk("ppm_to_app_exit(void)--\n"); } module_init(ppm_init); module_exit(ppm_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Driver Monkey"); MODULE_DESCRIPTION("Test ppm");