6. Driver supports multi-key operation

Source: Internet
Author: User

Multi-key driver optimization

Optimized code that supports two keys for supported code: DUOKEY.C:

#include <linux/module.h>/* for module specific items */

#include <linux/fs.h>/* for file operations */

#include <linux/ioport.h>/* for io-port access * *

#include <linux/io.h>/* for inb/outb/... * *

#include <linux/init.h>

#include <linux/miscdevice.h>

#include <linux/interrupt.h>

#include <linux/slab.h>

#define GPNCON 0x7f008830

#define GPNDAT 0x7f008834

struct Work_struct *work1;

struct Timer_list key_timer;//defining timers

unsigned int *gpio_data;

void Work1_func (struct work_struct *work)

{

Start Timer 100 ms timeout =hz/10,hz=1 seconds. Jiffies is the current time of the system

Mod_timer (&KEY_TIMER,JIFFIES+HZ/10);

}

void Key_timer_func (unsigned Long data)

{///Timer timeout function needs to be modified, need to determine which key is timed out

unsigned int key_val;

When you time out, you need to read the data

KEY_VAL=READW (gpio_data) &0x01;//reads the value of a key EINT0.

When he was pressed, it was low, it was pressed. is a valid key.

if (0==key_val)//Real Press

PRINTK ("<0> key1 down!\n");

KEY_VAL=READW (gpio_data) &0x02;//reads the value of a key EINT1.

When he was pressed, it was low, it was pressed. is a valid key.

if (0==key_val)//Real Press

PRINTK ("<0> key2 down!\n");

}

irqreturn_t key_int (int irq, void *dev_id)

{

1. Detect if a key interrupt has occurred

2. Clear the key interrupt that has occurred

The previous hardware-related work must be performed in the interrupt

The following is hardware-independent work, which we refer to as a work1_func function outside of the interrupt to handle.

3. Print Key values

Schedule_work (WORK1);

return 0;

}

void Key_hw_init ()

{

unsigned int *gpio_config;

unsigned short data;

Gpio_config = Ioremap (gpncon,4);

data = READW (Gpio_config);

Data &= ~0b1111;//Add a button

Data |= 0b1010;

Writew (Data,gpio_config);

Gpio_data = Ioremap (gpndat,4);

}

int Key_open (struct inode *node, struct file *filp)

{

return 0;

}

struct File_operations key_fops =

{

. open = Key_open,

};

struct Miscdevice Key_miscdevice =

{

. minor = 200,

. Name = "Ok6410key",

. FoPs = &key_fops,

};

static int Key_init ()

{

Misc_register (&key_miscdevice);

Registering an interrupt handler

REQUEST_IRQ (irq_eint (0), Key_int, irqf_trigger_falling, "Ok6410key", 0);

Added support for one key

REQUEST_IRQ (Irq_eint (1), Key_int, irqf_trigger_falling, "Ok6410key", 0);

Hardware initialization

Key_hw_init ();//The corresponding bit is set

2. Create a job

Work1 = kmalloc (sizeof (struct work_struct), gfp_kernel);

Init_work (Work1, Work1_func);

Timer initialization

Init_timer (&key_timer);

Key_timer.function=key_timer_func;

Register Timer

Add_timer (&key_timer);

return 0;

}

static void Key_exit ()

{

Misc_deregister (&key_miscdevice);

}

Module_init (Key_init);

Module_exit (Key_exit);

/* Optimization: More than one interrupt, Gpio is also a multi-key initialization, interrupt generation to determine which key generated by the interrupt. */

Result of Make:

Generate. ko drive files, copy to board to run. Press 1 and the 2nd number key will output the appropriate information.

The first is to create the corresponding character device file.

Mknod/dev/6410key C 10 200

Key application Design

Application code KEY_APP.C: The main function is to read out the values of the pressed key:

#include <stdio.h>

#include <stdlib.h>

int main ()

{

int FD;

int key_num;

1. Turn on the device

Fd=open ("/dev/6410key", 0);

if (fd<0)

printf ("Open device fail!\n");

2. Read the device

Read (fd,&key_num,4);

printf ("Key is%d\n", key_num);

3. Turn off the device

Close (FD);

return 0;

}

Compilation: Arm-linux-gcc-static Key_app.c-o Key_app

This is our key test application.

In fact, it's not possible to test our previous drivers: because we have only the open function in our previous file_operations structure. Read is not supported.

struct File_operations key_ops =

{

. open = Key_open,

};

These functions do not have to learn to go to the kernel code to find prototypes.

Finished, make, error: implicit declaration of function ' Copy_to_user ' without his head file, header file is linux/eaccess.h. Final make success:

Improved DUOKEY.C:

#include <linux/module.h>/* for module specific items */

#include <linux/fs.h>/* for file operations */

#include <linux/ioport.h>/* for io-port access * *

#include <linux/io.h>/* for inb/outb/... * *

#include <linux/init.h>

#include <linux/miscdevice.h>

#include <linux/interrupt.h>

#include <linux/slab.h>

#include <linux/uaccess.h>

#define GPNCON 0x7f008830

#define GPNDAT 0x7f008834

struct Work_struct *work1;

struct Timer_list key_timer;//defining timers

unsigned int *gpio_data;

Global variables

unsigned int key_num;

Read button

ssize_t key_read (struct file *filp, char __user *buf, size_t size, loff_t *pos)

{

Return the kernel to the user

Copy_to_user (buf,&key_num,4);

return 4;

}

void Work1_func (struct work_struct *work)

{

Start Timer 100 ms timeout =hz/10,hz=1 seconds. Jiffies is the current time of the system

Mod_timer (&KEY_TIMER,JIFFIES+HZ/10);

}

void Key_timer_func (unsigned Long data)

{///Timer timeout function needs to be modified, need to determine which key is timed out

unsigned int key_val;

When you time out, you need to read the data

KEY_VAL=READW (gpio_data) &0x01;//reads the value of a key EINT0.

When he was pressed, it was low, it was pressed. is a valid key.

if (0==key_val)//Real Press

key_num=1;//Read Key number

KEY_VAL=READW (gpio_data) &0x02;//reads the value of a key EINT1.

When he was pressed, it was low, it was pressed. is a valid key.

if (0==key_val)//Real Press

key_num=2;

}

irqreturn_t key_int (int irq, void *dev_id)

{

1. Detect if a key interrupt has occurred

2. Clear the key interrupt that has occurred

The previous hardware-related work must be performed in the interrupt

The following is hardware-independent work, which we refer to as a work1_func function outside of the interrupt to handle.

3. Print Key values

Schedule_work (WORK1);

return 0;

}

void Key_hw_init ()

{

unsigned int *gpio_config;

unsigned short data;

Gpio_config = Ioremap (gpncon,4);

data = READW (Gpio_config);

Data &= ~0b1111;//Add a button

Data |= 0b1010;

Writew (Data,gpio_config);

Gpio_data = Ioremap (gpndat,4);

}

int Key_open (struct inode *node, struct file *filp)

{

return 0;

}

struct File_operations key_fops =

{

. open = Key_open,

. Read = key_read,//increased read operations

};

struct Miscdevice Key_miscdevice =

{

. minor = 200,

. Name = "6410key",

. FoPs = &key_fops,

};

static int Key_init ()

{

Misc_register (&key_miscdevice);

Registering an interrupt handler

REQUEST_IRQ (irq_eint (0), Key_int, irqf_trigger_falling, "6410key", 0);

Added support for one key

REQUEST_IRQ (Irq_eint (1), Key_int, irqf_trigger_falling, "6410key", 0);

Hardware initialization

Key_hw_init ();//The corresponding bit is set

2. Create a job

Work1 = kmalloc (sizeof (struct work_struct), gfp_kernel);

Init_work (Work1, Work1_func);

Timer initialization

Init_timer (&key_timer);

Key_timer.function=key_timer_func;

Register Timer

Add_timer (&key_timer);

return 0;

}

static void Key_exit ()

{

Misc_deregister (&key_miscdevice);

}

Module_init (Key_init);

Module_exit (Key_exit);

/* Optimization: More than one interrupt, Gpio is also a multi-key initialization, interrupt generation to determine which key generated by the interrupt. */

The next step is to test the Development Board: first, copy the generated key driver files to the Development Board: install.

Next is the creation of the character device file:

Mknod/dev/6410key C 10 200

6410key is the device file that we use, C is the symbol of the character device file, 10 is the fixed main device number of the hybrid device, and 200 is the secondary device number we define in the character driver.

After you have created it, run the application Key_app:

[Email protected]]#./key_app

Key is 0

6. Driver supports multi-key operation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.