Mini2440 按键驱动程序学习笔记

发布时间:2024-06-28  

参考了友善之臂的按键驱动程序和韦东山写的《嵌入式Linux应用开发完全手册》【下载见http://www.linuxidc.com/Linux/2011-01/31114.htm】一书的第20章—Linux异常处理体系结构部分的按键驱动程序,修改了部分内容,学习了嵌入式Linux下按键驱动程序。

按照习惯,先看原理,对所学习的知识结构有了大致的了解了开始阅读别人的代码,仔细分析代码实现的每个过程。由于时间有限,我只了解了一些概念性的理论和内核代码中部分数据结构,学习的过程还有待深入。对于我这样的初学者来说,想把资料中所介绍的每个原理和具体的实现方法都完全掌握,恐怕不止是时间的问题,我所追求的是一种快速上手的方法,先学会用再深入学习。

下面是经我改动后的按键驱动程序:

/*buttons_driver.c*/

 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

     

#define DEVICE_NAME     "buttons"

     

      struct button_irq_desc {

             int irq;

             int pin;

             int pin_setting;

             int number;

             char *name;

      };

     

      static struct button_irq_desc button_irqs [] = {

             {IRQ_EINT8 , S3C2410_GPG0 ,  S3C2410_GPG0_EINT8  , 0, "KEY0"},

             {IRQ_EINT11, S3C2410_GPG3 ,  S3C2410_GPG3_EINT11 , 1, "KEY1"},

             {IRQ_EINT13, S3C2410_GPG5 ,  S3C2410_GPG5_EINT13 , 2, "KEY2"},

             {IRQ_EINT15, S3C2410_GPG7 ,  S3C2410_GPG7_EINT15 , 3, "KEY3"},

             {IRQ_EINT14, S3C2410_GPG6 ,  S3C2410_GPG6_EINT14 , 4, "KEY4"},

             {IRQ_EINT19, S3C2410_GPG11,  S3C2410_GPG11_EINT19, 5, "KEY5"},

      };

     

      static volatile char key_values [] = {'0', '0', '0', '0', '0', '0'};

     

      static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

     

      static volatile int ev_press = 0;

     

     

      static irqreturn_t buttons_interrupt(int irq, void *dev_id)

      {

             struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;

                   

             if ('0'== key_values[button_irqs->number]) { // Changed

     

                    key_values[button_irqs->number] =  '1';

             }

             else if('1' == key_values[button_irqs->number]){

                    key_values[button_irqs->number] = '0';

             }

             ev_press = 1;

             wake_up_interruptible(&button_waitq);

            

             return IRQ_RETVAL(IRQ_HANDLED);

      }

     

     

      static int s3c24xx_buttons_open(struct inode *inode, struct file *file)

      {

             int i;

             int err;

             //set the interrupt to falling

       //友善的是上升沿和下降沿都中断,这里改成下降沿中断

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

                    err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_FALLING,

                                                  button_irqs[i].name, (void *)&button_irqs[i]);

                    if (err)

                           break;

             }

     

             if (err) {

                    i--;

                    for (; i >= 0; i--) {

                    disable_irq(button_irqs[i].irq);

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

                    }

                    return -EBUSY;

             }

     

             ev_press = 1;

            

             return 0;

      }

     

     

      static int s3c24xx_buttons_close(struct inode *inode, struct file *file)

      {

             int i;

            

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

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

             }

     

             return 0;

      }

     

     

      static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)

      {

             unsigned long err;

     

             if (!ev_press) {

             if (filp->f_flags & O_NONBLOCK)

                    return -EAGAIN;

             else

                    wait_event_interruptible(button_waitq, ev_press);

             }

            

             ev_press = 0;

     

             err = copy_to_user(buff, (const void *)key_values, min(sizeof(key_values), count));

     

             return err ? -EFAULT : min(sizeof(key_values), count);

      }

 

      #if 0

      static unsigned int s3c24xx_buttons_poll( struct file *file, struct poll_table_struct *wait)

      {

             unsigned int mask = 0;

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>