Пользовательский обработчик прерываний для пользовательской кнопки на биглборде

Я новичок в разработке модулей ядра. Я пишу модуль ядра для обработки нажатия кнопки пользователя. Мне нужно, чтобы светодиод на плате светился после нажатия кнопки пользователя. Как мне написать собственный обработчик для пользовательской кнопки, поскольку она изначально получена модулями ядра. Нужно ли отключать кнопки GPIO в конфигурации ядра и писать полный модуль, или я могу просто зарегистрировать свой собственный обработчик?


person Sanket    schedule 18.11.2013    source источник


Ответы (1)


Сначала вам нужно удалить модуль gpio_keys из ядра. Используйте для этого команду rmmod - $> rmmod gpio_keys

Я не уверен в светящемся светодиоде на кнопке прерывания, но я мог бы обработать кнопку прерывания, используя следующий код:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#include <asm/gpio.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/proc_fs.h>
#include<linux/sched.h>

#define GPIO 4

int var;

static irqreturn_t irq_handler(int irq, void *dev_id,struct pt_regs *regs)
{
    var++;
    printk("In the Interrupt handler, Count: %d\n", var);

    return IRQ_HANDLED;
}

int read_proc(char *buf,char **start,off_t offset,int count,int *eof,void *data )
{
   int len=0;
   if(offset>0)
   {len=0;}
   else{len  += sprintf(buf, "No of times button pressed: %d\n",++var);}
   return len;
}

void create_new_proc_entry()
{
  create_proc_read_entry("hello",0,NULL,read_proc,NULL);
}

static int __init hello_init(void)
{
       int errno = 0;
       printk("Hello: registered module successfully!\n");

       create_new_proc_entry();

      if((errno = gpio_direction_input(GPIO)) !=0)
      {
         printk(KERN_INFO "Can't set GPIO direction, error %i\n", errno);
         gpio_free(GPIO);
         return -EINVAL;
      }
       int irq_line = gpio_to_irq(GPIO);
       printk ("IRQ Line is %d \n",irq_line);

       errno = request_irq( irq_line, irq_handler, IRQF_TRIGGER_FALLING, "Interrupt", NULL );
      if(errno<0)
       {
         printk(KERN_INFO "Problem requesting IRQ, error %i\n", errno);
       }
       return 0;
}


static void __exit hello_exit(void)
{
  printk ("Unloading my module.\n");
  remove_proc_entry("hello",NULL);
  int irq_line = gpio_to_irq(GPIO);
  free_irq(irq_line,NULL);
  printk("Hello Example Exit\n");
  return;
}



module_init(hello_init);
module_exit(hello_exit);

// do some kernel module documentation
MODULE_AUTHOR("Deadman");
MODULE_DESCRIPTION("Interrupt Module");
MODULE_LICENSE("GPL");

Вы можете игнорировать вызовы, связанные с файловой системой proc выше. Просто проверьте функции обработчика прерываний. Этот код работал нормально для меня.

Также, если вы хотите использовать семафоры или любую дополнительную работу во время обработки прерываний, перейдите по этой ссылке для создания тасклетов -

http://www.ibm.com/developerworks/library/l-tasklets/

По сути, вы можете вызвать tasklet_schedule в коде обработчика прерываний.

Надеюсь это поможет.

person Kedar Joshi    schedule 04.12.2013
comment
Если мы можем удалить модуль gpio_keys, это означает, что это динамический модуль. В этом случае светодиоды, приобретенные с этим модулем, также освобождаются? Поправьте меня, если я ошибаюсь. - person Sanket; 30.01.2014
comment
Ну, я не уверен в этом. Я написал код выше для какой-то другой цели, и мне пришлось удалить gpio_keys для обработки кнопки прерывания. А вот про светодиоды не знаю. Я почти уверен, что вы можете обрабатывать прерывания, используя этот код. - person Kedar Joshi; 31.01.2014