Assigning Interrupt Handlers

Frey, Fred (ext ???) f.frey at
Tue Sep 8 15:14:24 CEST 2020

Thank you both for your quick responses. I found both examples provided quite edifying.


Because of the simplicity of the driver I need to write, it sounds like you're recommending UDD over RTDM. Is that accurate?


-----Original Message-----
From: Philippe Gerum <rpm at> 
Sent: Sunday, September 6, 2020 6:37 AM
To: Frey, Fred (ext ???) <f.frey at>
Cc: xenomai at
Subject: Re: Assigning Interrupt Handlers

Frey, Fred (ext ???) via Xenomai <xenomai at> writes:

> Hello all,
> I'd like some guidance on the topic of setting up interrupt handlers to work with Xenomai.
> Platform: Debian Buster on AM335x Arm (Beaglebone Black) Xenomai 
> version: 3.0.10 `uname -r` : 4.14.108-ti-xenomai-r135
> Specifically, I'd like to set up a function to run every time the PRU generates an interrupt that I've defined.
> I'm a little confused on what functionality is actually provided here. 
> Reading the docs I easily can find the 'rtdm_irq_request()'
> function which looks like exactly what I need.

This is indeed what you need to register an in-kernel handler for the IRQ, called from a (mini-)driver.

> However, when looking through the header files I have, I can't find 
> any mention of this function. Looking through some old mailing list posts, I gathered that this function was actually only callable from the kernel context. So I guess my question is three-fold:
>   1.  Is it possible for me to register an interrupt handler from
>   userspace?

No, there is no direct support for this, on purpose.

>   2.  If not, is the prescribed method of doing this to write a device
>   driver?


>   3.  If I have to write a device driver for the PRU, would my  
> interrupt handler have to live inside of my device driver, or would I 
> be able to register
> a function inside of my client program to be an interrupt handler?

The interrupt handler would definitely have to live in your device driver. That driver could be very simple implementation-wise: it would register a handler for the interrupt, sending wake up events upon IRQ receipt to any task blocked on a synchronization event shared between the handler and those tasks, e.g. a semaphore or an event flag depending on the semantics you need.

So, in kernel space you could have a so-called "named" device driver implementing the IRQ handler, which would also define some IOCIRQWAIT ioctl request which the app in user-space could invoke to wait for the next event (from primary mode):

        rtdm_event_init(&event, 0);
        rtdm_irq_request(..., irq, irq_handler, ...);


driver_ioctl_rt(..., cmd=IOCIRQWAIT, ...):

A driver for a named device in Xenomai's lingo exports a character-based interface to certain device(s), with the device nodes appearing in the /dev/rtdm hierarchy. In user-space, the app would have to open() the device node in /dev/rtdm exposed by the mini-driver, then issue ioctl(fd, IOCIRQWAIT) requests in order to synchronize on IRQ receipt:

        int fd, ret;

        fd = open("/dev/rtdm/some_device", O_RDONLY);

        for (;;) {
            ret = ioctl(fd, IOCIRQWAIT);
            if (ret)
                    error(1, errno, "oops");
            ... process next IRQ event ...

(the libcobalt implementation of open() and ioctl() would have to be called by the application, not glibc's).

The illustration above is obviously very sketchy, but the basics are presented.

There is also the option of using the UDD driver, which is Xenomai's version of UIO, offering a generic interface for mapping device memory and synchronizing on IRQ events to applications. UDD hosts mini-drivers users provide on top, hiding the nitty-gritty details of device creation, memory mapping and more. It provides a unified interface to applications for accessing the features.

The UDD documentation is terse, but you may want to refer to this post to get started with UDD:


More information about the Xenomai mailing list