Experimental Physics and Industrial Control System
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
<2005>
2006
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
<2005>
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024