APP:
//author:DriverMonkey //phone:13410905075 //mail:[email protected] //qq:196568501 #include<stdio.h> #include<string.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<unistd.h> #define US (1000) #define PPM_CHANEL 8 #define FIX_LOW_TIME 100*US #define FIX_SYNC_TIME 5000 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,FIX_SYNC_TIME*US, }; // 9 int main(int argc,char *args[]) { int fd; int channel = 0; long long value = 0; fd=open("/dev/ppm",O_WRONLY|O_CREAT,0640); if(fd < 0) return 0; if(argc > 3) return; channel = atol(args[1]); printf("input channle is: %d\n", channel); value = atol(args[2]); printf("input value is: %d\n", (int)value ); printf("old value is:%d\n",(int)ppm_values[channel*2 + 1]); ppm_values[channel*2 + 1] = value*US; printf("new value is:%d\n",(int)ppm_values[channel*2 + 1]); write(fd,ppm_values,sizeof(ppm_values)); sleep(20); close(fd); }
Driver:
//author:DriverMonkey //phone:13410905075 //mail:[email protected] //qq:196568501 #include <linux/kernel.h> #include <linux/module.h> #include <linux/cdev.h> #include <linux/fs.h> #include <linux/device.h> #include <linux/syscalls.h> #include <linux/interrupt.h> #include <linux/gpio.h> #include <linux/of_gpio.h> #include <linux/of_platform.h> #include <linux/uaccess.h> #include <linux/string.h> #include <mach/gpio.h> #include <mach/irqs.h> #define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio)) #define US (1000) #define PPM_CHANEL 8 #define FIX_LOW_TIME 100*US struct 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, }; // 9 ktime_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 != sizeof(ppm_values)) 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");