registering asynchronous events on kernel thread in user space

659 views
Skip to first unread message

sid...@gmail.com

unread,
Aug 28, 2014, 5:44:12 AM8/28/14
to beagl...@googlegroups.com
I have read online that we can't handle interrupts from user space. Instead - 
1) We can write a kernel thread and have that thread wait on an event. 
2) Once the interrupt occurs, send one asynchronous event from the kernel module/driver to user space where we will have one signal handler with FASYNC to tackle this

I have written a kernel module that registers interrupts on the rising edge on a GPIO pin and want to relay this message to user space. How do I go about implementing the above?

Thanks!

neo star

unread,
Sep 8, 2014, 10:40:33 PM9/8/14
to beagl...@googlegroups.com, sid...@gmail.com
Hi

I too have the same question, have you found any answer ? thanks

kavitha bk

unread,
Sep 9, 2014, 1:52:58 AM9/9/14
to beagl...@googlegroups.com, sid...@gmail.com
May be you can use udev In the 
        err = request_threaded_irq(pdata->irq, NULL, receive_thread,
                                   pdata->irqflags, "interrupt", ir);



In reciever thread
static irqreturn_t receive_threar(int irq, void *context_data)
{
 struct data *dh = context_data;
     
input_report_key(dh->input_dev, key, 1);

      input_sync(dh>input_dev)

}



In userspace use evetest like application to wait on the event or simple select on /dev/input should work



--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Brandon I

unread,
Sep 9, 2014, 3:29:08 PM9/9/14
to beagl...@googlegroups.com, sid...@gmail.com
See UIO: https://www.kernel.org/doc/htmldocs/uio-howto/

The uio_pruss.c driver that comes with the pru package is a good example.

> I have written a kernel module that registers interrupts on the rising edge on a GPIO pin and want to relay this message to user space. 

The sysfs gpio interface already does this. Check out the code.

neo star

unread,
Sep 9, 2014, 10:10:41 PM9/9/14
to beagl...@googlegroups.com, sid...@gmail.com
Hi Brandon

I read through the link, very informative thanks.I can create a thread to do the polling and signal me when its ready.
But how to really write an ISR in arm. I see a lot of guides but they say that it will work in Intel processors but they are not sure about ARM.
For sure from my readings i see that i need a kernel object to handle an ISR, But how to really do that.
One example about how to handle interrupts is in http://stackoverflow.com/questions/15245626/simple-interrupt-handler-request-irq-returns-error-code-22
The other one is request_threaded_irq() as mentioned by Kavita in the above post.
Is there any How to and guide to writing one. Any links.
Thanks.

neo

unread,
Sep 9, 2014, 10:28:06 PM9/9/14
to beagl...@googlegroups.com, sid...@gmail.com
Hi Kavita

I understood the part of request_threaded_irq() found a sample implementation here-> http://lxr.free-electrons.com/source/drivers/input/touchscreen/cy8ctmg110_ts.c for touch controllers.
But did not understand the bit about

"In userspace use evetest like application to wait on the event or simple select on /dev/input should work"

Can you elaborate what you meant by that ? Thanks.

Brandon I

unread,
Sep 9, 2014, 10:50:18 PM9/9/14
to beagleboard
Before you jump into the kernel hole, is there a reason that you're not using the existing sysfs gpio interface (https://www.kernel.org/doc/Documentation/gpio/sysfs.txt) for the interrupts?

Using this, if you set the gpio up as an interrupt with the sysfs interface, you poll() the value file and it will block until there's an interrupt. When it unblocks, you can read the current value.


Any sane way you do it will be the same at the low level. You'll have a read or ioctl function on the kernel device file that blocks in the kernel using a completion/semaphore, putting your process/thread to sleep. When the interrupt fires, the interrupt handler function is called to release the completion/semaphore, unblocking your process/thread and allowing it to continue executing. This unblocking is how the userspace program is signaled.

