7

I'm writting a driver for a synthesized device in an FPGA. The device has several IRQs and have requested them on my driver:

irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
rc = request_irq(irq, &Custom_driver_handler,IRQF_TRIGGER_RISING , DRIVER_NAME, base_addr);

My problem is that i want that the irq_handler calls a function of an user space application. Is there any way to call my user space application from the irq_handler of the driver on kernel space??

I know i could save a flag from the driver and mmap its direction from the user application to polling it, but what i want to know is if there is any faster/more correct way.

Thank you in advance

eps_712
  • 135
  • 1
  • 2
  • 8
  • 2
    Almost twenty years ago this was called the "upcall" in the Linux kernel: http://lkml.iu.edu/hypermail/linux/kernel/9809.3/0922.html. Ten years ago the article was posted https://lwn.net/Articles/127698/ Handling interrupts in user space. And now there is UIO framework: UIO (User I/O) http://unix.stackexchange.com/questions/136274/can-i-achieve-functionality-similar-to-interrupts-in-linux-userspace https://lwn.net/Articles/232575/ https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt/ https://www.osadl.org/fileadmin/dam/rtlws/12/Koch.pdf http://www.hep.by/gnu/kernel/uio-howto/ – osgx Mar 13 '17 at 14:35
  • As i understand, detecting an interrupt using a UIO driver is making polling to a memory direction. Isn't it?? Example of use of UIO driver : int32_t irq_count; int fd = open("/dev/uio0", O_RDWR); void *map_addr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); /* Always read exactly 4 bytes! */ while (read(fd, &irq_count, 4) == 4) { printf(Interrupt number %d\n, irq_count); } – eps_712 Mar 14 '17 at 13:22
  • no you understanding is not full: this read will not return control back to user program when there is no interrupt: https://lwn.net/Articles/232575/ "*The user-space driver will open the device (/dev/uio0). Reading the device returns an int value which is the event count (number of interrupts) seen by the device; **if no interrupts have come** in since the last read, the **operation will block** until an interrupt happens (though non-blocking operation is supported in the usual way as well).*" – osgx Mar 14 '17 at 14:26
  • Possible duplicate of [Linux Interrupt Handling in User Space](https://stackoverflow.com/questions/7986260/linux-interrupt-handling-in-user-space) – Ciro Santilli OurBigBook.com Jun 15 '17 at 06:30

1 Answers1

6

There are several ways of invoking user-space functions from kernel, usually named upcalls: http://lkml.iu.edu/hypermail/linux/kernel/9809.3/0922.html; check also https://lwn.net/Articles/127698/ "Handling interrupts in user space" and the http://wiki.tldp.org/kernel_user_space_howto overview from 2008, part "Sending Signals from the Kernel to the User Space".

To make writing drivers easier, there is UIO framework in the kernel now: https://unix.stackexchange.com/questions/136274/can-i-achieve-functionality-similar-to-interrupts-in-linux-userspace https://lwn.net/Articles/232575/ https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt/ https://www.osadl.org/fileadmin/dam/rtlws/12/Koch.pdf http://www.hep.by/gnu/kernel/uio-howto/

With UIO you can block or poll special file descriptor to wait for interrupt (block by using read() syscall; poll with poll syscall): https://lwn.net/Articles/232575/

On the user space side, the first UIO-handled device will show up as /dev/uio0 (assuming a normal udev setup). The user-space driver will open the device. Reading the device returns an int value which is the event count (number of interrupts) seen by the device; if no interrupts have come in since the last read, the operation will block until an interrupt happens (though non-blocking operation is supported in the usual way as well). The file descriptor can be passed to poll().

include/linux/uio_driver.h is available in linux kernel for many years, it is here for 3. and 4. versions of kernel.

Community
  • 1
  • 1
osgx
  • 90,338
  • 53
  • 357
  • 513