MINI2440 key input subsystem driver and test code analysis

Publisher:翩翩轻舞Latest update time:2022-11-12 Source: csdnKeywords:MINI2440 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Key input subsystem driver:


#include

#include

#include

#include

#include

#include /* for -EBUSY */

#include /* for request_region */

#include /* for loops_per_jiffy */

#include    /* for inb_p, outb_p, inb, outb, etc. */

#include /* for get_user, etc. */

#include   /* for wait_queue */

#include   /* for __init, module_{init,exit} */

#include   /* for POLLIN, etc. */

#include

#include

#include

#include

#include

#include


struct pin_desc {

    int     irq;

    int     pin;

    int     pin_state;

    char    *name;

    int     key_val;

    int     pin_val;

};


static struct pin_desc buttons_pin[] = {

    {IRQ_EINT8,    S3C2410_GPG(0),   S3C2410_GPG0_EINT8,    "KEY1",   BTN_0},

    {IRQ_EINT11,   S3C2410_GPG(3),   S3C2410_GPG3_EINT11,   "KEY3",   BTN_1},

    {IRQ_EINT13,   S3C2410_GPG(5),   S3C2410_GPG5_EINT13,   "KEY2",   BTN_2},

    {IRQ_EINT14,   S3C2410_GPG(6),   S3C2410_GPG6_EINT14,   "KEY4",   BTN_3},

    {IRQ_EINT15,   S3C2410_GPG(7),   S3C2410_GPG7_EINT15,   "KEY5",   BTN_4},

    {IRQ_EINT19,   S3C2410_GPG(11),  S3C2410_GPG11_EINT19,  "KEY6",   BTN_5},

};


static struct input_dev *buttons_input;


static irqreturn_t buttons_interrupt(int irq,void *dev_id)

{

    struct pin_desc *pin_desc = (struct pin_desc *)dev_id;

    int val;

    val = s3c2410_gpio_getpin(pin_desc->pin);


    input_event(buttons_input,EV_KEY,pin_desc->key_val, !val);

    input_sync(buttons_input);


    return IRQ_HANDLED;

}


static int __init buttons_init(void)