So, if you *want* to reinvent the wheel, for understanding, then that's fine. But, there's an existing interface that exists, only a few lines of code away.

--Brandon

--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to a topic in the Google Groups "BeagleBoard" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/beagleboard/eNX0CU7-noE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to beagleboard...@googlegroups.com.

neo

unread,
Sep 10, 2014, 8:13:55 AM9/10/14
to beagl...@googlegroups.com
Hi Brandon

Thanks for the reply.
I will summarize here what i found about controlling a GPIO and about using interrupts.
  1. Using sysfs one can easily control the gpio and using threading can re-create pseudo-interrupt from user space. Found a useful project called libsoc https://github.com/jackmitch/libsoc. They use threading along with polling using poll(2)
  2. Using mmap() one can import the memory space of the GPIO peripheral and with a combination of threads can re-create pseudo-interrupt from user space. Found useful project called BBBIOlib https://github.com/VegetableAvenger/BBBIOlib.
  3. Using /dev/input/event for controlling GPIO from user space.
  4. Using an LKM from kernel space where one can use request_irq() or request_threaded_irq() and using some kind of buffering to transfer the data to userspace. Here one will be writing actual interrupts. Some bits can be found here http://processors.wiki.ti.com/index.php/GPIO_Driver_Guide#Sysfs_entries_configuration

I have very good idea about 1 and 2.

I am still working on 3-> /dev/input and also on 4-> about writing a real ISR.

Although the above methods enable GPIO control I am not sure which will give me the highest performance.

I read that using mmap() method gives faster switching on forums and the using sysfs gives the slowest switching rate. I am not sure about /dev/input method. The LKM method gives faster ISR and i am guessing that LKM in combination with mmap() will give faster response timings.

Any thoughts on the above...

John Syn

unread,
Sep 10, 2014, 3:20:36 PM9/10/14
to beagl...@googlegroups.com

From: neo <prag....@gmail.com>
Reply-To: "beagl...@googlegroups.com" <beagl...@googlegroups.com>
Date: Wednesday, September 10, 2014 at 5:13 AM
To: "beagl...@googlegroups.com" <beagl...@googlegroups.com>
Subject: Re: [beagleboard] Re: registering asynchronous events on kernel thread in user space

Hi Brandon

Thanks for the reply.
I will summarize here what i found about controlling a GPIO and about using interrupts.
  1. Using sysfs one can easily control the gpio and using threading can re-create pseudo-interrupt from user space. Found a useful project called libsoc https://github.com/jackmitch/libsoc. They use threading along with polling using poll(2)
  2. Using mmap() one can import the memory space of the GPIO peripheral and with a combination of threads can re-create pseudo-interrupt from user space. Found useful project called BBBIOlib https://github.com/VegetableAvenger/BBBIOlib.
  3. Using /dev/input/event for controlling GPIO from user space.
  4. Using an LKM from kernel space where one can use request_irq() or request_threaded_irq() and using some kind of buffering to transfer the data to userspace. Here one will be writing actual interrupts. Some bits can be found here http://processors.wiki.ti.com/index.php/GPIO_Driver_Guide#Sysfs_entries_configuration

I have very good idea about 1 and 2.

I am still working on 3-> /dev/input and also on 4-> about writing a real ISR.

Although the above methods enable GPIO control I am not sure which will give me the highest performance.

I read that using mmap() method gives faster switching on forums and the using sysfs gives the slowest switching rate. I am not sure about /dev/input method. The LKM method gives faster ISR and i am guessing that LKM in combination with mmap() will give faster response timings.

Any thoughts on the above...

You are on the right path. One thing to remember, whenever you are doing any I/O from user space, you are dealing with context switching and thread scheduling, which means that your application won’t respond to a GPIO event for anywhere from a few ms to 100mS. This is true because of both the interrupt latency in Linux and thread scheduler. In most cases, this is fine, because the user doesn’t know the difference. However, if you are attempting to do some sort of control, then you may want to consider the PRU. The PRU can still send events to your user space app. Another solution might be Xenomai which reduces to interrupt latency to about 50uS on the BBB, but you still have the context switch delay. 

