* [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.