EPICS Home

Experimental Physics and Industrial Control System


 
1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE:counting semaphore for 3.14.x
From: Kate Feng <[email protected]>
To: [email protected]
Date: Thu, 13 Jan 2005 13:20:48 -0500
A  while ago,  Kate Feng wrote :

>The drvIK320.c  for the  Heidenhain IK320 encoder posted in
> the http://www.aps.anl.gov/aod/bcda/synApps/index.php
> required the counting semaphore.

Many thanks to people who made suggestions offline
regarding the counting semaphore.   Now, the driver for IK320
encoder  is ported  to our RTEMS  application. The original author
of the IK320 encoder  wrote:

>The counting semaphore keeps track of outstanding
>jobs on the IK320 card, letting the IOC wait for the last
>axis on the IK to finish.

Since we have hardware  setup for only one axis,  we  think it's
safe to use the counting semaphore  for outstanding jobs
in case of multiple axes.  I did not find official  document
regarding  the  implementation of the counting semaphore.
To make life easier,  I  follow  the document of vxWorks and
RTEMS and the source code of EPICS.   To one's
consideration/reference,  attached  at  the end is the
implementation  of the counting semaphore I  tested for the  IK320
encoders.  It is almost  identical  to  the code of RTEMS/osdEvent.c
except for that the   "RTEMS_SIMPLE_BINARY_SEMAPHORE"
is replaced by  "RTEMS_COUNTING_SEMAPHORE".


Perhaps, to  one's interest,  I listed  the  various suggestions I got
for the usage of the counting semaphore for the IK320 encoder.

1.  the counting semaphore could be replaced  by the binary
semaphore  (e.g. epicsEvent) .
2.  the  counting semaphore could be replaced by the
message semaphore  (e.g. epicsMessage).
3. the counting semaphore is a nice primitive to be implemented.


Thanks again,
Kate


/*
 * Create a counting semaphore
 */
rtems_id epicsCountCreate(int initialState)
{
    rtems_status_code sc;
    rtems_id sid;
    rtems_interrupt_level level;
    static char c1 = 'a';
    static char c2 = 'a';
    static char c3 = 'a';

    sc = rtems_semaphore_create (rtems_build_name ('B', c3, c2, c1),
        initialState,
 RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE |
     RTEMS_NO_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
        0,
        &sid);
    if (sc != RTEMS_SUCCESSFUL) {
        errlogPrintf ("Can't create binary semaphore: %s\n",
rtems_status_text (sc));
        return 0;
    }
    rtems_interrupt_disable (level);
    if (c1 == 'z') {
        if (c2 == 'z') {
            if (c3 == 'z') {
                c3 = 'a';
            }
            else {
                c3++;
            }
            c2 = 'a';
        }
        else {
            c2++;
        }
        c1 = 'a';
    }
    else {
        c1++;
    }
    rtems_interrupt_enable (level);
    return sid;
}

void epicsCountDestroy(rtems_id id)
{
    rtems_status_code sc;

    sc = rtems_semaphore_delete(id);
    if (sc != RTEMS_SUCCESSFUL)
       printf("Can't destroy semaphore: %s\n", rtems_status_text (sc));
}

void
epicsCountSignal(rtems_id id)
{
    rtems_status_code sc;

    sc = rtems_semaphore_release (id);
    if (sc != RTEMS_SUCCESSFUL)
        printf("Can't release semaphore: %s\n", rtems_status_text (sc));

}

int epicsCountWait(rtems_id id)
{
    rtems_status_code sc;

    sc = rtems_semaphore_obtain (id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    if (sc != RTEMS_SUCCESSFUL)
        return ERROR;
    return OK;
}

int epicsCountWaitWithTimeout(rtems_id id, double timeOut)
{
    rtems_status_code sc;
    rtems_unsigned32 wait;
    rtems_interval delay;
    extern double rtemsTicksPerSecond_double;

    if (timeOut <= 0.0) {
        wait = RTEMS_NO_WAIT;
        delay = 0;
    }
    else {
        wait = RTEMS_WAIT;
        delay = timeOut * rtemsTicksPerSecond_double;
        if (delay == 0)
            delay++;
    }
    sc = rtems_semaphore_obtain (id, wait, delay);
    if (sc == RTEMS_SUCCESSFUL)
        return 0;
    else if (sc == RTEMS_TIMEOUT)
        return -2;
    else
        return -1;
}





Navigate by Date:
Prev: CA links and EPICS Records user routines Andy Foster
Next: MSVCPRT.LIB bharoto
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: CA links and EPICS Records user routines Ralph Lange
Next: MSVCPRT.LIB bharoto
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024