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

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.


  reply	other threads:[~2008-04-12 14:06 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 [this message]
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

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=18432.49619.109362.265306@domain.hid \
    --to=gilles.chanteperdrix@xenomai.org \
    --cc=kalibera@domain.hid \
    --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.