GPIO Kernel driver

the goal of this project is just to implement a simple module that registers an interrupt handler which keeps track of how many interrupts it receives. On the Beagleboard, we can use the User buttons as source of interrupts. Make sure you properly change the multiplexing configuration of the associated pad to configure it as a GPIO. To show off that the interrupt handler is working, switch on an LED whenever the button is pressed and switch it off when the button is released. In your module init function, register your handler on the GPIO’s interrupt line, which is defined by a irq module parameter.

C language :

#include <linux/kernel.h>
#include <linux/console.h>
#include <linux/init.h>
#include <linux/time.h>
#include <asm/string.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/workqueue.h>

#define USE_GPIO
#define USE_INTERRUPT

static void mykmod_work_handler (struct work_struct *myWorkQueue);
static struct workqueue_struct *myWorkQueue = 0;
static DECLARE_DELAYED_WORK (mykmod_work, mykmod_work_handler);
static unsigned long onesec;

#ifdef USE_INTERRUPT
static void
workInInte (void)
{
  printk ("***Interrupt detected***\n");
  queue_delayed_work (myWorkQueue, &mykmod_work, onesec);
}

static irqreturn_t
interruption (int irq, void *dev_id)
{
  workInInte ();
  return IRQ_HANDLED;
}
#endif

static void
mykmod_work_handler (struct work_struct *myWorkQueue)
{
  int i = 0;
  printk ("***myWorkQueue flash time:200ms***\n");
  for (i = 0; i < 6; i++)
    {
      gpio_set_value (150, (i % 2));
      mdelay (200);
    }
}

static int __init
mykmod_init (void)
{
  int ret;
  printk ("*******************************************************\n");
  printk ("*Hello Mras2an*\n");
  printk ("*******************************************************\n\n");

#ifdef USE_GPIO
  printk ("***LED D7***\n");
  /*set a LED D7 on beagleboard*/
  gpio_request (150, "LED D7");
  gpio_direction_output (150, 1);
  gpio_set_value (150, 0);
#endif

#ifdef USE_INTERRUPT
  /*use interrupt */
  if (gpio_is_valid (4) == 0)
    {
      printk ("you can't use the GPIO\n");
    }
  else
    {
      printk ("you can use the GPIO\n");
    }

  gpio_request (4, "IntQu");
  gpio_direction_input (4);
  gpio_get_value (4);

  if ((ret =
       request_irq (gpio_to_irq (4), interruption, IRQF_TRIGGER_FALLING,
            "IntQu", NULL)) != 0)
    {
      printk (KERN_DEBUG "erreur request_irq : %d \n", ret);
    }
  else
    {
      printk ("***Interrupt : Ok***\n");
    }
#endif
  /*use woekqueue */
  onesec = msecs_to_jiffies (100);
  printk ("myWorkQueue init");
  if (!myWorkQueue)
    {
      myWorkQueue = create_singlethread_workqueue ("myWorkQueue");
    }

  return 0;
}

static void __devexit
mykmod_exit (void)
{
  struct timeval *start = NULL;
  start = kmalloc (sizeof (start), GFP_ATOMIC);
#ifdef USE_GPIO
  gpio_free (150);
#endif

#ifdef USE_INTERRUPT
  free_irq (gpio_to_irq (4), NULL);
  gpio_free (4);
#endif
  do_gettimeofday (start);
  kfree (start);
  if (myWorkQueue)
    {
      destroy_workqueue (myWorkQueue);
    }

  printk ("myWorkQueue exit,\nfree GPIO,\nfree interrupt.\n");
  printk ("\nstart->tv_usec:%ld \n", start->tv_usec);
  printk ("start->tv_sec:%ld \n", start->tv_sec);
  printk ("*********************************************************\n");
  printk ("*Goodbye Mras2an*\n");
  printk ("*********************************************************\n\n");
}

/*************************************************************
 hello.c
*************************************************************/
module_init (mykmod_init);
module_exit (mykmod_exit);

MODULE_LICENSE ("GPL");
MODULE_DESCRIPTION ("test module");
MODULE_AUTHOR ("Mras2an");

 

Makefile :

obj-m := hello_version.o                                                            
KDIR := /kernel/linux-omap-2.6
PWD := $(shell pwd)
default:
    $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules


KDIR: it's your kernel path.
You can compile the code with make command, copy "helo.ko" on your board and mount the driver with "insmod helo.ko" commande.

Sujet: GPIO Kernel driver

Aucun message nʼ a été trouvé.

Nouvel avis