All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tomas Kalibera <kalibera@domain.hid>
To: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
Cc: xenomai@xenomai.org
Subject: Re: [Xenomai-help] waiting for multiple hardware interrupts
Date: Sat, 12 Apr 2008 12:08:36 -0400	[thread overview]
Message-ID: <4800DE84.5040200@domain.hid> (raw)
In-Reply-To: <18432.49619.109362.265306@domain.hid>

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



  reply	other threads:[~2008-04-12 16:08 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4800DE84.5040200@domain.hid \
    --to=kalibera@domain.hid \
    --cc=gilles.chanteperdrix@xenomai.org \
    --cc=xenomai@xenomai.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.