Regards,
John
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.

Brandon I

unread,
Sep 10, 2014, 4:56:15 PM9/10/14
to beagleboard
> pseudo-interrupt from user space

There's nothing pseudo about it. Again, any usual way to have a userspace application respond to an interrupt will be the exact same. The kernel will block the userspace process until the interrupt is seen. The only real alternative is burning up the cpu with memory polling, which appears to be what the BBIOlib method uses. So, your latency is limited to your poll speed (which can be faster than interrupts). But, if you have a constant poll for minimum latency, lets hope you're not trying to do something important elsewhere since your cpu usage will be at 100%, and you'll be maximizing process to process context switching!

For 4, The only difference between a userspace and kernel space interrupt handler is where the code is that responds to the interrupt. You will only benefit from writing your own interrupt handler if you put all of your code that does something with that interrupt in the kernel. Otherwise, you're back to process blocked by kernel, interrupt occurs, kernel unblocks process, process does something after seeing the interrupt....back to the sysfs/UIO method.

I would try some benchmarks. See if the regular UIO/sysfs interrupt method gives you sufficient performance. And definitely keep in mind John's statement. You're going to see a massive amount of jitter for anything in userspace or kernel space (better jitter since you can disable interrupts and whatnot, but if you don't finish quickly in kernel space, you'll crash the kernel).

If something like a precise timestamp is needed for an async event, then there are other ways to approach this. If you're looking for fixed low latency, you're doomed.

On Wed, Sep 10, 2014 at 5:13 AM, neo <prag....@gmail.com> wrote:
pseudo-interrupt from user space


John Syn

unread,
Sep 10, 2014, 5:05:12 PM9/10/14
to beagl...@googlegroups.com

From: Brandon I <brando...@gmail.com>
Reply-To: "beagl...@googlegroups.com" <beagl...@googlegroups.com>
Date: Wednesday, September 10, 2014 at 1:55 PM

To: "beagl...@googlegroups.com" <beagl...@googlegroups.com>
Subject: Re: [beagleboard] Re: registering asynchronous events on kernel thread in user space
I agree with everything Brandon just articulated. 

Regards,
John

On Wed, Sep 10, 2014 at 5:13 AM, neo <prag....@gmail.com> wrote:
pseudo-interrupt from user space


--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.

neo

unread,
Sep 11, 2014, 1:07:26 PM9/11/14
to beagl...@googlegroups.com

Hi John

  1. You said that i can execute control functions / time critical functions using PRU, but how ? Is there any guide/sample code to using the PRU like in github ?
  2. There is nothing described about using PRU in the TRM, except that its has 7 interrupt lines so are there application notes or guides or ready to use libraries.
  3. Any reason why you suggested that i can use PRU for time critical operations and can generate a signal to the user-space reliably without that jitter you were referring to ? 

Thanks

neo

unread,
Sep 11, 2014, 1:22:41 PM9/11/14
to beagl...@googlegroups.com
Hi Brandon
  1. I agree with jitter involved with processing interrupts and 100% cpu usage during polling for the same, so is there no way to let the user-space know that interrupt has occurred apart from polling ?
  2. The reason why i said pseudo-interrupt is because we are polling and waiting there which is same as watching a flag in a UART register for RX flag to set.
  3. I am curious as to how interrupts for Ethernet and usb are written. I am guessing that the ISR will use the DMA to transfer bytes to user-space. But even in that case the userspace should know that a new data has arrived. Then hoe to synchronize the kernel space and user-space if there are to share a data ? 

Thanks...

Brandon I

