5

I have a code which detects GPIO interrupt in a kernel module. Now,I am looking for a mechanism to notify user space upon detecting gpio interrupt from kernel module. Any example / code snippet with certain advantages/disadvantages over different options? I would appreciate your response.

user1867459
  • 423
  • 2
  • 8
  • 27
  • 1
    See http://stackoverflow.com/questions/19257624/interrupt-handling-and-user-space-notification/19258745#19258745. – eepp Nov 06 '13 at 19:10
  • Thanks for redirecting me to the post. Looks like what I am looking for is served by Netlink socket only. I don't want to have polling based solution from a user space. Could you please confirm that Netlink is the only solution under such a scenario? – user1867459 Nov 06 '13 at 21:03
  • 3
    You want to use the `poll(2)` system call, not to actually poll. `poll(2)` will block your thread and unblock when there's some possible I/O on the file descriptor. For GPIO pins file descriptors, this means the value changed (from 0 to 1 or vice versa). – eepp Nov 06 '13 at 22:10
  • 1
    See also [Sysfs and GPIO](http://stackoverflow.com/questions/19744811/how-is-sysfs-updated-when-a-gpio-change-state) as well as the [gpio.txt](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/gpio.txt) kernel documentation which provides documentation on the *sysfs* user space implementation to notify of changes (via irqs), using `poll()` underneath. – artless noise Nov 08 '13 at 16:04

3 Answers3

1

Take a look at the GPIO keyboard driver (drivers/input/keyboard/gpio_keys.c). It is a good starting point for your problem.

In the userspace you then listen (some blocking read for example, or just tail to test) to /dev/input/yourevent for events.

Ortwin Angermeier
  • 5,957
  • 2
  • 34
  • 34
  • Hi Thanks for the reply. I am looking for a non-polling/non-blocking based solution.i.e. the user space thread need not monitor for the event to happen, instead it should be notified that now the event happened. – user1867459 Nov 06 '13 at 21:01
  • 1
    That is not possible. A "real" interrupt can only be handled in the kernel. If you *really*, and i mean *really really* have to have minimal latency you would have to implement your logic in the kernel(module). That brings up the question: why are you looking for a non-blocking solution? Give some more details with your problem. What is generating the interrupt(over GPIO) in what frequency etc. – Ortwin Angermeier Nov 06 '13 at 21:40
1

You can send a signal to user space thread from kernel API, which can help u run non-blocking:

send_sig(int sig, struct task_struct *p, int priv)

But there is a limitation: u need to be aware of pid of user thread in Kernel. You can over come this by writing pid of user process via /proc and then kernel reading the pid. With this arrangement, when there is an interrupt, kernel can send signal to user thread. In case your process restarts or gets killed, you will have to update the pid via proc.

If i were you, i would have preferred to do this unless i dont want to transfer data from kernel to user. For data transfer requirement, i would have used Netlink or some other mechanism.

Gyan Gupta
  • 986
  • 8
  • 15
  • *You can send a signal to user space thread from kernel API, which can help u run non-blocking:*, in the mean time, whats the user-land thread doing? Is it waiting? It is. There is no way(for good reason) to let the kernel execute some function directly user-space. In the end, a user-space thread always has to wait for the kernel to do something. That's the way it is. – Ortwin Angermeier Nov 07 '13 at 02:18
  • what user thread will do: it depends of design of thread. If user thread only have to take some action on receipt of interrupt then blocking mode is good. However, if user thread is doing other tasks as well then it makes sense to receive the signals from kernel. sending signal from kernel to user can not be termed bad, however this approach is less used. Depending on situation, there is nothing bad in using this approach. – Gyan Gupta Nov 07 '13 at 02:55
1

You can: (1) Send a signal to the user application, or (2) implement file_operations->poll method, use poll_wait and wait queue to wake user application when interrupt occur.

Hook Guo
  • 85
  • 2
  • 8