欢迎访问华乐美文网

按键驱动改写成input驱动

改写2021-01-13 11:57书业网

1、建立文件夹InputKey

2、在文件夹InputKey下建立驱动程序inputDev.c。

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/fs.h>

#include <linux/init.h>

#include <linux/delay.h>

#include <linux/poll.h>

#include <linux/irq.h>

#include <asm/irq.h>

#include <asm/uaccess.h>

#include <mach/regs-gpio.h>

#include <mach/hardware.h>

#include <linux/platform_device.h>

#include <linux/cdev.h>

#include <linux/miscdevice.h>

#include <linux/gpio.h>

#include <linux/interrupt.h>

#include <linux/sched.h>

#include <linux/input.h>

MODULE_AUTHOR("wjb");

MODULE_LICENSE("GPL");

struct input_dev* button_devp;

struct button_irq_desc{

int irq;

int pin;

int number;

char *name;

};

static struct button_irq_desc button_irqs[] = {

{IRQ_EINT8, S3C2410_GPG(0), 0, "KEY0"},

{IRQ_EINT11, S3C2410_GPG(3), 1, "KEY1"},

{IRQ_EINT13, S3C2410_GPG(5), 2, "KEY2"},

{IRQ_EINT15, S3C2410_GPG(6), 3, "KEY3"},

{IRQ_EINT14, S3C2410_GPG(7), 4, "KEY4"},

{IRQ_EINT19, S3C2410_GPG(11), 5, "KEY5"},

};

static irqreturn_t button_interrupt(int irq, void* dev_id)

{

struct button_irq_desc *button_irqs = (struct button_irq_desc*)dev_id;

int down;

down = !s3c2410_gpio_getpin(button_irqs->pin);

switch(button_irqs->irq)

{

case IRQ_EINT8:

input_report_key(button_devp, BTN_0, down);

input_sync(button_devp);

break;

case IRQ_EINT11:

input_report_key(button_devp, BTN_1, down);

input_sync(button_devp);

break;

case IRQ_EINT13:

input_report_key(button_devp, BTN_2, down);

input_sync(button_devp);

break;

case IRQ_EINT15:

input_report_key(button_devp, BTN_3, down);

input_sync(button_devp);

break;

case IRQ_EINT14:

input_report_key(button_devp, BTN_4, down);

input_sync(button_devp);

break;

case IRQ_EINT19:

input_report_key(button_devp, BTN_5, down);

input_sync(button_devp);

break;

default:

break;

}

return IRQ_RETVAL(IRQ_HANDLED);

}

static int __init button_init(void)

{

int i;

int err;

button_devp = input_allocate_device();

for(i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++)

{

if(button_irqs[i].irq < 0)

{

continue;

}

err = request_irq(button_irqs[i].irq, button_interrupt, IRQ_TYPE_EDGE_BOTH, button_irqs[i].name, (void *)&button_irqs[i]);

if(err)

{

break;

}

}

if(err)

{

i--;

for(; i >= 0; i--)

{

if(button_irqs[i].irq < 0)

{

continue;

}

disable_irq(button_irqs[i].irq);

free_irq(button_irqs[i].irq, (void*)&button_irqs[i]);

}

return -EBUSY;

}

set_bit(EV_KEY, button_devp->evbit);

set_bit(BTN_0, button_devp->keybit);

set_bit(BTN_1, button_devp->keybit);

set_bit(BTN_2, button_devp->keybit);

set_bit(BTN_3, button_devp->keybit);

set_bit(BTN_4, button_devp->keybit);

set_bit(BTN_5, button_devp->keybit);

input_register_device(button_devp);

return 0;

}

static void __exit button_exit(void)

{

int i = 5;

input_unregister_device(button_devp);

for(i = 5; i >= 0; i--)

{

if(button_irqs[i].irq < 0)

{

continue;

}

disable_irq(button_irqs[i].irq);

free_irq(button_irqs[i].irq, (void*)&button_irqs[i]);

}

}

module_init(button_init);

module_exit(button_exit);

这里有两点要注意:

1)button_init函数一定要返回一个值。不然虽然能编译通过,但是运行会有问题。

2)中断处理函数返回值不能是void型。据说这个是2.6内核和2.4内核的区别。同样,如果返回值为void,编译也没问题,运行会有bad_irq字样的错误。

3、Makefile

ifneq ($(KERNELRELEASE), )

obj-m := inputDev.o

else

KDIR := /usr/src/linux-2.6.32.2

all:

make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux- clean:

rm -f *.ko *.o *.mod.o *.mod.c *.symvers

endif

4、make

运行make命令,会生成inputDev.ko。

5、编写应用程序appInputDev.c

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <stdint.h>

#include <sys/ioctl.h>

#include <sys/fcntl.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <linux/input.h>

int main(void)

{

struct input_event ev_key;

int fd = open("/dev/input/event1", O_RDWR);

while(1)

{

int count = read(fd, &ev_key, sizeof(struct input_event));

if(EV_KEY == ev_key.type)

{

printf("time : %ld, %d", ev_key.time.tv_sec, ev_key.time.tv_usec);

printf(" type:%d code : %d value : %d /n", ev_key.type, ev_key.code, ev_key.value); }

}

return 0;

}

注意:此处打开的文件是/dev/input/event1,之所以是event1,而不是event0,或者event2等等,主要是我发现系统之前已经有一个/dev/input/event0,而添加了这个设备模块后,/dev/input/event1就多出来了。但是如果我们有多个input设备同时注册,那么具体该打开的文件是哪个,我还有点不懂。

6、生成应用程序

使用命令arm-linux-gcc -o appInput appInputDev.c,将会生成应用程序appInput。

7、测试

将inputDev.ko和appInput拷贝到开发板。

1)使用insmod inputDev.ko将设备注册。

这时候,会发现/dev/input/下多出一个event1,用cat /dev/bus/input/devices,会发现一个新的虚拟设备/devices/virtual/input/input1已经存在了,其handler正是event1。(如果使用rmmod inputDev将inputDev设备模块移掉,然后再insmod inputDev.ko,会发现新的虚拟设备变成/devices/virtual/input/input2了,但是handler仍旧是event1;继续多删除模块添加模块几次,/devices/virtual/input/input*的数值会继续增长。)

2)执行./appInput,运行appInput。然后按下任意一个按键,会发现有输出: time : 1293632357, 846429 type:1 code : 257 value : 1

  • 改写拟人句的方法 [1500字]
  • 古诗改写
  • 古诗改写成小故事 (精选)
  • 作文改写 (2000字)
  • 改写句子 [1000字]

Copyright @ 2012-2024华乐美文网 All Rights Reserved. 版权所有