LINUX 产生PPM 驱动例子

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");  






 


你可能感兴趣的:(linux)