{

    int error;

    int i;


    buttons_input = input_allocate_device();

    if(!buttons_input)

        return  -ENOMEM;


#if 0

    buttons_input->evbit[0] = BIT(EV_KEY);


    buttons_input->keybit[BITS_TO_LONGS(KEY_L)] = BIT(KEY_L);

    buttons_input->keybit[BITS_TO_LONGS(KEY_S)] = BIT(KEY_S);

    buttons_input->keybit[BITS_TO_LONGS(KEY_ENTER)] = BIT(KEY_ENTER);

    buttons_input->keybit[BITS_TO_LONGS(KEY_LEFTSHIFT)] = BIT(KEY_LEFTSHIFT);

#endif


    set_bit(EV_KEY,buttons_input->evbit);


    for(i = 0;i    {

        set_bit(buttons_pin[i].key_val,buttons_input->keybit);

    }


    error = input_register_device(buttons_input);

    if(error){

        input_free_device(buttons_input);

        return -1;

    }

   

    for(i = 0;i    {

       s3c2410_gpio_cfgpin(buttons_pin[i].pin,buttons_pin[i].pin_state);

       request_irq(buttons_pin[i].irq,buttons_interrupt, IRQF_SHARED | IRQF_TRIGGER_RISING

               | IRQF_TRIGGER_FALLING,buttons_pin[i].name,(void *)&buttons_pin[i]);

    }

   

    return 0;


}

static void __exit buttons_exit(void)

{

    int i;

   

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

    {

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

    }


    input_unregister_device(buttons_input);

    input_free_device(buttons_input);

}


module_init(buttons_init);

module_exit(buttons_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("RopenYuan");

 


Key input subsystem test program


 


#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include


int main(void)

{

 int buttons_fd;

 int key_value,i=0,count;


 struct input_event ev_key;

 buttons_fd = open("/dev/input/event0", O_RDWR);

 if (buttons_fd < 0) {

  perror("open device buttons");

  exit(1);

 }


 for (;;) {

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

  for(i=0; i<(int)count/sizeof(struct input_event); i++)

   if(EV_KEY==ev_key.type)

    printf("type:%d,code:%d,value:%dn", ev_key.type,ev_key.code,ev_key.value);


   if(EV_SYN==ev_key.type)

    printf("syn eventnn");


    }


 close(buttons_fd);

 return 0;

}


MAKEFILE


ifneq ($(KERNELRELEASE),)


obj-m := buttons.o


else

  

#KDIR := /home/yuanpengjun/home/linuxeditorkernelfilesystem/kernal/linux-2.6.32/linux-2.6.32.2/

KDIR := /home/yuanpengjun/mini2440/kernel/linux-2.6.32.2/

all:

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

  make -C $(KDIR) M=$(PWD) modules

  /home/yuanpengjun/mini2440/editor/4.4.3/bin/arm-none-linux-gnueabi-gcc -o button button_app.c


clean:

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


endif


The above driver code does not include fault tolerance processing, just to verify whether it can run successfully.


Input appears when loading the module: Unspecified device as /devices/virtual/input/input0  


The reason is that the member name in struct input_dev is not set in the driver. If there is a member named XXXX->name = "yyyyyyy", the following situation will occur after the driver module is loaded:


input: yyyyyyy as /devices/virtual/input/input0  


When uninstalling the module, rmmod: chdir(2.6.32.2): No such file or directory appears, and the module cannot be uninstalled from the system;


The reason is: When the current kernel module is inserted and uninstalled, it will be transferred to the directory /lib/modules/kernel version number/, in the format of /lib/modules/2.6.32.2/. In this case, the module will no longer appear. Unable to uninstall;


Keywords:MINI2440 Reference address:MINI2440 key input subsystem driver and test code analysis

Previous article:mini2440 touch screen driver----implementation method of non-input subsystem
Next article:s3c2410 touch screen driver (2.6 kernel) analysis - interrupt the lower half

Recommended ReadingLatest update time:2024-11-16 12:24

Introduction to command parameters for generating uImage for mini2440
mkimage -n 'mini2440' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d  arch/arm/boot/zImage  uImage Parameter explanation:     -n 'mini2440' //Specify the original kernel image name, that is, use mini2440 to generate uImage     -A arm //Specify the chip architecture to run the image as ARM kernel  
[Microcontroller]
Mini2440----Building the debugging and downloading environment under Keil for ARM
Off-topic: Recommended compilation environment selection For those who are new to ARM bare metal programming, I would like to remind you about the choice of compilation environment. Currently, there are three mainstream ones: ADS+AXD, KEIL FOR ARM, and IAR FOR ARM. I started using ADS+AXD for learning because it comes
[Microcontroller]
mini2440 LED Driver
myled.c #include linux/module.h #include linux/kernel.h #include linux/fs.h #include linux/cdev.h #include asm/uaccess.h #include linux/device.h #include mach/hardware.h #include mach/gpio-nrs.h #include mach/regs-gpio.h /*#include "gpio-nrs.h"*/ //add tsuibin #incl
[Microcontroller]
U-boot-2014.04 ported to MINI2440 (4) Detailed analysis of the first boot phase start.S, etc.
The startup phase of u-boot is divided into two parts. The first part is mainly the start.S file. The post analyzes the meaning of each line of code as much as possible, and checks a lot of manuals. The purpose of analysis is also for learning. Writing a blog is also to leave something for my own learning. There are a
[Microcontroller]
U-boot-2014.04 ported to MINI2440 (4) Detailed analysis of the first boot phase start.S, etc.
DMA test under ads for mini2440
I found a dma ads project on the Internet and integrated its dma function into the original ads project TQ2440_Test. Replace the original TQ2440_Test main.c with the following main.c http://download.csdn.net/detail/songqqnew/3636198 The reason why we introduce DMA is that it is so important for performance! Only by
[Microcontroller]
Using u-boot_2016_01 to start mini2440 (II) uboot memory distribution
The distribution of startup memory is mainly divided in board_init_f: According to my code, the distribution is as follows: Code log: U-Boot 2016.01-g3401853-dirty (Apr 04 2016 - 08:06:26 -0400) U-Boot code: 33A00000 - 33A7BEF4 BSS: - 33ACAAE4 CPUID: 32440001 FCLK: 405.600 MHz HCLK: 101.400 MHz PCLK: 50.700 M
[Microcontroller]
Using u-boot_2016_01 to start mini2440 (II) uboot memory distribution
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号