linux用户空间驱动,用mmap写Linux用户空间驱动

/*

* PB18_IRQTest.c

* This is  a test program for sam9260, using PB19(J5_18 pin) input a signal to PB18(J5_16 pin),

* PB18 receive this signal as IRQ and make the LED linking on PB17((J5_14 pin)) turn on or turn off

*

*           @Author: Cun Tian Rui

*           @Date :March.18.2011

*/

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

void led_on()

{

at91_set_gpio_output(AT91_PIN_PB17,1);

}

void led_off()

{

at91_set_gpio_output(AT91_PIN_PB17 ,0);

}

struct light_dev *light_devp;

int light_major = 200;

struct light_dev

{

struct cdev cdev;

unsigned char value;

};

MODULE_AUTHOR("Cun Tian Rui");

MODULE_LICENSE("Dual BSD/GPL");

static void io_init(void)

{

at91_set_gpio_input(AT91_PIN_PB18, 1);

at91_set_deglitch(AT91_PIN_PB18, 1);

at91_sys_write(1 + PIO_IDR,  1<<18);

at91_sys_write(1 + PIO_IER,  (~(1<<18)));

at91_sys_write(AT91_PMC_PCER, 1 <

}

struct gpio_irq_desc

{

int irq;

unsigned long flags;

char *name;

};

static struct gpio_irq_desc PB18_IRQ={AT91_PIN_PB18,AT91_AIC_SRCTYPE_LOW,"PB18"};

static irqreturn_t PB18_intHandle(int irq, void *dev_id)

{

led_on();

return IRQ_RETVAL(IRQ_HANDLED);

}

int light_open(struct inode *inode,struct file *filp)

{

int err;

struct light_dev *dev;

dev = container_of(inode->i_cdev,struct light_dev,cdev);

filp->private_data = dev;

io_init();

err = request_irq(PB18_IRQ.irq,PB18_intHandle,PB18_IRQ.flags,PB18_IRQ.name,(void*)0);

if(err)

{

free_irq(PB18_IRQ.irq,(void*)0);

return  -EBUSY;

}

return 0;

}

int light_release(struct inode *inode,struct file *filp)

{

free_irq(PB18_IRQ.irq,(void*)0);

return 0;

}

// ioctl

int light_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,

unsigned long arg)

{

struct light_dev *dev = filp->private_data;

switch(cmd)

{

case 0:

at91_set_gpio_output(AT91_PIN_PB19,0);

break;

case 1:

at91_set_gpio_output(AT91_PIN_PB19,1);

led_off();

break;

default:

return -ENOTTY;

// break;

}

return 0;

}

struct file_operations light_fops =

{

.owner = THIS_MODULE,

.ioctl = light_ioctl,

.open  = light_open,

.release = light_release,

};

static void light_setup_cdev(struct light_dev *dev,int index)

{

int err,devno = MKDEV(light_major,index);

cdev_init(&dev->cdev,&light_fops);

dev->cdev.owner = THIS_MODULE;

dev->cdev.ops = &light_fops;

err = cdev_add(&dev->cdev,devno,1);

if(err)

{

printk(KERN_NOTICE "Error %d adding LED%d",err,index);

}

}

int light_init(void)

{

int result;

dev_t dev = MKDEV(light_major,0);

if(light_major)

{

result = register_chrdev_region(dev,1,"PB18_IRQTest");

}

if(result 

{

return result;

}

light_devp = kmalloc(sizeof(struct light_dev),GFP_KERNEL);

if(!light_devp)

{

result = - ENOMEM;

goto fail_malloc;

}

memset(light_devp,0,sizeof(struct light_dev));

light_setup_cdev(light_devp,0);

return 0;

fail_malloc:unregister_chrdev_region(dev,light_devp);

return result;

}

void light_cleanup(void)

{

cdev_del(&light_devp->cdev);

kfree(light_devp);

unregister_chrdev_region(MKDEV(light_major,0),1);

}

module_init(light_init);

module_exit(light_cleanup);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值