* [Xenomai-help] waiting for multiple hardware interrupts
@ 2008-04-11 19:11 Tomas Kalibera
2008-04-12 14:06 ` Gilles Chanteperdrix
0 siblings, 1 reply; 7+ messages in thread
From: Tomas Kalibera @ 2008-04-11 19:11 UTC (permalink / raw)
To: xenomai
Hi,
is it possible, in user-space, to wait for a set of hardware interrupts
? Something like UNIX select, which allows to wait for multiple devices
to become ready...
Or do I need to spawn a dedicated thread for each interrupt to wait for ?
Thanks,
Tomas
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Xenomai-help] waiting for multiple hardware interrupts
2008-04-11 19:11 [Xenomai-help] waiting for multiple hardware interrupts Tomas Kalibera
@ 2008-04-12 14:06 ` Gilles Chanteperdrix
2008-04-12 16:08 ` Tomas Kalibera
2008-04-15 14:45 ` [Xenomai-help] xeno_16550A and multiple channels Anders Blomdell
0 siblings, 2 replies; 7+ messages in thread
From: Gilles Chanteperdrix @ 2008-04-12 14:06 UTC (permalink / raw)
To: Tomas Kalibera; +Cc: xenomai
Tomas Kalibera wrote:
> Hi,
>
> is it possible, in user-space, to wait for a set of hardware interrupts
> ? Something like UNIX select, which allows to wait for multiple devices
> to become ready...
>
> Or do I need to spawn a dedicated thread for each interrupt to wait for ?
There are two answers to this question: if you use the native skin
services, and/or the various interrupt you want to wait for belongs to
the same driver, you may use the native skin event flags services. Each
interrupt handler would call rt_event_signal to signal a different bit
in the rt_event object, and you would wait for events with the
rt_event_wait service.
But Xenomai also has a select service (for now, only the posix skin
proposes this service), which looks more adapted if each interrupt
handler belongs to a different driver. If you want to use it, you will
have to implement a select_bind callback for each RTDM driver you want
to select from. For instance, if an RTDM driver looks like:
typedef struct mydriver_context {
/* ... */
rtdm_sem_t pending_sem;
/* ... */
} mydriver_context_t;
int mydriver_irq_handler(rtdm_irq_t *irq)
{
mydriver_context_t *context = /* ... */
rtdm_sem_up(&context->pending_sem);
/* ... */
}
ssize_t mydriver_read(struct rtdm_dev_context *context,
rtdm_user_info_t *user_info,
void *buf, size_t nbyte)
{
/* ... */
mydriver_context_t *mydriver_context =
(mydriver_context_t *)&context->dev_private;
int err;
/* ... */
err = rtdm_sem_down(&mydriver_context->pending_sem);
/* ... */
}
static struct rtdm_device mydriver_device {
/* ... */
.ops = {
/* ... */
.read_rt = mydriver_read;
/* ...*/
};
static int __init mydriver_init(void)
{
int err = rtdm_dev_register(&mydriver_device);
/* ... */
}
All you have to do is to write:
int mydriver_select_bind(struct rtdm_dev_context *context,
struct xnselector *selector,
unsigned type,
unsigned index)
{
mydriver_context_t *mydriver_context =
(mydriver_context_t *)&context->dev_private;
int err;
if (type == RTDM_SELECTTYPE_READ)
err = rtdm_sem_select_bind(&mydriver_context->pending_sem,
selector, type, index);
else
err = -EBADF;
return err;
}
And add in mydriver_device declaration:
static struct rtdm_device mydriver_device {
/* ... */
.ops = {
/* ... */
.select_bind = mydriver_select_bind;
/* ...*/
};
You do not have to worry very much about the performance of the
mydriver_select_bind callback: contrarily to what happens with a Linux
driver, it will be called only the first time mydriver's file descriptor
is passed to select, after that, select does all the housekeeping (the
select block gets updated by each call to rtdm_sem_up and rtdm_sem_down).
I took rtdm_sem_t as an example, but rtdm_event_t also has builtin
support for (there is an rtdm_event_select_bind service that can be
called in the implementation of a driver's select_bind callback).
Also note this scheme works well if a driver signals a semaphore (or
event) whether there is a pending reader or not, as showed in the
example. For instance, adapting Xenomai serial driver to select would be
a bit more complicated, because the driver only signals an event if
there is a pending reader, whereas we want the select block to be
updated even when there is no thread blocked in the select service.
--
Gilles.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Xenomai-help] waiting for multiple hardware interrupts
2008-04-12 14:06 ` Gilles Chanteperdrix
@ 2008-04-12 16:08 ` Tomas Kalibera
2008-04-12 17:05 ` Gilles Chanteperdrix
2008-04-15 14:45 ` [Xenomai-help] xeno_16550A and multiple channels Anders Blomdell
1 sibling, 1 reply; 7+ messages in thread
From: Tomas Kalibera @ 2008-04-12 16:08 UTC (permalink / raw)
To: Gilles Chanteperdrix; +Cc: xenomai
Hi Gilles,
thank you for the info. I have additional question: Is it possible to
wait for multiple interrupts without specific kernel support (RTDM
driver or kernel-space IRQ handlers or anything) ? I see that without
kernel support, in native skin, one can in user-space wait for a
specific hardware interrupt using "rt_intr_wait". I need to wait for
multiple interrupts in user space. Do I have to create a dedicated
thread to wait for each interrupt ?
Thanks,
Tomas
Gilles Chanteperdrix wrote:
> Tomas Kalibera wrote:
> > Hi,
> >
> > is it possible, in user-space, to wait for a set of hardware interrupts
> > ? Something like UNIX select, which allows to wait for multiple devices
> > to become ready...
> >
> > Or do I need to spawn a dedicated thread for each interrupt to wait for ?
>
> There are two answers to this question: if you use the native skin
> services, and/or the various interrupt you want to wait for belongs to
> the same driver, you may use the native skin event flags services. Each
> interrupt handler would call rt_event_signal to signal a different bit
> in the rt_event object, and you would wait for events with the
> rt_event_wait service.
>
> But Xenomai also has a select service (for now, only the posix skin
> proposes this service), which looks more adapted if each interrupt
> handler belongs to a different driver. If you want to use it, you will
> have to implement a select_bind callback for each RTDM driver you want
> to select from. For instance, if an RTDM driver looks like:
>
> typedef struct mydriver_context {
> /* ... */
> rtdm_sem_t pending_sem;
> /* ... */
> } mydriver_context_t;
>
> int mydriver_irq_handler(rtdm_irq_t *irq)
> {
> mydriver_context_t *context = /* ... */
>
> rtdm_sem_up(&context->pending_sem);
>
> /* ... */
> }
>
> ssize_t mydriver_read(struct rtdm_dev_context *context,
> rtdm_user_info_t *user_info,
> void *buf, size_t nbyte)
> {
> /* ... */
> mydriver_context_t *mydriver_context =
> (mydriver_context_t *)&context->dev_private;
> int err;
>
> /* ... */
>
> err = rtdm_sem_down(&mydriver_context->pending_sem);
>
> /* ... */
> }
>
> static struct rtdm_device mydriver_device {
> /* ... */
>
> .ops = {
> /* ... */
> .read_rt = mydriver_read;
>
> /* ...*/
> };
>
> static int __init mydriver_init(void)
> {
> int err = rtdm_dev_register(&mydriver_device);
> /* ... */
> }
>
> All you have to do is to write:
> int mydriver_select_bind(struct rtdm_dev_context *context,
> struct xnselector *selector,
> unsigned type,
> unsigned index)
> {
> mydriver_context_t *mydriver_context =
> (mydriver_context_t *)&context->dev_private;
> int err;
>
> if (type == RTDM_SELECTTYPE_READ)
> err = rtdm_sem_select_bind(&mydriver_context->pending_sem,
> selector, type, index);
> else
> err = -EBADF;
>
> return err;
> }
>
> And add in mydriver_device declaration:
>
> static struct rtdm_device mydriver_device {
> /* ... */
>
> .ops = {
> /* ... */
> .select_bind = mydriver_select_bind;
>
> /* ...*/
> };
>
> You do not have to worry very much about the performance of the
> mydriver_select_bind callback: contrarily to what happens with a Linux
> driver, it will be called only the first time mydriver's file descriptor
> is passed to select, after that, select does all the housekeeping (the
> select block gets updated by each call to rtdm_sem_up and rtdm_sem_down).
>
> I took rtdm_sem_t as an example, but rtdm_event_t also has builtin
> support for (there is an rtdm_event_select_bind service that can be
> called in the implementation of a driver's select_bind callback).
>
> Also note this scheme works well if a driver signals a semaphore (or
> event) whether there is a pending reader or not, as showed in the
> example. For instance, adapting Xenomai serial driver to select would be
> a bit more complicated, because the driver only signals an event if
> there is a pending reader, whereas we want the select block to be
> updated even when there is no thread blocked in the select service.
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Xenomai-help] waiting for multiple hardware interrupts
2008-04-12 16:08 ` Tomas Kalibera
@ 2008-04-12 17:05 ` Gilles Chanteperdrix
0 siblings, 0 replies; 7+ messages in thread
From: Gilles Chanteperdrix @ 2008-04-12 17:05 UTC (permalink / raw)
To: Tomas Kalibera; +Cc: xenomai
Tomas Kalibera wrote:
> Hi Gilles,
>
> thank you for the info. I have additional question: Is it possible to
> wait for multiple interrupts without specific kernel support (RTDM
> driver or kernel-space IRQ handlers or anything) ? I see that without
> kernel support, in native skin, one can in user-space wait for a
> specific hardware interrupt using "rt_intr_wait". I need to wait for
> multiple interrupts in user space. Do I have to create a dedicated
> thread to wait for each interrupt ?
No, there is currently no Xenomai features to allow you to wait for
multiple interrupts from a unique user-space thread without a kernel
module. That said, the rt_event solution could be implemented with
a really minimal kernel module.
--
Gilles.
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Xenomai-help] xeno_16550A and multiple channels
2008-04-12 14:06 ` Gilles Chanteperdrix
2008-04-12 16:08 ` Tomas Kalibera
@ 2008-04-15 14:45 ` Anders Blomdell
2008-04-15 15:14 ` Jan Kiszka
1 sibling, 1 reply; 7+ messages in thread
From: Anders Blomdell @ 2008-04-15 14:45 UTC (permalink / raw)
To: xenomai-help
With a PCI multiport I/O-card, configured with:
modprobe xeno_16550A.ko io=0xd400,0xd080 irq=5,5
I can't get cross-link to work. This is what I get:
main : write-file opened
main : write-config written
main : can't open rtser1 (read), Device or resource busy
main : rtser0 (write) -> closed
The reason is that the second call (xeno_16550A.c) to:
err = rtdm_irq_request(&ctx->irq_handle, irq[dev_id],
rt_16550_interrupt,
RTDM_IRQTYPE_SHARED | RTDM_IRQTYPE_EDGE,
context->device->proc_name, ctx);
returns -16.
This somehow makes sense since rtser0 and rtser1 uses the same interrupt, but
having multiple channels sharing the same interrupt seems to be a valid usecase
according to http://www.xenomai.org/index.php/16550A.
Kernel version is 2.6.24.3 and Xenomai version is 2.4.2.
Any ideas of what might be wrong?
/Anders
--
Anders Blomdell Email: anders.blomdell@domain.hid
Department of Automatic Control
Lund University Phone: +46 46 222 4625
P.O. Box 118 Fax: +46 46 138118
SE-221 00 Lund, Sweden
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Xenomai-help] xeno_16550A and multiple channels
2008-04-15 14:45 ` [Xenomai-help] xeno_16550A and multiple channels Anders Blomdell
@ 2008-04-15 15:14 ` Jan Kiszka
2008-04-15 17:23 ` Anders Blomdell
0 siblings, 1 reply; 7+ messages in thread
From: Jan Kiszka @ 2008-04-15 15:14 UTC (permalink / raw)
To: Anders Blomdell; +Cc: xenomai-help
Anders Blomdell wrote:
> With a PCI multiport I/O-card, configured with:
>
> modprobe xeno_16550A.ko io=0xd400,0xd080 irq=5,5
>
> I can't get cross-link to work. This is what I get:
>
> main : write-file opened
> main : write-config written
> main : can't open rtser1 (read), Device or resource busy
> main : rtser0 (write) -> closed
>
> The reason is that the second call (xeno_16550A.c) to:
>
> err = rtdm_irq_request(&ctx->irq_handle, irq[dev_id],
> rt_16550_interrupt,
> RTDM_IRQTYPE_SHARED | RTDM_IRQTYPE_EDGE,
> context->device->proc_name, ctx);
>
> returns -16.
>
> This somehow makes sense since rtser0 and rtser1 uses the same interrupt, but
> having multiple channels sharing the same interrupt seems to be a valid usecase
> according to http://www.xenomai.org/index.php/16550A.
>
> Kernel version is 2.6.24.3 and Xenomai version is 2.4.2.
>
> Any ideas of what might be wrong?
CONFIG_XENO_OPT_SHIRQ?
Jan
--
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Xenomai-help] xeno_16550A and multiple channels
2008-04-15 15:14 ` Jan Kiszka
@ 2008-04-15 17:23 ` Anders Blomdell
0 siblings, 0 replies; 7+ messages in thread
From: Anders Blomdell @ 2008-04-15 17:23 UTC (permalink / raw)
To: Jan Kiszka; +Cc: xenomai-help
Jan Kiszka wrote:
> Anders Blomdell wrote:
>> With a PCI multiport I/O-card, configured with:
>>
>> modprobe xeno_16550A.ko io=0xd400,0xd080 irq=5,5
>>
>> I can't get cross-link to work. This is what I get:
>>
>> main : write-file opened
>> main : write-config written
>> main : can't open rtser1 (read), Device or resource busy
>> main : rtser0 (write) -> closed
>>
>> The reason is that the second call (xeno_16550A.c) to:
>>
>> err = rtdm_irq_request(&ctx->irq_handle, irq[dev_id],
>> rt_16550_interrupt,
>> RTDM_IRQTYPE_SHARED | RTDM_IRQTYPE_EDGE,
>> context->device->proc_name, ctx);
>>
>> returns -16.
>>
>> This somehow makes sense since rtser0 and rtser1 uses the same interrupt, but
>> having multiple channels sharing the same interrupt seems to be a valid usecase
>> according to http://www.xenomai.org/index.php/16550A.
>>
>> Kernel version is 2.6.24.3 and Xenomai version is 2.4.2.
>>
>> Any ideas of what might be wrong?
>
> CONFIG_XENO_OPT_SHIRQ?
Right, I had forgot to set:
CONFIG_XENO_OPT_SHIRQ=y
How about a printk to warn if it's not enabled?
static inline int xnintr_irq_attach(xnintr_t *intr)
{
if (intr->flags & XN_ISR_SHARED) {
printk(KERN_WARNING "CONFIG_XENO_OPT_SHIRQ not set\n")
}
return xnarch_hook_irq(intr->irq, &xnintr_irq_handler, intr->iack, intr);
}
To give bummers like me a hint of what might be wrong.
Thanks
Anders
--
Anders Blomdell Email: anders.blomdell@domain.hid
Department of Automatic Control
Lund University Phone: +46 46 222 4625
P.O. Box 118 Fax: +46 46 138118
SE-221 00 Lund, Sweden
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2008-04-15 17:23 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-11 19:11 [Xenomai-help] waiting for multiple hardware interrupts Tomas Kalibera
2008-04-12 14:06 ` Gilles Chanteperdrix
2008-04-12 16:08 ` Tomas Kalibera
2008-04-12 17:05 ` Gilles Chanteperdrix
2008-04-15 14:45 ` [Xenomai-help] xeno_16550A and multiple channels Anders Blomdell
2008-04-15 15:14 ` Jan Kiszka
2008-04-15 17:23 ` Anders Blomdell
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.