主機:centos 6.7
開發板:FL2440
系統內核版本:Linux 3.0
編譯器:arm-Linux-gcc-4.5.4
芯片:Samsung S3C2400
[hongfuhao@centos6 input_kbd]$ ls
kbd_device.c kbd_driver.c event_button.c kbd_driver.h Makefile驅動相關頭文件kbd_driver.h:
- /*****************************************************************************
- * Copyright: (C) 2016 Guo Wenxue<[email protected]>
- * All rights reserved.
- *
- * Filename: kbd_driver.h
- * Description: This head file is for s3c keyboard driver
- *
- * Version: 1.0.0(07/26/2016)
- * Author: Guo Wenxue <[email protected]>
- * ChangeLog: 1, Release initial version on "07/26/2016 06:54:47 PM"
- *
- ********************************************************************************/
- #ifndef _KBD_DRIVER_H_
- #define _KBD_DRIVER_H_
- /* keyboard hardware informtation structure definition */
- typedef struct s3c_kbd_info_s
- {
- int code; /* input device key code */
- int nIRQ; /* keyboard IRQ number*/
- unsigned int setting; /* keyboard IRQ Pin Setting*/
- unsigned int gpio; /* keyboard GPIO port */
- } s3c_kbd_info_t;
- /* keyboard platform device private data structure */
- typedef struct s3c_kbd_platform_data_s
- {
- s3c_kbd_info_t *keys;
- int nkeys;
- } s3c_kbd_platform_data_t;
- #endif /* ----- #ifndef _KBD_DRIVER_H_ ----- */
platform_device相關驅動文件 kbd_device.c:
- /*********************************************************************************
- * Copyright: (C) 2016 Guo Wenxue<[email protected]>
- * All rights reserved.
- *
- * Filename: kbd_device.c
- * Description: This file
- *
- * Version: 1.0.0(07/26/2016)
- * Author: Guo Wenxue <[email protected]>
- * ChangeLog: 1, Release initial version on "07/26/2016 05:01:25 PM"
- *
- ********************************************************************************/
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/platform_device.h>
- #include <linux/input.h>
- #include <mach/hardware.h>
- #include <asm/gpio.h>
- #include <asm/irq.h>
- #include <mach/regs-gpio.h>
- #include "kbd_driver.h"
- static s3c_kbd_info_t s3c_kbd_gpios[] = {
- [0] = {
- .code = KEY_1,
- .nIRQ = IRQ_EINT0,
- .gpio = S3C2410_GPF(0),
- .setting = S3C2410_GPF0_EINT0,
- },
- [1] = {
- .code = KEY_2,
- .nIRQ = IRQ_EINT2,
- .gpio = S3C2410_GPF(2),
- .setting = S3C2410_GPF2_EINT2,
- },
- [2] = {
- .code = KEY_3,
- .nIRQ = IRQ_EINT3,
- .gpio = S3C2410_GPF(3),
- .setting = S3C2410_GPF3_EINT3,
- },
- [3] = {
- .code = KEY_4,
- .nIRQ = IRQ_EINT4,
- .gpio = S3C2410_GPF(4),
- .setting = S3C2410_GPF4_EINT4,
- },
- };
- /* keyboard platform device private data */
- static s3c_kbd_platform_data_t s3c_kbd_data = {
- .keys = s3c_kbd_gpios,
- .nkeys = ARRAY_SIZE(s3c_kbd_gpios),
- };
- static void platform_kbd_release(struct device * dev)
- {
- return;
- }
- static struct platform_device s3c_keyboard_device = {
- .name = "s3c_kbd",
- .id = 1,
- .dev =
- {
- .platform_data = &s3c_kbd_data,
- .release = platform_kbd_release,
- },
- };
- static int __init s3c_keyboard_dev_init(void)
- {
- int rv;
- rv = platform_device_register(&s3c_keyboard_device);
- if(rv)
- {
- printk("S3C keyboard platform device register failure\n");
- return rv;
- }
- printk("S3C keyboard platform device register ok\n");
- return 0;
- }
- static void __exit s3c_keyboard_dev_exit(void)
- {
- printk("S3C keyboard device exit\n");
- platform_device_unregister(&s3c_keyboard_device);
- return ;
- }
- module_init(s3c_keyboard_dev_init);
- module_exit(s3c_keyboard_dev_exit);
- MODULE_DESCRIPTION("FL2440 board keyboard input driver platform_device");
- MODULE_AUTHOR("Guo Wenxue<[email protected]>");
- MODULE_LICENSE("GPL");
- MODULE_ALIAS("platform:FL2440 keyboard device");
platform_driver相關驅動文件 kbd_driver.c:
- /*********************************************************************************
- * Copyright: (C) 2016 Guo Wenxue<[email protected]>
- * All rights reserved.
- *
- * Filename: kbd_driver.c
- * Description: This file
- *
- * Version: 1.0.0(07/26/2016)
- * Author: Guo Wenxue <[email protected]>
- * ChangeLog: 1, Release initial version on "07/26/2016 05:01:25 PM"
- *
- ********************************************************************************/
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/platform_device.h>
- #include <linux/input.h>
- #include <linux/irq.h>
- #include <linux/interrupt.h>
- #include <mach/hardware.h>
- #include <asm/gpio.h>
- #include <asm/irq.h>
- #include <linux/slab.h>
- #include <mach/regs-gpio.h>
- #include "kbd_driver.h"
- /* 1HZ=100*jiffies 1*jiffies=10ms => 1HZ=100*10ms = 1s */
- #define CANCEL_DITHERING_DELAY (HZ/50) /* Remove button push down dithering timer delay 20ms */
- typedef struct s3c_kbd_s
- {
- struct timer_list *timers; /* every key get a cancel dithering timer */
- struct input_dev *input_dev;
- s3c_kbd_platform_data_t *pdata;
- } s3c_kbd_t; /*--- end of struct s3c_kbd_s ---*/
- s3c_kbd_t *s3c_kbd = NULL;
- static irqreturn_t s3c_kbd_intterupt(int irq, void *dev_id)
- {
- int i;
- int found = 0;
- struct platform_device *pdev = dev_id;
- s3c_kbd_t *s3c_kbd = NULL;
- s3c_kbd = platform_get_drvdata(pdev);
- for(i=0; i<s3c_kbd->pdata->nkeys; i++)
- {
- if(irq == s3c_kbd->pdata->keys[i].nIRQ)
- {
- found = 1;
- break;
- }
- }
- if(!found) /* An ERROR interrupt */
- return IRQ_NONE;
- mod_timer(&s3c_kbd->timers[i], jiffies+CANCEL_DITHERING_DELAY);
- return IRQ_HANDLED;
- }
- static void cancel_dithering_timer_handler(unsigned long data)
- {
- int which =(int)data;
- unsigned int pinval;
- pinval = s3c2410_gpio_getpin(s3c_kbd->pdata->keys[which].gpio);
- if( pinval )
- {
- //printk("s3c_kbd key[%d] code[%d] released\n", which, s3c_kbd->pdata->keys[which].code);
- input_event(s3c_kbd->input_dev, EV_KEY, s3c_kbd->pdata->keys[which].code, 0);
- }
- else
- {
- //printk("s3c_kbd key[%d] code[%d] pressed\n", which, s3c_kbd->pdata->keys[which].code);
- input_event(s3c_kbd->input_dev, EV_KEY, s3c_kbd->pdata->keys[which].code, 1);
- }
- input_sync(s3c_kbd->input_dev);
- }
- static int s3c_kbd_probe(struct platform_device *pdev)
- {
- int i = 0;
- int rv = -ENOMEM;
- struct input_dev *input_dev = NULL;
- s3c_kbd_platform_data_t *pdata = pdev->dev.platform_data;
- /* malloc s3c_kbd struct */
- s3c_kbd = kmalloc(sizeof(s3c_kbd_t), GFP_KERNEL);
- if( !s3c_kbd )
- {
- printk("error: s3c_kbd_probe kmalloc() for s3c_kbd failure\n");
- goto fail;
- }
- memset(s3c_kbd, 0, sizeof(s3c_kbd_t));
- /* malloc cancel dithering timer for every key */
- s3c_kbd->timers = (struct timer_list *) kmalloc(pdata->nkeys*sizeof(struct timer_list), GFP_KERNEL);
- if( !s3c_kbd->timers )
- {
- printk("error: s3c_kbd_probe kmalloc() for s3c_kbd timers failure\n");
- goto fail;
- }
- memset(s3c_kbd->timers, 0, pdata->nkeys*sizeof(struct timer_list));
- /* malloc input_dev for keyboard */
- input_dev=input_allocate_device();
- if( !input_dev )
- {
- printk("error: s3c_kbd_probe input_allocate_device() failure\n");
- goto fail;
- }
- /* setup input_dev */
- input_dev->name = pdev->name;
- input_dev->dev.parent = &pdev->dev;
- input_dev->id.bustype = BUS_HOST;
- input_dev->id.vendor = 0x0001;
- input_dev->id.product = 0x0001;
- input_dev->id.version = 0x0100;
- set_bit(EV_KEY,input_dev->evbit);
- set_bit(EV_REP,input_dev->evbit);
- /* Initialize all the keys and interrupt */
- for(i=0; i<pdata->nkeys; i++)
- {
- set_bit(pdata->keys[i].code, input_dev->keybit);
- s3c2410_gpio_cfgpin(pdata->keys[i].gpio, pdata->keys[i].setting);
- irq_set_irq_type(pdata->keys[i].nIRQ, IRQ_TYPE_EDGE_BOTH);
- rv = request_irq(pdata->keys[i].nIRQ, s3c_kbd_intterupt, IRQF_DISABLED, pdev->name, pdev);
- if( rv )
- {
- printk("error: request IRQ[%d] for key<%d> failure\n", pdata->keys[i].nIRQ, i);
- rv = -EBUSY;
- goto fail;
- }
- //printk("s3c_kbd request IRQ[%d] for key<%d> ok\n", pdata->keys[i].nIRQ, i);
- /* Initialize all the keys cancel dithering timer */
- setup_timer(&s3c_kbd->timers[i], cancel_dithering_timer_handler, i);
- }
- /* register input device */
- rv = input_register_device(input_dev);
- if( rv )
- {
- printk("error: s3c_kbd_probe input_register_device error!\n");
- goto fail;
- }
- /* set s3c_kbd as private data in pdev */
- s3c_kbd->input_dev = input_dev;
- s3c_kbd->pdata = pdata;
- platform_set_drvdata(pdev, s3c_kbd);
- printk("s3c_kbd_probe ok\n");
- return 0;
- fail:
- while(i--)
- {
- disable_irq(pdata->keys[i].nIRQ);
- free_irq(pdata->keys[i].nIRQ, pdev);
- del_timer( &s3c_kbd->timers[i] );
- }
- if(input_dev)
- {
- input_free_device(input_dev);
- }
- if(s3c_kbd && s3c_kbd->timers)
- {
- kfree(s3c_kbd->timers);
- }
- if(s3c_kbd)
- {
- kfree(s3c_kbd);
- }
- printk("s3c_kbd_probe failed\n");
- return -ENODEV;
- }
- static int s3c_kbd_remove(struct platform_device *pdev)
- {
- int i = 0;
- s3c_kbd_t *s3c_kbd = platform_get_drvdata(pdev);
- for(i=0; i<s3c_kbd->pdata->nkeys; i++)
- {
- del_timer( &s3c_kbd->timers[i] );
- disable_irq(s3c_kbd->pdata->keys[i].nIRQ);
- free_irq(s3c_kbd->pdata->keys[i].nIRQ, pdev);
- }
- input_unregister_device(s3c_kbd->input_dev);
- kfree(s3c_kbd->timers);
- kfree(s3c_kbd);
- printk("s3c_kbd_remove ok\n");
- return 0;
- }
- static struct platform_driver s3c_keyboard_driver = {
- .probe = s3c_kbd_probe,
- .remove = s3c_kbd_remove,
- .driver = {
- .name = "s3c_kbd",
- .owner = THIS_MODULE,
- },
- };
- static int __init s3c_keyboard_drv_init(void)
- {
- int rv;
- rv = platform_driver_register(&s3c_keyboard_driver);
- if(rv)
- {
- printk("s3c keyboard platform driver register failure\n");
- return rv;
- }
- printk("s3c keyboard platform driver register ok\n");
- return 0;
- }
- static void __exit s3c_keyboard_drv_exit(void)
- {
- printk("s3c keyboard driver exit\n");
- platform_driver_unregister(&s3c_keyboard_driver);
- return ;
- }
- module_init(s3c_keyboard_drv_init);
- module_exit(s3c_keyboard_drv_exit);
- MODULE_DESCRIPTION("FL2440 board keyboard input driver platform_driver");
- MODULE_AUTHOR("Guo Wenxue<[email protected]>");
- MODULE_LICENSE("GPL");
- MODULE_ALIAS("platform:FL2440 keyboard driver");
驅動測試文件event_button.c:
- /*********************************************************************************
- * Copyright: (C) 2012 Guo Wenxue<Email:[email protected] QQ:281143292>
- * All rights reserved.
- *
- * Filename: event_button.c
- * Description: This file used to test GPIO button driver builtin Linux kernel on ARM board
- *
- * Version: 1.0.0(07/13/2012~)
- * Author: Guo Wenxue <[email protected]>
- * ChangeLog: 1, Release initial version on "07/13/2012 02:46:18 PM"
- *
- ********************************************************************************/
- #include <stdio.h>
- #include <unistd.h>
- #include <errno.h>
- #include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <libgen.h>
- #include <getopt.h>
- #include <sys/types.h>
- #include <sys/ioctl.h>
- #include <linux/input.h>
- #include <linux/kd.h>
- #include <linux/keyboard.h>
- #if 0 /* Just for comment here, Reference to linux-3.3/include/linux/input.h */
- struct input_event
- {
- struct timeval time;
- __u16 type; /* 0x00:EV_SYN 0x01:EV_KEY 0x04:EV_MSC 0x11:EV_LED*/
- __u16 code; /* key value, which key */
- __s32 value; /* 1: Pressed 0:Not pressed 2:Always Pressed */
- };
- #endif
- #define TRUE 1
- #define FALSE 0
- #define EV_RELEASED 0
- #define EV_PRESSED 1
- #define EV_REPEAT 2
- #define BUTTON_CNT 5
- #define MODE_POLL 0x01
- #define MODE_NORMAL 0x02
- void usage(char *name);
- void display_button_event(struct input_event *ev, int cnt);
- int main(int argc, char **argv)
- {
- char *kbd_dev = NULL;
- char kbd_name[256] = "Unknown";
- int kbd_fd = -1;
- int rv, opt;
- int mode = MODE_NORMAL;
- int size = sizeof (struct input_event);
- struct input_event ev[BUTTON_CNT];
- struct option long_options[] = {
- {"device", required_argument, NULL, 'd'},
- {"poll", no_argument, NULL, 'p'},
- {"help", no_argument, NULL, 'h'},
- {NULL, 0, NULL, 0}
- };
- while ((opt = getopt_long(argc, argv, "d:ph", long_options, NULL)) != -1)
- {
- switch (opt)
- {
- case 'd':
- kbd_dev = optarg;
- break;
- case 'p':
- mode = MODE_POLL;
- break;
- case 'h':
- usage(argv[0]);
- return 0;
- default:
- break;
- }
- }
- if(NULL == kbd_dev)
- {
- usage(argv[0]);
- return -1;
- }
- if ((getuid ()) != 0)
- printf ("You are not root! This may not work...\n");
- if ((kbd_fd = open(kbd_dev, O_RDONLY)) < 0)
- {
- printf("Open %s failure: %s", kbd_dev, strerror(errno));
- return -1;
- }
- ioctl (kbd_fd, EVIOCGNAME (sizeof (kbd_name)), kbd_name);
- printf ("Monitor input device %s (%s) event with %s mode:\n", kbd_dev, kbd_name, MODE_POLL==mode?"poll":"infilit loop");
- #if 0 /* Not implement in the Linux GPIO button driver */
- unsigned char key_b[BUTTON_CNT/8 + 1];
- memset(key_b, 0, sizeof(key_b));
- if(ioctl(kbd_fd, EVIOCGKEY(sizeof(key_b)), key_b) < 0)
- {
- printf("EVIOCGKEY ioctl get error: %s\n", strerror(errno));
- return -1;
- }
- #endif
- #if 0 /* Not implement in the Linux GPIO button driver */
- /* rep[0]è?¨?¤???¨??‰é”?é???¤??????°????‰? delay????—?é—?,rep[1]è?¨?¤???‰é”?é???¤??????°????—?é—?é—?é?”?€? */
- int rep[2] ={2500, 1000} ;
- if(ioctl(kbd_fd, EVIOCSREP, rep) < 0)
- {
- printf("EVIOCSREP ioctl get error: %s\n", strerror(errno));
- return -1;
- }
- if(ioctl(kbd_fd, EVIOCGREP, rep) < 0)
- {
- printf("EVIOCGKEY ioctl get error: %s\n", strerror(errno));
- return -1;
- }
- else
- {
- printf("repeate speed: [0]= %d, [1] = %d/n", rep[0], rep[1]);
- }
- #endif
- while (1)
- {
- if(MODE_POLL==mode)
- {
- fd_set rds;
- FD_ZERO(&rds);
- FD_SET(kbd_fd, &rds);
- rv = select(kbd_fd + 1, &rds, NULL, NULL, NULL);
- if (rv < 0)
- {
- printf("Select() system call failure: %s\n", strerror(errno));
- goto CleanUp;
- }
- else if (FD_ISSET(kbd_fd, &rds))
- {
- if ((rv = read (kbd_fd, ev, size*BUTTON_CNT )) < size)
- {
- printf("Reading data from kbd_fd failure: %s\n", strerror(errno));
- break;
- }
- else
- {
- display_button_event(ev, rv/size);
- }
- }
- }
- else
- {
- if ((rv = read (kbd_fd, ev, size*BUTTON_CNT )) < size)
- {
- printf("Reading data from kbd_fd failure: %s\n", strerror(errno));
- break;
- }
- else
- {
- display_button_event(ev, rv/size);
- }
- }
- }
- CleanUp:
- close(kbd_fd);
- return 0;
- }
- void usage(char *name)
- {
- char *progname = NULL;
- char *ptr = NULL;
- ptr = strdup(name);
- progname = basename(ptr);
- printf("Usage: %s [-p] -d <device>\n", progname);
- printf(" -d[device ] button device name\n");
- printf(" -p[poll ] Use poll mode, or default use infinit loop.\n");
- printf(" -h[help ] Display this help information\n");
- free(ptr);
- return;
- }
- void display_button_event(struct input_event *ev, int cnt)
- {
- int i;
- struct timeval pressed_time, duration_time;
- for(i=0; i<cnt; i++)
- {
- //printf("type:%d code:%d value:%d\n", ev[i].type, ev[i].code, ev[i].value);
- if(EV_KEY==ev[i].type && EV_PRESSED==ev[i].value)
- {
- if(BTN_1 == ev[i].code)
- {
- pressed_time = ev[i].time;
- printf("S1 button key[%d] pressed time: %ld.%ld\n", ev[i].code, pressed_time.tv_sec, pressed_time.tv_usec);
- }
- else if(BTN_2 == ev[i].code)
- {
- pressed_time = ev[i].time;
- printf("S2 button key[%d] pressed time: %ld.%ld\n", ev[i].code, pressed_time.tv_sec, pressed_time.tv_usec);
- }
- else if(BTN_3 == ev[i].code)
- {
- pressed_time = ev[i].time;
- printf("S3 button key[%d] pressed time: %ld.%ld\n", ev[i].code, pressed_time.tv_sec, pressed_time.tv_usec);
- }
- else if(BTN_4 == ev[i].code)
- {
- pressed_time = ev[i].time;
- printf("S4 button key[%d] pressed time: %ld.%ld\n", ev[i].code, pressed_time.tv_sec, pressed_time.tv_usec);
- }
- else
- {
- pressed_time = ev[i].time;
- printf("button key[%d] pressed time: %ld.%ld\n", ev[i].code, pressed_time.tv_sec, pressed_time.tv_usec);
- }
- }
- if(EV_KEY==ev[i].type && EV_RELEASED==ev[i].value)
- {
- if(BTN_1 == ev[i].code)
- {
- timersub(&ev[i].time, &pressed_time, &duration_time);
- printf("S1 button key[%d] released time: %ld.%ld\n", ev[i].code, ev[i].time.tv_sec, ev[i].time.tv_usec);
- printf("S1 button key[%d] duration time: %ld.%ld\n", ev[i].code, duration_time.tv_sec, duration_time.tv_usec);
- }
- else if(BTN_2 == ev[i].code)
- {
- timersub(&ev[i].time, &pressed_time, &duration_time);
- printf("S2 button key[%d] released time: %ld.%ld\n", ev[i].code, ev[i].time.tv_sec, ev[i].time.tv_usec);
- printf("S2 button key[%d] duration time: %ld.%ld\n", ev[i].code, duration_time.tv_sec, duration_time.tv_usec);
- }
- else if(BTN_3 == ev[i].code)
- {
- timersub(&ev[i].time, &pressed_time, &duration_time);
- printf("S3 button key[%d] released time: %ld.%ld\n", ev[i].code, ev[i].time.tv_sec, ev[i].time.tv_usec);
- printf("S3 button key[%d] duration time: %ld.%ld\n", ev[i].code, duration_time.tv_sec, duration_time.tv_usec);
- }
- else if(BTN_4 == ev[i].code)
- {
- timersub(&ev[i].time, &pressed_time, &duration_time);
- printf("S4 button key[%d] released time: %ld.%ld\n", ev[i].code, ev[i].time.tv_sec, ev[i].time.tv_usec);
- printf("S4 button key[%d] duration time: %ld.%ld\n", ev[i].code, duration_time.tv_sec, duration_time.tv_usec);
- }
- else
- {
- timersub(&ev[i].time, &pressed_time, &duration_time);
- printf("button key[%d] released time: %ld.%ld\n", ev[i].code, ev[i].time.tv_sec, ev[i].time.tv_usec);
- printf("button key[%d] duration time: %ld.%ld\n", ev[i].code, duration_time.tv_sec, duration_time.tv_usec);
- }
- }
- } /* for(i=0; i<cnt; i++) */
- }
驅動和測試程序編譯Makefile文件
- TEST_APP=event_button
- KERNEL_VER = linux-3.0
- LINUX_SRC ?= /home/leiyuxing/fl2440/kernel/$(KERNEL_VER)
- CROSS_COMPILE=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-
- PWD := $(shell pwd)
- obj-m += kbd_device.o
- obj-m += kbd_driver.o
- modules:
- @make -C $(LINUX_SRC) M=$(PWD) modules
- @make clear
- @chmod a+x *.ko && cp *.ko /tftp
- @make testapp
- clear:
- @rm -f *.o *.cmd *.mod.c
- @rm -rf *~ core .depend .tmp_versions Module.symvers modules.order -f
- @rm -f .*ko.cmd .*.o.cmd .*.o.d
- clean: clear
- @rm -f *.ko ${TEST_APP}
- testapp:
- ${CROSS_COMPILE}gcc ${TEST_APP}.c -o ${TEST_APP}
[hongfuhao@centos6 input_kbd]$ make
make[1]: Entering directory `/home/leiyuxing/fl2440/kernel/linux-3.0'
CC [M] /home/leiyuxing/fl2440/kernel/linux-3.0/input_dev/input_kbd/kbd_device.o
CC [M] /home/leiyuxing/fl2440/kernel/linux-3.0/input_dev/input_kbd/kbd_driver.o
Building modules, stage 2.
MODPOST 2 modules
CC /home/leiyuxing/fl2440/kernel/linux-3.0/input_dev/input_kbd/kbd_device.mod.o
LD [M] /home/leiyuxing/fl2440/kernel/linux-3.0/input_dev/input_kbd/kbd_device.ko
CC /home/leiyuxing/fl2440/kernel/linux-3.0/input_dev/input_kbd/kbd_driver.mod.o
LD [M] /home/leiyuxing/fl2440/kernel/linux-3.0/input_dev/input_kbd/kbd_driver.ko
make[1]: Leaving directory `/home/leiyuxing/fl2440/kernel/linux-3.0'
make[1]: Entering directory `/home/leiyuxing/fl2440/kernel/linux-3.0/input_dev/input_kbd'
make[1]: Leaving directory `/home/leiyuxing/fl2440/kernel/linux-3.0/input_dev/input_kbd'
[hongfuhao@centos6 input_kbd]$ ls
kbd_device.c kbd_driver.c kbd_driver.ko
event_button.c kbd_device.ko kbd_driver.h Makefile
[hongfuhao@centos6input_kbd]$/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc
event_button.c
[hongfuhao@centos6 input_kbd]$ ls
a.out kbd_device.c kbd_driver.c kbd_driver.ko
event_button.c kbd_device.ko kbd_driver.h Makefile
在開發板上的操作:
下載設備驅動:
>: tftp -gr kbd_device.ko 192.168.1.2
kbd_device.ko 100% |*******************************| 3358 0:00:00 ETA
>: tftp -gr kbd_driver.ko 192.168.1.2
kbd_driver.ko 100% |*******************************| 5996 0:00:00 ETA
運行測試:
>: insmod kbd_device.ko
S3C keyboard platform device register ok
>: insmod kbd_driver.ko
input: s3c_kbd as /devices/platform/s3c_kbd.1/input/input0
s3c_kbd_probe ok
s3c keyboard platform driver register ok
使用測試程序a.out分別測試4個按鍵:
>: ./a.out
Usage: a.out [-p] -d <device>
-d[device ] button device name
-p[poll ] Use poll mode, or default use infinit loop.
-h[help ] Display this help information
>: ./a.out -p -d /dev/event0
Monitor input device /dev/event0 (s3c_kbd) event with poll mode:
Monitor input device /dev/event0 (s3c_kbd) event with poll mode:
button key[2] pressed time: 483.320105
button key[2] released time: 483.500073
button key[2] duration time: 1094956827.500065
button key[3] pressed time: 485.265110
button key[3] released time: 485.520131
button key[3] duration time: 1094956829.520123
button key[4] pressed time: 487.815109
button key[4] released time: 488.60077
button key[4] duration time: 1094956832.60069
測試發現我的按鍵4壞了故無法顯示。