registering asynchronous events on kernel thread in user space

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!

Hi

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

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

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.

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.

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.

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.

Or, you can make the gpio look like an event/button: http://bec-systems.com/site/281/how-to-implement-an-interrupt-driven-gpio-input-in-linux

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

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…

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

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.

I agree with everything Brandon just articulated.

Regards,
John

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

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…

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!

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.

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

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:

https://github.com/linux-wpan

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

majordomo@vger.kernel.org

Regards,
John

Hi John

Thanks for the link.