linuxfl2440开发板驱动开发之按键驱动

来源:互联网 发布:java获取泛型t的class 编辑:程序博客网 时间:2024/06/02 01:22

linuxfl2440开发板驱动开发按键驱动

[luxibao@centos ~]$ mkdir input_kbd

[luxibao@centos input_kbd]$ ls

event_button.c  kbd_device.c  kbd_driver.c  kbd_driver.h  Makefile

驱动相关头文件kbd_driver.h:

 

/********************************************************************************

 *      Copyright:  (C) 2016 Guo Wenxue<guowenxue@aliyun.com>

 *                  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 <guowenxue@aliyun.com>

 *      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<guowenxue@aliyun.com>

 *                  All rights reserved.

 *

 *       Filename:  kbd_device.c

 *    Description:  This file

 *

 *        Version:  1.0.0(07/26/2016)

 *         Author:  Guo Wenxue <guowenxue@aliyun.com>

 *      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<guowenxue@gmail.com>");

MODULE_LICENSE("GPL");

MODULE_ALIAS("platform:FL2440 keyboard device");

 

platform_driver相关驱动文件 kbd_driver.c:


/*********************************************************************************

 *      Copyright:  (C) 2016 Guo Wenxue<guowenxue@aliyun.com>

 *                  All rights reserved.

 *

 *       Filename:  kbd_driver.c

 *    Description:  This file

 *

 *        Version:  1.0.0(07/26/2016)

 *         Author:  Guo Wenxue <guowenxue@aliyun.com>

 *      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<guowenxue@gmail.com>");

MODULE_LICENSE("GPL");

MODULE_ALIAS("platform:FL2440 keyboard driver");

 

驱动测试文件event_button.c:

/*********************************************************************************

 *      Copyright:  (C) 2012 Guo Wenxue<Email:guowenxue@gmail.com 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 <guowenxue@gmail.com>

 *      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/luxibao/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

        @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}

 

[luxibao@centos input_kbd]$ make

make[1]: Entering directory `/home/luxibao/fl2440/kernel/linux-3.0'

  CC [M]  /home/luxibao/input_kbd/kbd_device.o

  CC [M]  /home/luxibao/input_kbd/kbd_driver.o

  Building modules, stage 2.

  MODPOST 2 modules

  CC      /home/luxibao/input_kbd/kbd_device.mod.o

  LD [M]  /home/luxibao/input_kbd/kbd_device.ko

  CC      /home/luxibao/input_kbd/kbd_driver.mod.o

  LD [M]  /home/luxibao/input_kbd/kbd_driver.ko

make[1]: Leaving directory `/home/luxibao/fl2440/kernel/linux-3.0'

make[1]: Entering directory `/home/luxibao/input_kbd'

make[1]: Leaving directory `/home/luxibao/input_kbd'

make[1]: Entering directory `/home/luxibao/input_kbd'

/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc event_button.c -o event_button

make[1]: Leaving directory `/home/luxibao/input_kbd'

[luxibao@centos input_kbd]$ ls

event_button    kbd_device.c   kbd_driver.c  kbd_driver.ko

event_button.c  kbd_device.ko  kbd_driver.h  Makefile

[luxibao@centos input_kbd]$ rm -rf event_button

[luxibao@centos input_kbd]$ ls

event_button.c  kbd_device.ko  kbd_driver.h   Makefile

kbd_device.c    kbd_driver.c   kbd_driver.ko

[luxibao@centos input_kbd]$ /opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc event_button.c

[luxibao@centos 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% |*******************************|  3358   0:00:00 ETA

>: tftp -gr a.out 192.168.1.2

a.out                100% |*******************************| 12829   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

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:

button key[2]  pressed time: 919.885106

button key[2] released time: 920.65095

button key[2] duration time: 1092937936.65087

button key[3]  pressed time: 921.5096

button key[3] released time: 921.190084

button key[3] duration time: 1092937937.190076

button key[4]  pressed time: 922.330099

button key[4] released time: 922.485089

button key[4] duration time: 1092937938.485081

 

 

遇到的问题

问题1:


解决:删除/tftp   用sz命令就行

问题2:驱动加载不了第二个



解决:


 

交叉编译器编译event_button.c生成的event_button,删除后进行后面操作


重新生成的.ko和a.out就可以正常加载和运行了

0 0