linux利用键盘按键控制led灯,Linux驱动开发--通过按键控制led灯

/*request_irq()*/

#include /*work_struct*/

#define KEY_MAJOR 125

#define KEY_COUNT 4

#define DEVICE_NAME "key_led"

int key_major=KEY_MAJOR;

struct KEY{

int irq;

unsigned long flags;

char* name;

};

static struct KEY key[]={

{IRQ_EINT(0),IRQF_TRIGGER_LOW,"key1"},

{IRQ_EINT(1),IRQF_TRIGGER_LOW,"key2"},

{IRQ_EINT(2),IRQF_TRIGGER_LOW,"key3"},

{IRQ_EINT(3),IRQF_TRIGGER_LOW,"key4"},

};

struct KEY_DEV{

struct cdev cdev;

struct class* key_class;

struct work_struct key_workstruct;

int value;

};

struct KEY_DEV *key_dev;

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

{

struct KEY_DEV* dev;

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

filp->private_data=dev;

return 0;

}

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

{

return 0;

}

ssize_t key_read(struct file* filp,char __user *buf,size_t count,loff_t *f_pos)

{

return 0;

}

ssize_t key_write(struct file *filp,const char __user *buf,size_t count,loff_t *f_pos)

{

return 0;

}

long key_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)

{

struct KEY_DEV *key_dev=filp->private_data;

switch(cmd){

default:

return -ENOTTY;

}

return 0;

}

struct file_operations key_fops={

.owner=THIS_MODULE,

.open=key_open,

.read=key_read,

.write=key_write,

.unlocked_ioctl=key_ioctl,

.release=key_release,

};

void init_led(void)

{

int i;

s3c_gpio_cfgpin_range(S3C64XX_GPM(0),S3C64XX_GPM(3),S3C_GPIO_SFN(1));

for(i=0;i<4;i++){

gpio_set_value(S3C64XX_GPM(i),1);

}

for(i=0;i<4;i++){

s3c_gpio_setpull(S3C64XX_GPM(i),S3C_GPIO_PULL_NONE);

}

}

void led_on(int led_no)

{

switch(led_no)

{

case 1:

gpio_set_value(S3C64XX_GPM(0),0);

break;

case 2:

gpio_set_value(S3C64XX_GPM(1),0);

break;

case 3:

gpio_set_value(S3C64XX_GPM(2),0);

break;

case 4:

gpio_set_value(S3C64XX_GPM(3),0);

break;

default:

break;

}

}

irqreturn_t key_interrupt(int irq,void* dev_id)

{

switch(irq){

case IRQ_EINT(0):

key_dev->value=IRQ_EINT(0);

schedule_work(&(key_dev->key_workstruct));

break;

case IRQ_EINT(1):

key_dev->value=IRQ_EINT(1);

schedule_work(&(key_dev->key_workstruct));

break;

case IRQ_EINT(2):

key_dev->value=IRQ_EINT(2);

schedule_work(&(key_dev->key_workstruct));

break;

case IRQ_EINT(3):

key_dev->value=IRQ_EINT(3);

schedule_work(&(key_dev->key_workstruct));

break;

default:

schedule_work(&(key_dev->key_workstruct));

break;

}

return IRQ_HANDLED;

}

void do_workstruct(struct work_struct *work)

{

struct KEY_DEV* dev=container_of(work,struct KEY_DEV,key_workstruct);

init_led();

switch(dev->value)

{

case IRQ_EINT(0):

led_on(1);

break;

case IRQ_EINT(1):

led_on(2);

break;

case IRQ_EINT(2):

led_on(3);

break;

case IRQ_EINT(3):

led_on(4);

break;

default:

break;

}

printk("has key\n");

}

static int __init key_init(void)

{

int result,i;

dev_t devno;

if(KEY_MAJOR){

devno=MKDEV(KEY_MAJOR,0);

result=register_chrdev_region(devno,1,DEVICE_NAME);

}else{

result=alloc_chrdev_region(&devno,0,1,DEVICE_NAME);

key_major=MAJOR(devno);

}

if(result<0){

printk(KERN_WARNING "ERROR: can not register\n");

return result;

}

key_dev=kmalloc(sizeof(struct KEY_DEV),GFP_KERNEL);

if(!key_dev){

result=-ENOMEM;

goto fail;

}

memset(key_dev,0,sizeof(struct KEY_DEV));

cdev_init(&key_dev->cdev,&key_fops);

key_dev->cdev.owner=THIS_MODULE;

result=cdev_add(&key_dev->cdev,devno,1);

if(result){

printk(KERN_WARNING "ERROR: can not add cdev\n");

goto fail;

}

key_dev->key_class= class_create(THIS_MODULE,"key_class");

if(IS_ERR(key_dev->key_class)){

printk("Err: failed increating class.\n");

return -1;

}

device_create(key_dev->key_class, NULL, devno,NULL,DEVICE_NAME);

INIT_WORK(&(key_dev->key_workstruct),do_workstruct);

for(i=0;icdev);

kfree(key_dev);

}

device_destroy(key_dev->key_class,devno);

class_destroy(key_dev->key_class);

unregister_chrdev_region(devno,1);

}

MODULE_LICENSE("Dual BSD/GPL");

MODULE_AUTHOR("yixuaning ");

module_init(key_init);

module_exit(key_exit);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值