unread,
Sep 11, 2014, 3:49:26 PM9/11/14
to beagl...@googlegroups.com
OK, one more time. All userspace interrupts work the same, pru, network driver, *anything*. The process blocks until the interrupt handler unblocks the process with a semaphore or completion in the kernel. For example, when you read data for a socket connection, it blocks. When data comes in, the data is copied to userspace, the read function unblocks. Again, this is all explained in that LDD3 chapter I linked. There's no other way to do it, except going around the kernel and polling memory.

1. This isn't a realtime kernel. You will always have jitter. Does it matter? I don't know what you're doing. You don't need to use polling. UIO and select doesn't use polling.

2. Using select (and even poll() since it's just a wrapper for select()) on the gpio doesn't poll. It's interrupt driven. Same method as described.

3. Same method as described.

If you use the PRU, it will be the same method to notify your userspace application with the same shortcomings, unless you put all of your code into the pru. If you want deterministic timing, you either need a realtime kernel, or put all your code on the pru. But, I can guarantee you don't need deterministic timing, and I can guess that you're worrying about nothing Seriously, do some benchmarks with sysfs. It's only a few lines of code. And, there are all sorts of userspace hardware drivers that use userspace interrupts out there including graphics and network. 

If you only need to know when a gpio event happened, and process it later (it will always be later since this isn't a realtime kernel or in the pru), you can timestamp the event. I believe you can do this with the enhanced timers, and I know you can do this in the pru. So it would go, event happens, pru/etimer hardware timestamps the event, sends interrupt, userspace gets interupt using "the only way possible", userspace reads timestamp from hardware, pretends that the event happened at the timestamp for any calculations.

If you explained what you were doing, we could advise you better.

Good luck!

William Hermans

unread,
Sep 11, 2014, 4:00:57 PM9/11/14
to beagl...@googlegroups.com
If you only need to know when a gpio event happened, and process it later (it will always be later since this isn't a realtime kernel or in the pru), you can timestamp the event.


Even an RTOS will process events later, it just does it a bit faster. And I can not agree with you more Brandon. 99% of the time, worrying about how fast you can process events turns into an over obsession. Also, if you need to react that fast to an "event", you're using he wrong hardware, and most likely going to need something like a C2000.

neo

unread,
Sep 13, 2014, 9:17:12 AM9/13/14
to beagl...@googlegroups.com
Hi Brandon

I am learning to use the BBB to interface a 802.15.4 radio to BBB without a MCU between BBB and CC2500. I want to remove the MCU and interface directly to the Kernel.
So for this i have to service interrupts which will be a gpio interrupt to BBB if a new packet arrives. So that the reason for the Doubts n questions.
And also the reason why i want to know which method is faster or better.
But I think that i have to do some profiling as u pointed out.
Will post the results ASAP here.

Thanks for the reply
To unsubscribe from this group and all its topics, send an email to beagleboard+unsubscribe@googlegroups.com.

John Syn

unread,
Sep 13, 2014, 6:14:49 PM9/13/14
to beagl...@googlegroups.com
Date: Saturday, September 13, 2014 at 6:17 AM

To: "beagl...@googlegroups.com" <beagl...@googlegroups.com>
Subject: Re: [beagleboard] Re: registering asynchronous events on kernel thread in user space

Hi Brandon

I am learning to use the BBB to interface a 802.15.4 radio to BBB without a MCU between BBB and CC2500. I want to remove the MCU and interface directly to the Kernel.
Are you referring to the CC2520? If so, there is a driver in the linux-wpan repo:


If you want support, send “subscribe linux-wpan” e-mail to:


Regards,
John
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.

neo star

unread,
Sep 13, 2014, 10:20:42 PM9/13/14
to beagl...@googlegroups.com
Hi John

Thanks for the link.
>>> beagleboard...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>
> --
> For more options, visit http://beagleboard.org/discuss
> ---
> You received this message because you are subscribed to the Google Groups
> "BeagleBoard" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to beagleboard...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
> --
> For more options, visit http://beagleboard.org/discuss
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "BeagleBoard" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/beagleboard/eNX0CU7-noE/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
Reply all
Reply to author
Forward
0 new messages