您的位置:首页 > 运维架构 > Linux

LINUX 产生PPM 驱动例子

2013-07-26 19:20 921 查看
APP:

//author:DriverMonkey
//phone:13410905075
//mail:bookworepeng@Hotmail.com
//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:bookworepeng@Hotmail.com
//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");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: