Linux Embedded Drive Learning Path (15) key Driver-timer stabilization

Source: Internet
Author: User
Tags mutex

In the previous timer driver, we found that in the continuous press of the button, it should normally be one time to press the corresponding release. The program sometimes shows that it is two times pressed and released at once. This problem is because when pressed, because it is a mechanical button, so the voltage signal will produce a certain fluctuation, will let the program two interrupts, how to solve this problem?

We can wait for a period of time after an interruption to determine whether the button has been pressed, if it has been pressed, this time is valid, otherwise invalid. The timer is used here.

The operation functions commonly used by timers are:

   init_timer ( &timer);   // timer initialization    timer.data=10 ;         //  set timeout handler parameters  &N bsp; timer.expires=jiffies+ (10  *hz);   //  set timeout jiffies value of 10s       timer.function=timer_func;  //  Set the timeout handler    add_timer (&timer);       //  add timer to kernel    del_timer ( &timer);   //  Delete timer should delete the last call before each call  

Driver Code:

#include <linux/sched.h>#include<linux/signal.h>#include<linux/spinlock.h>#include<linux/errno.h>#include<linux/random.h>#include<linux/poll.h>#include<linux/init.h>#include<linux/slab.h>#include<linux/module.h>#include<linux/wait.h>#include<linux/mutex.h>#include<linux/io.h>#include<asm/irq.h>#include<linux/irq.h>#include<linux/fs.h>#include<asm/arch/regs-gpio.h>#include<linux/interrupt.h>#include<linux/poll.h>Static struct class*key_class;//Create ClassStatic structClass_device *key_class_devs;//Create a device for a classStatic structtimer_list Keys_timer;structpin_desc{unsignedintpin; unsignedintKey_val;};structPin_desc pins_desc[4] ={{s3c2410_gpf0,0x01}, {S3C2410_GPF2,0X02}, {s3c2410_gpg3,0X03}, {s3c2410_gpg11,0x04},};structPIN_DESC *Pin_timer; //Hold down the press key in the key interrupt unsignedCharkeyvals=0;Static volatile intEv_press =0;StaticDeclare_wait_queue_head (BUTTON_WAITQ);Static structFasync_struct *Key_async_queue;StaticDeclare_mutex (CANopen);//Defining Mutex LocksStaticIrqreturn_t KEYS_IRQ (intIrqvoid*dev_id) {Pin_timer= (structPIN_DESC *) dev_id; Mod_timer (&keys_timer, jiffies+hz/ - ); //jiffies is a global variable that accumulates every 10ms, where 10ms produces an interrupt returnirq_handled;}intKey_open (structInode *inode,structFile *FP) {    /*get the Semaphore*/    if(Fp->f_flags &O_nonblock) {        if(Down_trylock (&CANopen)) return-Ebusy; }    Else{Down (&CANopen); } REQUEST_IRQ (Irq_eint0, KEYS_IRQ, Irqt_bothedge,"Key2", &pins_desc[0]); REQUEST_IRQ (Irq_eint2, KEYS_IRQ, Irqt_bothedge,"Key3", &pins_desc[1]); REQUEST_IRQ (irq_eint11, KEYS_IRQ, Irqt_bothedge,"Key4", &pins_desc[2]); REQUEST_IRQ (irq_eint19, KEYS_IRQ, Irqt_bothedge,"Key5", &pins_desc[3]); return 0;} ssize_t Key_read (structFile *FP,Char__user *buff, size_t count, loff_t *OFFP) {    if(Fp->f_flags &O_nonblock) {        if(!ev_press)return-Eagain; }    Else{wait_event_interruptible (button_waitq,ev_press); }    if(Count! =1)    {        return-EINVAL; } copy_to_user (Buff,&keyvals,1); Ev_press=0; return 0;} ssize_t Key_write (structFile *FP,Const Char__user *buf, size_t count, loff_t *PPOs) {}intKey_close (structInode *inode,structFile *file) {FREE_IRQ (irq_eint0,&pins_desc[0]); FREE_IRQ (Irq_eint2,&pins_desc[1]); FREE_IRQ (irq_eint11,&pins_desc[2]); FREE_IRQ (irq_eint19,&pins_desc[3]); Up (&canopen);}StaticUnsignedintKey_poll (structFile *file,structPoll_table_struct *wait) {unsignedintMask =0; Poll_wait (file,&button_waitq,wait); if(ev_press) Mask|= pollin|Pollrdnorm; returnMask;}Static intKey_fsync (intFdstructFile *filp,intOn ) {PRINTK ("ok\n"); returnFasync_helper (FD, Filp, ON, &key_async_queue);}structFile_operations led_fops={. Owner=this_module,. Open=Key_open,. Write=key_write,. Read=key_read,. Release=Key_close,. Poll=key_poll,. Fasync=Key_fsync,};Static voidKeys_timer_fun (unsignedLongt) {    structPin_desc *pindesc = (structPIN_DESC *) Pin_timer; unsignedintPinval; if( !Pindesc)return ; Pinval= S3c2410_gpio_getpin (pindesc->pin); if(pinval) {keyvals= pindesc->key_val|0x80; }    Else{keyvals= pindesc->Key_val; } ev_press=1; Wake_up_interruptible (&BUTTON_WAITQ); Kill_fasync (&Key_async_queue, SIGIO, poll_in); return ;}intMajor;Static intKey_init (void) {Major= Register_chrdev (0,"Key_drv", &led_fops); Key_class= Class_create (This_module,"Key_class"); Key_class_devs= Class_device_create (Key_class,null,mkdev (Major,0), NULL,"My_keys"); Init_timer (&Keys_timer); Keys_timer.function=Keys_timer_fun; / * Timer Interrupt function * /keys_timer.expires=0; Add_timer (&Keys_timer); PRINTK ("Key Install module\n"); return 0;}Static voidKey_exit (void) {Unregister_chrdev (major,"Key_drv" );    Class_device_unregister (Key_class_devs);   Class_destroy (Key_class);   Del_timer (&Keys_timer); //Remove timer 
PRINTK ("Key Module exit\n");} Module_init (Key_init); Module_exit (Key_exit); Module_license ("GPL");

To test the application:

#include <stdio.h>#include<signal.h>#include<fcntl.h>#include<unistd.h>intFD;Static CharKey_val;intMainintargcChar**argv) {    intOflags; FD= Open ("/dev/my_keys", O_RDWR);/*O_nonblock for non-blocking*/    if(fd<0) {printf ("Open failed\n"); return 0; }     while(1) {Read (FD,&key_val,1); printf ("key_val:%d\n", Key_val); }    return 0;}

Sd

Linux Embedded Drive Learning Path (15) key Driver-timer stabilization

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.