4

I am writing Linux user space application. where I want to invoke registered callback function in user space area from the kernel space.

i.e. interrupt arriving on GPIO pin(switch press event) and registered function getting called in user space.

is there any method is available to do this.

Thanks

Claudio
  • 10,614
  • 4
  • 31
  • 71
Akash Gajjar
  • 94
  • 2
  • 8
  • 3
    I think the usual way to do this is for the device driver to send a `SIGIO` signal to the process. The process registers a signal handler that executes the callback. – Barmar Jul 06 '17 at 13:18
  • https://github.com/brgl/libgpiod. @Barmar, looks like you have legacy knowledge on topic :-) – 0andriy Jul 06 '17 at 21:34
  • there also is a python module called [python-sysfs-gpio](https://github.com/derekstavis/python-sysfs-gpio). – Fl0v0 Jul 07 '17 at 07:33
  • @FI0v0, don't use it. It's legacy stuff left for backward compatibility. – 0andriy Jul 08 '17 at 08:22
  • @0andriy wow, i didnt know that. is there some more information on this topic? maybe in a mailing list? I needed a python interface for the gpios and all i found back then was python-sysfs-gpio. If this is legacy, there is the need for a new python interface. – Fl0v0 Jul 10 '17 at 09:34
  • @Fl0v0, see my comment above with the link to a new brand library. I dunno if it has a python binding. – 0andriy Jul 10 '17 at 11:11
  • @0andriy It doesn't have python bindings yet :( https://github.com/brgl/libgpiod/issues/5 – Fl0v0 Jul 12 '17 at 08:48
  • @Fl0v0, meaning someone has a great chance to make themselves famous. – 0andriy Jul 12 '17 at 16:07

2 Answers2

1

I found below code after lot of digging and perfectly works for me.

Handling interrupts from GPIO In many cases, a GPIO input can be configured to generate an interrupt when it changes state, which allows you to wait for the interrupt rather than polling in an inefficient software loop. If the GPIO bit can generate interrupts, the file edge exists. Initially, it has the value none , meaning that it does not generate interrupts. To enable interrupts, you can set it to one of these values: • rising: Interrupt on rising edge • falling: Interrupt on falling edge • both: Interrupt on both rising and falling edges • none: No interrupts (default) You can wait for an interrupt using the poll() function with POLLPRI as the event. If you want to wait for a rising edge on GPIO 48, you first enable interrupts:

#echo 48 > /sys/class/gpio/export

#echo rising > /sys/class/gpio/gpio48/edge

Then, you use poll() to wait for the change, as shown in this code example:

 #include <stdio.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <poll.h>>

 int main(void) {

         int f;
         struct pollfd poll_fds [1];
         int ret;
         char value[4];
         int n;

         f = open("/sys/class/gpio/gpio48", O_RDONLY);
         if (f == -1) {
              perror("Can't open gpio48");
              return 1;
         }

         poll_fds[0].fd = f;
         poll_fds[0].events = POLLPRI | POLLERR;

         while (1) {
              printf("Waiting\n");

              ret = poll(poll_fds, 1, -1);
              if (ret > 0) {
                  n = read(f, &value, sizeof(value));
                  printf("Button pressed: read %d bytes, value=%c\n", n, value[0]);
              }
         }     
      return 0; 
}
Akash Gajjar
  • 94
  • 2
  • 8
  • Didn't work for me. I'm not sure why, though. The code triggers immediately when it is first run, but then never again when I trigger further interrupts. I'm comparing my code to this link: https://developer.ridgerun.com/wiki/index.php/Gpio-int-test.c to see what I am doing differently. I know that the further interrupts are being triggered, because my kernel-level driver that watches for the same interrupt is catching it each time. I'll update this when I figure out what is going wrong. – Eliezer Miron Apr 15 '19 at 23:58
  • Turns out, using gpio.h to configure interrupts only works at the kernel level. I needed to also change the edge value from the user level to get it to work. But now it's working great! – Eliezer Miron Apr 16 '19 at 17:38
  • Oh, and on line 15, I think you are missing "/value" after "/sys/class/gpio/gpio48" – Eliezer Miron Apr 16 '19 at 17:54
0

Have to implement a handler in a kernel module that triggers e.g. a char device. From user space it could be accessed by polling (e.g. ioctl() calls). It seems that it is the only way at the moment.

renonsz
  • 571
  • 1
  • 4
  • 17