- Connections write timeouts were incorrectly handled in asynnetc. Fixed.
- Implemented the desired run/drive behaviour: drive waits for what it started run starts, and success waits for everything to finish. This required changes to a lot of files. - Fixed a bug in remob which supressed required messages
This commit is contained in:
@ -59,7 +59,8 @@ static int ReplacementCheckStatus(void *pData, SConnection * pCon)
|
|||||||
if (myCollider->isDirty == 1) {
|
if (myCollider->isDirty == 1) {
|
||||||
myCollider->isDirty = 0;
|
myCollider->isDirty = 0;
|
||||||
StartDevice(pServ->pExecutor,
|
StartDevice(pServ->pExecutor,
|
||||||
"anticollider", myCollider->pDes, myCollider, pCon, 77.77);
|
"anticollider", myCollider->pDes, myCollider,
|
||||||
|
pCon,pCon->runLevel, 77.77);
|
||||||
return HWIdle;
|
return HWIdle;
|
||||||
} else {
|
} else {
|
||||||
return HWIdle;
|
return HWIdle;
|
||||||
|
68
asynnet.c
68
asynnet.c
@ -42,7 +42,7 @@
|
|||||||
#define DATASOCKET 1
|
#define DATASOCKET 1
|
||||||
#define MAXCONNECTIONS 1024
|
#define MAXCONNECTIONS 1024
|
||||||
#define RBUFFERSIZE 262144 /* 256kb */
|
#define RBUFFERSIZE 262144 /* 256kb */
|
||||||
#define WBUFFERSIZE 2*262144 /* 512kb */
|
#define WBUFFERSIZE 4*262144 /* 512kb */
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int socket;
|
int socket;
|
||||||
@ -233,8 +233,8 @@ int ANETconnect(char *name, int iPort)
|
|||||||
}
|
}
|
||||||
memset(&addresse, 0, sizeof(struct sockaddr_in));
|
memset(&addresse, 0, sizeof(struct sockaddr_in));
|
||||||
addresse.sin_family = AF_INET;
|
addresse.sin_family = AF_INET;
|
||||||
addresse.sin_port = iPort;
|
addresse.sin_port = htons((unsigned short)(iPort &0xFFFF));
|
||||||
addresse.sin_addr = addr;
|
addresse.sin_addr.s_addr = addr.s_addr;
|
||||||
socke = socket(AF_INET, SOCK_STREAM, 0);
|
socke = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
status = connect(socke, (struct sockaddr *) &addresse,
|
status = connect(socke, (struct sockaddr *) &addresse,
|
||||||
sizeof(struct sockaddr_in));
|
sizeof(struct sockaddr_in));
|
||||||
@ -281,12 +281,11 @@ static int anetWrite(SocketDescriptor con)
|
|||||||
int status, length;
|
int status, length;
|
||||||
void *pPtr;
|
void *pPtr;
|
||||||
|
|
||||||
con.lastOpenForWrite = time(NULL);
|
|
||||||
pPtr = GetRWBufferData(con.writeBuffer, &length);
|
pPtr = GetRWBufferData(con.writeBuffer, &length);
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
status = send(con.socket, pPtr, length, 0);
|
status = send(con.socket, pPtr, length, 0);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
if (errno == EAGAIN) {
|
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
ANETclose(con.handle);
|
ANETclose(con.handle);
|
||||||
@ -296,7 +295,39 @@ static int anetWrite(SocketDescriptor con)
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
* I have seen that select did not report the write possibility set,
|
||||||
|
* though the send buffer was empty. Thus I try to write if data is there
|
||||||
|
* and leave the lastOpenForWrite flag only when the socket would block
|
||||||
|
* on write.
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
static int anetTestWrite(SocketDescriptor con)
|
||||||
|
{
|
||||||
|
int status, length;
|
||||||
|
void *pPtr;
|
||||||
|
time_t lastTime;
|
||||||
|
|
||||||
|
if(con.type != DATASOCKET){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastTime = con.lastOpenForWrite;
|
||||||
|
con.lastOpenForWrite = time(NULL);
|
||||||
|
pPtr = GetRWBufferData(con.writeBuffer, &length);
|
||||||
|
if (length > 0) {
|
||||||
|
status = send(con.socket, pPtr, length, 0);
|
||||||
|
if (status < 0) {
|
||||||
|
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
|
||||||
|
con.lastOpenForWrite = lastTime;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ANETclose(con.handle);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
RemoveRWBufferData(con.writeBuffer, status);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static int anetRead(SocketDescriptor con)
|
static int anetRead(SocketDescriptor con)
|
||||||
{
|
{
|
||||||
@ -354,7 +385,7 @@ static int anetRead(SocketDescriptor con)
|
|||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void ANETprocess(void)
|
void ANETprocess(void)
|
||||||
{
|
{
|
||||||
int i, status, count = 0, socke = 0;
|
int i, status, count = 0, socke = 0, length;
|
||||||
fd_set readMask, writeMask;
|
fd_set readMask, writeMask;
|
||||||
struct timeval tmo = { 0, 10 };
|
struct timeval tmo = { 0, 10 };
|
||||||
|
|
||||||
@ -378,7 +409,7 @@ void ANETprocess(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* I always jump out of this loop when a socket is created or closed
|
* I always jump out of this loop when a socket is created or closed
|
||||||
* because then the order in the connections array is no longer valid.
|
* because then the order in the connections array is no longer valid.
|
||||||
* Try again the next time round.
|
* Try again the next time round.
|
||||||
@ -386,21 +417,30 @@ void ANETprocess(void)
|
|||||||
for (i = 0; i < noConnections; i++) {
|
for (i = 0; i < noConnections; i++) {
|
||||||
socke = connections[i].socket;
|
socke = connections[i].socket;
|
||||||
if (FD_ISSET(socke, &readMask)) {
|
if (FD_ISSET(socke, &readMask)) {
|
||||||
if (!anetRead(connections[i])) {
|
if (anetRead(connections[i]) == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (FD_ISSET(socke, &writeMask)) {
|
if (FD_ISSET(socke, &writeMask)) {
|
||||||
if (!anetWrite(connections[i])) {
|
/*
|
||||||
|
* This has to be here, as I found out tracing a subtle bug:
|
||||||
|
* If the time is set in writeANET the modification will not
|
||||||
|
* propagate into the array as C copies the structure for the function call.
|
||||||
|
*/
|
||||||
|
connections[i].lastOpenForWrite = time(NULL);
|
||||||
|
if (anetWrite(connections[i]) == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* if I could not write to the socket for three minutes,
|
* If I could not write to the socket for 5 minutes,
|
||||||
* the socket is considered broken and is closed
|
* the socket is considered broken and is closed.
|
||||||
*/
|
*/
|
||||||
if (time(NULL) > connections[i].lastOpenForWrite + 180 &&
|
if (time(NULL) > connections[i].lastOpenForWrite + 300 &&
|
||||||
connections[i].type == DATASOCKET) {
|
connections[i].type == DATASOCKET) {
|
||||||
|
GetRWBufferData(connections[i].writeBuffer, &length);
|
||||||
|
anetLog(ANETCON, "Closing socket because of time overrun: %d, delay = %d, bytes to be written = %d, write bit = %d\n", connections[i].socket,
|
||||||
|
(int)(time(NULL) - connections[i].lastOpenForWrite), length, FD_ISSET(connections[i].socket, &writeMask) );
|
||||||
ANETclose(connections[i].handle);
|
ANETclose(connections[i].handle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -467,8 +507,8 @@ int ANETwrite(int handle, void *buffer, int count)
|
|||||||
status = StoreRWBuffer(con->writeBuffer, buffer, count);
|
status = StoreRWBuffer(con->writeBuffer, buffer, count);
|
||||||
}
|
}
|
||||||
if (status != 1) {
|
if (status != 1) {
|
||||||
anetLog(ANETERROR, "write buffer overrun on handle %d, socket %d",
|
anetLog(ANETERROR, "Write buffer overrun on handle %d, socket %d, trying to write %d bytes",
|
||||||
con->handle, con->socket);
|
con->handle, con->socket, count);
|
||||||
return ANETWRITEBUFFERFULL;
|
return ANETWRITEBUFFERFULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
5
conman.c
5
conman.c
@ -198,7 +198,8 @@ static SConnection *CreateConnection(SicsInterp * pSics)
|
|||||||
pRes->listening = 0;
|
pRes->listening = 0;
|
||||||
pRes->conStart = time(NULL);
|
pRes->conStart = time(NULL);
|
||||||
pRes->write = SCNormalWrite;
|
pRes->write = SCNormalWrite;
|
||||||
|
pRes->runLevel = RUNDRIVE;
|
||||||
|
|
||||||
/* initialise context variables */
|
/* initialise context variables */
|
||||||
pRes->iCmdCtr = 0;
|
pRes->iCmdCtr = 0;
|
||||||
pRes->conEventType = -1;
|
pRes->conEventType = -1;
|
||||||
@ -425,6 +426,7 @@ SConnection *SCCopyConnection(SConnection * pCon)
|
|||||||
result->conStart = pCon->conStart;
|
result->conStart = pCon->conStart;
|
||||||
result->contextStack = -1;
|
result->contextStack = -1;
|
||||||
result->iList = -1;
|
result->iList = -1;
|
||||||
|
result->runLevel = pCon->runLevel;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -847,7 +849,6 @@ int SCWriteWithOutcode(SConnection * self, char *buffer, int iOut)
|
|||||||
free(bufPtr);
|
free(bufPtr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static int SCBufferWrite(SConnection * self, char *buffer, int iOut)
|
static int SCBufferWrite(SConnection * self, char *buffer, int iOut)
|
||||||
{
|
{
|
||||||
|
1
conman.h
1
conman.h
@ -54,6 +54,7 @@ typedef struct __SConnection {
|
|||||||
int transID; /* transaction ID */
|
int transID; /* transaction ID */
|
||||||
char deviceID[256]; /* transaction device ID */
|
char deviceID[256]; /* transaction device ID */
|
||||||
int iUserRights; /* user rights of the connection */
|
int iUserRights; /* user rights of the connection */
|
||||||
|
int runLevel; /* run level, either RUNRUN for asynchronous or RUNDRIVE for synchronous */
|
||||||
|
|
||||||
/* master connection object fields */
|
/* master connection object fields */
|
||||||
int iList; /* callback registry, may go? */
|
int iList; /* callback registry, may go? */
|
||||||
|
13
counter.c
13
counter.c
@ -115,7 +115,7 @@ static int StartCount(void *pData, SConnection * pCon)
|
|||||||
} else {
|
} else {
|
||||||
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
|
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
|
||||||
sprintf(pBueffel, "WARNING: %s ", pError);
|
sprintf(pBueffel, "WARNING: %s ", pError);
|
||||||
SCWrite(pCon, pBueffel, eError);
|
SCWrite(pCon, pBueffel, eLog);
|
||||||
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
|
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
|
||||||
if (iRet == COTERM) {
|
if (iRet == COTERM) {
|
||||||
SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting",
|
SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting",
|
||||||
@ -226,7 +226,7 @@ static int CheckCountStatus(void *pData, SConnection * pCon)
|
|||||||
self->badStatusCount++;
|
self->badStatusCount++;
|
||||||
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
|
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
|
||||||
sprintf(pBueffel, "WARNING: %s ", pError);
|
sprintf(pBueffel, "WARNING: %s ", pError);
|
||||||
SCWrite(pCon, pBueffel, eError);
|
SCWrite(pCon, pBueffel, eLog);
|
||||||
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
|
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
|
||||||
if (iRet == COTERM || self->badStatusCount > 3) {
|
if (iRet == COTERM || self->badStatusCount > 3) {
|
||||||
SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting", eError);
|
SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting", eError);
|
||||||
@ -373,7 +373,7 @@ void DeleteCounter(void *pData)
|
|||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
int DoCount(pCounter self, float fPreset, SConnection * pCon, int iBlock)
|
int DoCount(pCounter self, float fPreset, SConnection * pCon, int iBlock)
|
||||||
{
|
{
|
||||||
int iRet;
|
int iRet, level;
|
||||||
char pBueffel[132];
|
char pBueffel[132];
|
||||||
Status eOld;
|
Status eOld;
|
||||||
|
|
||||||
@ -392,8 +392,13 @@ int DoCount(pCounter self, float fPreset, SConnection * pCon, int iBlock)
|
|||||||
/* set Preset */
|
/* set Preset */
|
||||||
SetCounterPreset(self, fPreset);
|
SetCounterPreset(self, fPreset);
|
||||||
|
|
||||||
|
if(iBlock){
|
||||||
|
level = RUNDRIVE;
|
||||||
|
} else {
|
||||||
|
level = RUNRUN;
|
||||||
|
}
|
||||||
iRet = StartDevice(GetExecutor(), self->name, self->pDes, self, pCon,
|
iRet = StartDevice(GetExecutor(), self->name, self->pDes, self, pCon,
|
||||||
fPreset);
|
level, fPreset);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
SetStatus(eOld);
|
SetStatus(eOld);
|
||||||
SCWrite(pCon, "Counting aborted", eError);
|
SCWrite(pCon, "Counting aborted", eError);
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
Mark Koennecke, January 1996
|
Mark Koennecke, January 1996
|
||||||
|
|
||||||
copyright: see implementation file.
|
copyright: see implementation file.
|
||||||
|
|
||||||
|
Massively reworked to accomodate second generation counter objects.
|
||||||
|
|
||||||
|
Mark Koennecke, January 2009
|
||||||
----------------------------------------------------------------------------*/
|
----------------------------------------------------------------------------*/
|
||||||
#ifndef SICSCOUNTER
|
#ifndef SICSCOUNTER
|
||||||
#define SICSCOUNTER
|
#define SICSCOUNTER
|
||||||
@ -25,6 +29,7 @@ typedef struct __Counter{
|
|||||||
unsigned long tStart;
|
unsigned long tStart;
|
||||||
int iCallbackCounter;
|
int iCallbackCounter;
|
||||||
int badStatusCount;
|
int badStatusCount;
|
||||||
|
int haltFixFlag; /* solely here to prevent multiple calls to the halt function on overrun timers in countersec.c*/
|
||||||
int (*setMode)(struct __Counter *self, CounterMode eMode);
|
int (*setMode)(struct __Counter *self, CounterMode eMode);
|
||||||
CounterMode (*getMode)(struct __Counter *self);
|
CounterMode (*getMode)(struct __Counter *self);
|
||||||
int (*getNMonitor)(struct __Counter *self);
|
int (*getNMonitor)(struct __Counter *self);
|
||||||
|
33
countersec.c
33
countersec.c
@ -61,6 +61,7 @@ static int SecStartCount(void *pData, SConnection *pCon)
|
|||||||
}
|
}
|
||||||
|
|
||||||
status = SecCtrInvokeFunction(self,pCon, START);
|
status = SecCtrInvokeFunction(self,pCon, START);
|
||||||
|
self->haltFixFlag = 0;
|
||||||
if(status == 1){
|
if(status == 1){
|
||||||
self->isUpToDate = 0;
|
self->isUpToDate = 0;
|
||||||
self->badStatusCount = 0;
|
self->badStatusCount = 0;
|
||||||
@ -68,6 +69,13 @@ static int SecStartCount(void *pData, SConnection *pCon)
|
|||||||
node = GetHipadabaNode(self->pDes->parNode, "status");
|
node = GetHipadabaNode(self->pDes->parNode, "status");
|
||||||
UpdateHipadabaPar(node,MakeHdbText("run"), pCon);
|
UpdateHipadabaPar(node,MakeHdbText("run"), pCon);
|
||||||
SetHdbProperty(node,"geterror", NULL);
|
SetHdbProperty(node,"geterror", NULL);
|
||||||
|
/*
|
||||||
|
* set time to 0. Otherwise, if there is a delay,
|
||||||
|
* the check for overrun counters in SecCtrCheckStatus
|
||||||
|
* may trigger!
|
||||||
|
*/
|
||||||
|
node = GetHipadabaNode(self->pDes->parNode, "time");
|
||||||
|
UpdateHipadabaPar(node,MakeHdbFloat(.0), pCon);
|
||||||
InvokeCallBack(self->pCall,COUNTSTART, pCon);
|
InvokeCallBack(self->pCall,COUNTSTART, pCon);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
@ -135,13 +143,15 @@ static int SecCtrCheckStatus(void *pData, SConnection *pCon)
|
|||||||
ReleaseCountLock(self->pCountInt);
|
ReleaseCountLock(self->pCountInt);
|
||||||
status = HWFault;
|
status = HWFault;
|
||||||
}
|
}
|
||||||
|
ReleaseHdbValue(&v);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check for overrun timers
|
* check for overrun timers
|
||||||
*/
|
*/
|
||||||
if(self->getMode(self) == eTimer &&
|
if(self->getMode(self) == eTimer &&
|
||||||
time(NULL) > self->tStart + self->getPreset(self)){
|
time(NULL) > self->tStart + self->getPreset(self) && self->haltFixFlag == 0){
|
||||||
SecCtrHalt(self);
|
SecCtrHalt(self);
|
||||||
|
self->haltFixFlag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = GetHipadabaNode(self->pDes->parNode,"control");
|
node = GetHipadabaNode(self->pDes->parNode,"control");
|
||||||
@ -182,11 +192,14 @@ static int SecCtrTransferData(void *pData, SConnection *pCon)
|
|||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
pHdb node = NULL;
|
pHdb node = NULL;
|
||||||
hdbValue v;
|
hdbValue v;
|
||||||
|
int status;
|
||||||
|
|
||||||
node = GetHipadabaNode(self->pDes->parNode,"values");
|
node = GetHipadabaNode(self->pDes->parNode,"values");
|
||||||
assert(node != NULL);
|
assert(node != NULL);
|
||||||
self->isUpToDate = 1;
|
self->isUpToDate = 1;
|
||||||
return GetHipadabaPar(node,&v,pCon);
|
status = GetHipadabaPar(node,&v,pCon);
|
||||||
|
ReleaseHdbValue(&v);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
static void *SecCtrCounterGetInterface(void *pData, int iID)
|
static void *SecCtrCounterGetInterface(void *pData, int iID)
|
||||||
@ -225,16 +238,19 @@ static CounterMode SecCtrGetMode(pCounter self)
|
|||||||
{
|
{
|
||||||
hdbValue v;
|
hdbValue v;
|
||||||
pHdb node = NULL;
|
pHdb node = NULL;
|
||||||
|
CounterMode mode;
|
||||||
|
|
||||||
node = GetHipadabaNode(self->pDes->parNode,"mode");
|
node = GetHipadabaNode(self->pDes->parNode,"mode");
|
||||||
assert(node != NULL);
|
assert(node != NULL);
|
||||||
GetHipadabaPar(node,&v,NULL);
|
GetHipadabaPar(node,&v,NULL);
|
||||||
assert(v.v.text != NULL);
|
assert(v.v.text != NULL);
|
||||||
if(strcmp(v.v.text,"timer") == 0){
|
if(strcmp(v.v.text,"timer") == 0){
|
||||||
return eTimer;
|
mode = eTimer;
|
||||||
} else {
|
} else {
|
||||||
return ePreset;
|
mode = ePreset;
|
||||||
}
|
}
|
||||||
|
ReleaseHdbValue(&v);
|
||||||
|
return mode;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static int SecCtrSetPreset(pCounter self, float val)
|
static int SecCtrSetPreset(pCounter self, float val)
|
||||||
@ -287,6 +303,7 @@ static long SecCtrGetMonitor(pCounter self, int iNum, SConnection *pCon)
|
|||||||
{
|
{
|
||||||
hdbValue v;
|
hdbValue v;
|
||||||
pHdb node = NULL;
|
pHdb node = NULL;
|
||||||
|
long val;
|
||||||
|
|
||||||
if (!self->isUpToDate) {
|
if (!self->isUpToDate) {
|
||||||
self->pCountInt->TransferData(self, pCon);
|
self->pCountInt->TransferData(self, pCon);
|
||||||
@ -295,10 +312,12 @@ static long SecCtrGetMonitor(pCounter self, int iNum, SConnection *pCon)
|
|||||||
assert(node != NULL);
|
assert(node != NULL);
|
||||||
GetHipadabaPar(node,&v,pCon);
|
GetHipadabaPar(node,&v,pCon);
|
||||||
if(iNum >= 0 && iNum < v.arrayLength){
|
if(iNum >= 0 && iNum < v.arrayLength){
|
||||||
return (long)v.v.intArray[iNum];
|
val = (long)v.v.intArray[iNum];
|
||||||
} else {
|
} else {
|
||||||
return -1L;
|
val = -1L;
|
||||||
}
|
}
|
||||||
|
ReleaseHdbValue(&v);
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static long SecCtrGetCounts(pCounter self, SConnection *pCon)
|
static long SecCtrGetCounts(pCounter self, SConnection *pCon)
|
||||||
|
58
devexec.c
58
devexec.c
@ -15,6 +15,9 @@
|
|||||||
Reworked to use copied connection objects instead of context pushes.
|
Reworked to use copied connection objects instead of context pushes.
|
||||||
Mark Koennecke, January 2009
|
Mark Koennecke, January 2009
|
||||||
|
|
||||||
|
Modified to accomodate run levels
|
||||||
|
Mark Koennecke, April 2009
|
||||||
|
|
||||||
Copyright:
|
Copyright:
|
||||||
|
|
||||||
Labor fuer Neutronenstreuung
|
Labor fuer Neutronenstreuung
|
||||||
@ -121,6 +124,7 @@ typedef struct _DevEntry {
|
|||||||
float fVal;
|
float fVal;
|
||||||
char *name;
|
char *name;
|
||||||
SConnection *pCon;
|
SConnection *pCon;
|
||||||
|
int level;
|
||||||
} DevEntry, *pDevEntry;
|
} DevEntry, *pDevEntry;
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -131,7 +135,7 @@ typedef struct {
|
|||||||
} checkContext, *pCheckContext;
|
} checkContext, *pCheckContext;
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, SConnection * pCon,
|
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, SConnection * pCon,
|
||||||
void *pData, float fVal, char *name)
|
void *pData, float fVal, char *name, int level)
|
||||||
{
|
{
|
||||||
pDevEntry pNew = NULL;
|
pDevEntry pNew = NULL;
|
||||||
|
|
||||||
@ -146,6 +150,8 @@ static pDevEntry CreateDevEntry(pObjectDescriptor pDes, SConnection * pCon,
|
|||||||
pNew->name = strdup(name);
|
pNew->name = strdup(name);
|
||||||
pNew->fVal = fVal;
|
pNew->fVal = fVal;
|
||||||
pNew->pCon = SCCopyConnection(pCon);
|
pNew->pCon = SCCopyConnection(pCon);
|
||||||
|
pNew->pCon->runLevel = level;
|
||||||
|
pNew->level = level;
|
||||||
return pNew;
|
return pNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +281,7 @@ void ExeInterest(pExeList self, pDevEntry pDev, char *text)
|
|||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
|
int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
|
||||||
void *pData, SConnection * pCon, float fNew)
|
void *pData, SConnection * pCon, int level, float fNew)
|
||||||
{
|
{
|
||||||
pDevEntry pNew = NULL;
|
pDevEntry pNew = NULL;
|
||||||
int iRet;
|
int iRet;
|
||||||
@ -319,7 +325,7 @@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
|
|||||||
|
|
||||||
/* well create a new entry */
|
/* well create a new entry */
|
||||||
self->iStop = 0;
|
self->iStop = 0;
|
||||||
pNew = CreateDevEntry(pDes, pCon, pData, fNew, name);
|
pNew = CreateDevEntry(pDes, pCon, pData, fNew, name, level);
|
||||||
if (!pNew) {
|
if (!pNew) {
|
||||||
SCWrite(pCon, "ERROR: memory exhausted in Device Executor ", eError);
|
SCWrite(pCon, "ERROR: memory exhausted in Device Executor ", eError);
|
||||||
return 0;
|
return 0;
|
||||||
@ -380,7 +386,7 @@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
|
|||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
int StartMotor(pExeList self, SicsInterp * pSics, SConnection * pCon,
|
int StartMotor(pExeList self, SicsInterp * pSics, SConnection * pCon,
|
||||||
char *name, float fVal)
|
char *name, int level, float fVal)
|
||||||
{
|
{
|
||||||
pDummy pMot = NULL;
|
pDummy pMot = NULL;
|
||||||
CommandList *pCom = NULL;
|
CommandList *pCom = NULL;
|
||||||
@ -415,12 +421,12 @@ int StartMotor(pExeList self, SicsInterp * pSics, SConnection * pCon,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return StartDevice(self, name, pMot->pDescriptor, (void *) pMot, pCon,
|
return StartDevice(self, name, pMot->pDescriptor, (void *) pMot, pCon,
|
||||||
fVal);
|
level, fVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int StartCounter(pExeList self, SicsInterp * pSics, SConnection * pCon,
|
int StartCounter(pExeList self, SicsInterp * pSics, SConnection * pCon,
|
||||||
char *name)
|
int level, char *name)
|
||||||
{
|
{
|
||||||
pCounter pCter = NULL;
|
pCounter pCter = NULL;
|
||||||
CommandList *pCom = NULL;
|
CommandList *pCom = NULL;
|
||||||
@ -455,7 +461,7 @@ int StartCounter(pExeList self, SicsInterp * pSics, SConnection * pCon,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return StartDevice(self, name, pCter->pDes, (void *) pCter,
|
return StartDevice(self, name, pCter->pDes, (void *) pCter,
|
||||||
pCon, pCter->pDriv->fPreset);
|
pCon, level, pCter->pDriv->fPreset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
@ -652,6 +658,27 @@ int CheckExeList(pExeList self)
|
|||||||
iRet = LLDnodePtr2First(self->iList);
|
iRet = LLDnodePtr2First(self->iList);
|
||||||
return testFinish(self);
|
return testFinish(self);
|
||||||
}
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int DevExecLevelRunning(pExeList self, int level)
|
||||||
|
{
|
||||||
|
int iRet;
|
||||||
|
pDevEntry pDev = NULL;
|
||||||
|
|
||||||
|
if(self->lTask < 0){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
iRet = LLDnodePtr2First(self->iList);
|
||||||
|
while (iRet != 0) {
|
||||||
|
LLDnodeDataTo(self->iList, &pDev);
|
||||||
|
if (pDev) {
|
||||||
|
if(pDev->level >= level){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iRet = LLDnodePtr2Next(self->iList);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int Wait4Success(pExeList self)
|
int Wait4Success(pExeList self)
|
||||||
@ -667,7 +694,10 @@ int Wait4Success(pExeList self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* wait for Devexec task to finish */
|
/* wait for Devexec task to finish */
|
||||||
TaskWait(self->pTask, self->lTask);
|
/*TaskWait(self->pTask, self->lTask); */
|
||||||
|
while(DevExecLevelRunning(self,RUNDRIVE)){
|
||||||
|
TaskYield(self->pTask);
|
||||||
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Wait4Success finished\n");
|
printf("Wait4Success finished\n");
|
||||||
#endif
|
#endif
|
||||||
@ -759,7 +789,7 @@ int StopExe(pExeList self, char *name)
|
|||||||
}
|
}
|
||||||
iRet = LLDnodePtr2Next(self->iList);
|
iRet = LLDnodePtr2Next(self->iList);
|
||||||
}
|
}
|
||||||
SCWrite(self->pOwner, "ERROR: Full Stop called!!", eError);
|
SCWrite(self->pOwner, "ERROR: Full Stop called!!", eLogError);
|
||||||
if (SCGetInterrupt(self->pOwner) > eContinue) {
|
if (SCGetInterrupt(self->pOwner) > eContinue) {
|
||||||
self->iStatus = DEVINT;
|
self->iStatus = DEVINT;
|
||||||
}
|
}
|
||||||
@ -826,7 +856,9 @@ int StopByData(pExeList self, void *data)
|
|||||||
int StopExeWait(pExeList self)
|
int StopExeWait(pExeList self)
|
||||||
{
|
{
|
||||||
StopExe(self, "all");
|
StopExe(self, "all");
|
||||||
Wait4Success(self);
|
while(DevExecLevelRunning(self,RUNRUN)){
|
||||||
|
TaskYield(self->pTask);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
@ -1044,10 +1076,14 @@ int Success(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
{
|
{
|
||||||
int iRet;
|
int iRet;
|
||||||
Status eOld;
|
Status eOld;
|
||||||
|
pExeList self = (pExeList)pData;
|
||||||
|
|
||||||
eOld = GetStatus();
|
eOld = GetStatus();
|
||||||
SetStatus(eRunning);
|
SetStatus(eRunning);
|
||||||
iRet = Wait4Success((pExeList) pData);
|
while(DevExecLevelRunning(self, RUNRUN)){
|
||||||
|
TaskYield(self->pTask);
|
||||||
|
}
|
||||||
|
iRet = self->iStatus;
|
||||||
if (iRet == DEVINT) {
|
if (iRet == DEVINT) {
|
||||||
if (SCGetInterrupt(pCon) == eAbortOperation) {
|
if (SCGetInterrupt(pCon) == eAbortOperation) {
|
||||||
SCSetInterrupt(pCon, eContinue);
|
SCSetInterrupt(pCon, eContinue);
|
||||||
|
189
devexec.h
189
devexec.h
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 197 "devexec.w"
|
#line 202 "devexec.w"
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -28,7 +28,7 @@
|
|||||||
#include "obdes.h"
|
#include "obdes.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
typedef struct __EXELIST *pExeList;
|
typedef struct __EXELIST *pExeList;
|
||||||
|
|
||||||
/* Returncodes */
|
/* Returncodes */
|
||||||
|
|
||||||
@ -37,140 +37,145 @@ typedef struct __EXELIST *pExeList;
|
|||||||
#define DEVERROR 2
|
#define DEVERROR 2
|
||||||
#define DEVBUSY 3
|
#define DEVBUSY 3
|
||||||
|
|
||||||
|
/* run level codes */
|
||||||
|
#define RUNRUN 0
|
||||||
|
#define RUNDRIVE 1
|
||||||
/*------------------------------------------------------------------------
|
/*------------------------------------------------------------------------
|
||||||
B I R T H & D E A T H
|
B I R T H & D E A T H
|
||||||
*/
|
*/
|
||||||
pExeList CreateExeList(pTaskMan pTask);
|
pExeList CreateExeList(pTaskMan pTask);
|
||||||
void DeleteExeList(void *self);
|
void DeleteExeList(void *self);
|
||||||
|
|
||||||
/* ================= Functions to talk to the above ====================== */
|
/* ================= Functions to talk to the above ====================== */
|
||||||
|
|
||||||
#line 43 "devexec.w"
|
#line 43 "devexec.w"
|
||||||
|
|
||||||
int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
|
int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
|
||||||
void *pData, SConnection * pCon, float fNew);
|
void *pData, SConnection *pCon, int level, float fNew);
|
||||||
int StartMotor(pExeList self, SicsInterp * pSics, SConnection * pCon,
|
int StartMotor(pExeList self, SicsInterp *pSics, SConnection *pCon,
|
||||||
char *name, float fNew);
|
char *name, int level, float fNew);
|
||||||
int StartCounter(pExeList self, SicsInterp * pSics, SConnection * pCon,
|
int StartCounter(pExeList self, SicsInterp *pSics, SConnection *pCon,
|
||||||
char *name);
|
int level, char *name);
|
||||||
|
|
||||||
#line 241 "devexec.w"
|
#line 249 "devexec.w"
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#line 88 "devexec.w"
|
#line 89 "devexec.w"
|
||||||
|
|
||||||
int CheckExeList(pExeList self);
|
int CheckExeList(pExeList self);
|
||||||
/*
|
/*
|
||||||
checks the entries for success and deletes entries which have finished
|
checks the entries for success and deletes entries which have finished
|
||||||
operation. If there are none left, the pOwner will be set to NULL.
|
operation. If there are none left, the pOwner will be set to NULL.
|
||||||
*/
|
*/
|
||||||
int Wait4Success(pExeList self);
|
int Wait4Success(pExeList self);
|
||||||
|
|
||||||
long GetDevexecID(pExeList self);
|
long GetDevexecID(pExeList self);
|
||||||
|
|
||||||
int DevExecTask(void *pEL);
|
int DevExecLevelRunning(pExeList self, int level);
|
||||||
void DevExecSignal(void *pEL, int iSignal, void *pSigData);
|
|
||||||
|
int DevExecTask(void *pEL);
|
||||||
|
void DevExecSignal(void *pEL, int iSignal, void *pSigData);
|
||||||
|
|
||||||
|
|
||||||
#line 243 "devexec.w"
|
#line 251 "devexec.w"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Waits for execution to finish. returns 1 on Success, 0 if problems
|
Waits for execution to finish. returns 1 on Success, 0 if problems
|
||||||
ocurred. Than the Interrupt code shall be checked and acted upon
|
ocurred. Than the Interrupt code shall be checked and acted upon
|
||||||
accordingly.
|
accordingly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
SConnection *GetExeOwner(pExeList self);
|
SConnection *GetExeOwner(pExeList self);
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
int isInRunMode(pExeList self);
|
int isInRunMode(pExeList self);
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
int ListPending(pExeList self, SConnection * pCon);
|
int ListPending(pExeList self, SConnection *pCon);
|
||||||
/*
|
/*
|
||||||
lists the Operations still pending on pCon.
|
lists the Operations still pending on pCon.
|
||||||
*/
|
*/
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#line 137 "devexec.w"
|
#line 142 "devexec.w"
|
||||||
|
|
||||||
int StopExe(pExeList self, char *name);
|
int StopExe(pExeList self, char *name);
|
||||||
int StopExeWait(pExeList self);
|
int StopExeWait(pExeList self);
|
||||||
/*
|
/*
|
||||||
will stop the entry name and its subentries from executing.
|
will stop the entry name and its subentries from executing.
|
||||||
If ALL is specified as name, everything will be stopped and
|
If ALL is specified as name, everything will be stopped and
|
||||||
the Executor cleared.
|
the Executor cleared.
|
||||||
StopExeWait will stop all running things and wait for the stop
|
StopExeWait will stop all running things and wait for the stop
|
||||||
to complete.
|
to complete.
|
||||||
*/
|
*/
|
||||||
|
int StopByData(pExeList self, void *data);
|
||||||
int StopByData(pExeList self, void *data);
|
|
||||||
/* stop the entry with the given data from execution */
|
/* stop the entry with the given data from execution */
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
void ClearExecutor(pExeList self);
|
void ClearExecutor(pExeList self);
|
||||||
/*
|
/*
|
||||||
clears the executor without sending commands to the devices.
|
clears the executor without sending commands to the devices.
|
||||||
*/
|
*/
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
int IsCounting(pExeList self);
|
int IsCounting(pExeList self);
|
||||||
int PauseExecution(pExeList self);
|
int PauseExecution(pExeList self);
|
||||||
int ContinueExecution(pExeList self);
|
int ContinueExecution(pExeList self);
|
||||||
|
|
||||||
|
|
||||||
#line 261 "devexec.w"
|
#line 269 "devexec.w"
|
||||||
|
|
||||||
/*-------------------------- Commands ------------------------------------*/
|
/*-------------------------- Commands ------------------------------------*/
|
||||||
int DevexecAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
int StopCommand(SConnection * pCon, SicsInterp * pSics, void *pData,
|
int StopCommand(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
/*
|
/*
|
||||||
implements the stop command
|
implements the stop command
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ListExe(SConnection * pCon, SicsInterp * pSics, void *pData,
|
int ListExe(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
/*
|
/*
|
||||||
lists all currently executing objects
|
lists all currently executing objects
|
||||||
*/
|
*/
|
||||||
int SicsIdle(SConnection * pCon, SicsInterp * pSics, void *pData,
|
int SicsIdle(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
/*
|
/*
|
||||||
prints the seconds since the device executor was running the last time
|
prints the seconds since the device executor was running the last time
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Success(SConnection * pCon, SicsInterp * pSics, void *pData,
|
int Success(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
/*
|
/*
|
||||||
waits until completion of all pending operations. Used in
|
waits until completion of all pending operations. Used in
|
||||||
connection with non blocking operation such as motors started
|
connection with non blocking operation such as motors started
|
||||||
with run.
|
with run.
|
||||||
*/
|
*/
|
||||||
int PauseAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
int PauseAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
/*
|
/*
|
||||||
pauses execution
|
pauses execution
|
||||||
*/
|
*/
|
||||||
int ContinueAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
int ContinueAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
/*
|
/*
|
||||||
continues execution
|
continues execution
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*--------------------------- Locking ---------------------------------*/
|
/*--------------------------- Locking ---------------------------------*/
|
||||||
|
|
||||||
#line 185 "devexec.w"
|
#line 190 "devexec.w"
|
||||||
|
|
||||||
void LockDeviceExecutor(pExeList self);
|
void LockDeviceExecutor(pExeList self);
|
||||||
void UnlockDeviceExecutor(pExeList self);
|
void UnlockDeviceExecutor(pExeList self);
|
||||||
|
|
||||||
|
|
||||||
#line 301 "devexec.w"
|
#line 309 "devexec.w"
|
||||||
|
|
||||||
/* -------------------------- Executor management -------------------------*/
|
/* -------------------------- Executor management -------------------------*/
|
||||||
pExeList GetExecutor(void);
|
|
||||||
void SetExecutor(pExeList pExe);
|
pExeList GetExecutor(void);
|
||||||
|
void SetExecutor(pExeList pExe);
|
||||||
/*----------------------- Logging -----------------------------------------*/
|
/*----------------------- Logging -----------------------------------------*/
|
||||||
void DevexecLog(char *op, char *device);
|
void DevexecLog(char *op, char *device);
|
||||||
#endif
|
#endif
|
||||||
|
14
devexec.tex
14
devexec.tex
@ -47,11 +47,11 @@ $\langle$devreg {\footnotesize ?}$\rangle\equiv$
|
|||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,@\\
|
\mbox{}\verb@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,@\\
|
||||||
\mbox{}\verb@ void *pData, SConnection *pCon, float fNew);@\\
|
\mbox{}\verb@ void *pData, SConnection *pCon, int level, float fNew);@\\
|
||||||
\mbox{}\verb@ int StartMotor(pExeList self, SicsInterp *pSics, SConnection *pCon,@\\
|
\mbox{}\verb@ int StartMotor(pExeList self, SicsInterp *pSics, SConnection *pCon,@\\
|
||||||
\mbox{}\verb@ char *name, float fNew);@\\
|
\mbox{}\verb@ char *name, int level, float fNew);@\\
|
||||||
\mbox{}\verb@ int StartCounter(pExeList self, SicsInterp *pSics, SConnection *pCon,@\\
|
\mbox{}\verb@ int StartCounter(pExeList self, SicsInterp *pSics, SConnection *pCon,@\\
|
||||||
\mbox{}\verb@ char *name); @\\
|
\mbox{}\verb@ int level, char *name); @\\
|
||||||
\mbox{}\verb@@$\Diamond$
|
\mbox{}\verb@@$\Diamond$
|
||||||
\end{list}
|
\end{list}
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
@ -67,6 +67,7 @@ The main interface function is {\bf StartDevice}. The parameters are:
|
|||||||
\item {\bf name}. The name of the object which operates.
|
\item {\bf name}. The name of the object which operates.
|
||||||
\item {\bf pDes}. A pointer to the ObjectDescriptor of the object to drive or count.
|
\item {\bf pDes}. A pointer to the ObjectDescriptor of the object to drive or count.
|
||||||
\item {\bf pData}. A pointer to the data structure coming with the object.
|
\item {\bf pData}. A pointer to the data structure coming with the object.
|
||||||
|
\item {\bf level} The start level of the device.
|
||||||
\item {\bf pCon}. A pointer to the client connection on whose request the
|
\item {\bf pCon}. A pointer to the client connection on whose request the
|
||||||
operation was initiated.
|
operation was initiated.
|
||||||
\item {\bf fNew}. A floating point value which sets the target value for
|
\item {\bf fNew}. A floating point value which sets the target value for
|
||||||
@ -112,6 +113,8 @@ $\langle$devcheck {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ long GetDevexecID(pExeList self);@\\
|
\mbox{}\verb@ long GetDevexecID(pExeList self);@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ int DevExecLevelRunning(pExeList self, int level);@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ int DevExecTask(void *pEL);@\\
|
\mbox{}\verb@ int DevExecTask(void *pEL);@\\
|
||||||
\mbox{}\verb@ void DevExecSignal(void *pEL, int iSignal, void *pSigData);@\\
|
\mbox{}\verb@ void DevExecSignal(void *pEL, int iSignal, void *pSigData);@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
@ -155,6 +158,8 @@ properly finished operation, DEVERROR for an operation which finished
|
|||||||
with an error code and DEVINT for an aoperation which was interrupted
|
with an error code and DEVINT for an aoperation which was interrupted
|
||||||
by the user.
|
by the user.
|
||||||
|
|
||||||
|
{\bf DevExeclevelRunning} tests if the level given as a parameter is still running.
|
||||||
|
|
||||||
\subsubsection{Influencing Execution}
|
\subsubsection{Influencing Execution}
|
||||||
In certain cases it is necessary to interact with running devices directly.
|
In certain cases it is necessary to interact with running devices directly.
|
||||||
This is done via the following interface.
|
This is done via the following interface.
|
||||||
@ -285,6 +290,9 @@ to the global SICS device executor.
|
|||||||
\mbox{}\verb@#define DEVERROR 2@\\
|
\mbox{}\verb@#define DEVERROR 2@\\
|
||||||
\mbox{}\verb@#define DEVBUSY 3@\\
|
\mbox{}\verb@#define DEVBUSY 3@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@/* run level codes */@\\
|
||||||
|
\mbox{}\verb@#define RUNRUN 0@\\
|
||||||
|
\mbox{}\verb@#define RUNDRIVE 1@\\
|
||||||
\mbox{}\verb@/*------------------------------------------------------------------------@\\
|
\mbox{}\verb@/*------------------------------------------------------------------------@\\
|
||||||
\mbox{}\verb@ B I R T H & D E A T H@\\
|
\mbox{}\verb@ B I R T H & D E A T H@\\
|
||||||
\mbox{}\verb@*/@\\
|
\mbox{}\verb@*/@\\
|
||||||
|
14
devexec.w
14
devexec.w
@ -42,11 +42,11 @@ functions are provided.
|
|||||||
|
|
||||||
@d devreg @{
|
@d devreg @{
|
||||||
int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
|
int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
|
||||||
void *pData, SConnection *pCon, float fNew);
|
void *pData, SConnection *pCon, int level, float fNew);
|
||||||
int StartMotor(pExeList self, SicsInterp *pSics, SConnection *pCon,
|
int StartMotor(pExeList self, SicsInterp *pSics, SConnection *pCon,
|
||||||
char *name, float fNew);
|
char *name, int level, float fNew);
|
||||||
int StartCounter(pExeList self, SicsInterp *pSics, SConnection *pCon,
|
int StartCounter(pExeList self, SicsInterp *pSics, SConnection *pCon,
|
||||||
char *name);
|
int level, char *name);
|
||||||
@}
|
@}
|
||||||
|
|
||||||
The main interface function is {\bf StartDevice}. The parameters are:
|
The main interface function is {\bf StartDevice}. The parameters are:
|
||||||
@ -55,6 +55,7 @@ The main interface function is {\bf StartDevice}. The parameters are:
|
|||||||
\item {\bf name}. The name of the object which operates.
|
\item {\bf name}. The name of the object which operates.
|
||||||
\item {\bf pDes}. A pointer to the ObjectDescriptor of the object to drive or count.
|
\item {\bf pDes}. A pointer to the ObjectDescriptor of the object to drive or count.
|
||||||
\item {\bf pData}. A pointer to the data structure coming with the object.
|
\item {\bf pData}. A pointer to the data structure coming with the object.
|
||||||
|
\item {\bf level} The start level of the device.
|
||||||
\item {\bf pCon}. A pointer to the client connection on whose request the
|
\item {\bf pCon}. A pointer to the client connection on whose request the
|
||||||
operation was initiated.
|
operation was initiated.
|
||||||
\item {\bf fNew}. A floating point value which sets the target value for
|
\item {\bf fNew}. A floating point value which sets the target value for
|
||||||
@ -95,6 +96,8 @@ From within the SICS main loops this special function is called:
|
|||||||
|
|
||||||
long GetDevexecID(pExeList self);
|
long GetDevexecID(pExeList self);
|
||||||
|
|
||||||
|
int DevExecLevelRunning(pExeList self, int level);
|
||||||
|
|
||||||
int DevExecTask(void *pEL);
|
int DevExecTask(void *pEL);
|
||||||
void DevExecSignal(void *pEL, int iSignal, void *pSigData);
|
void DevExecSignal(void *pEL, int iSignal, void *pSigData);
|
||||||
|
|
||||||
@ -130,6 +133,8 @@ properly finished operation, DEVERROR for an operation which finished
|
|||||||
with an error code and DEVINT for an aoperation which was interrupted
|
with an error code and DEVINT for an aoperation which was interrupted
|
||||||
by the user.
|
by the user.
|
||||||
|
|
||||||
|
{\bf DevExeclevelRunning} tests if the level given as a parameter is still running.
|
||||||
|
|
||||||
\subsubsection{Influencing Execution}
|
\subsubsection{Influencing Execution}
|
||||||
In certain cases it is necessary to interact with running devices directly.
|
In certain cases it is necessary to interact with running devices directly.
|
||||||
This is done via the following interface.
|
This is done via the following interface.
|
||||||
@ -231,6 +236,9 @@ to the global SICS device executor.
|
|||||||
#define DEVERROR 2
|
#define DEVERROR 2
|
||||||
#define DEVBUSY 3
|
#define DEVBUSY 3
|
||||||
|
|
||||||
|
/* run level codes */
|
||||||
|
#define RUNRUN 0
|
||||||
|
#define RUNDRIVE 1
|
||||||
/*------------------------------------------------------------------------
|
/*------------------------------------------------------------------------
|
||||||
B I R T H & D E A T H
|
B I R T H & D E A T H
|
||||||
*/
|
*/
|
||||||
|
10
drive.c
10
drive.c
@ -107,7 +107,7 @@ int Drive(SConnection * pCon, SicsInterp * pInter, char *name, float fNew)
|
|||||||
SCSetInterrupt(pCon, eAbortOperation);
|
SCSetInterrupt(pCon, eAbortOperation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
iRet = StartDevice(GetExecutor(), name, pDes, pDum, pCon, fNew);
|
iRet = StartDevice(GetExecutor(), name, pDes, pDum, pCon, RUNDRIVE, fNew);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
sprintf(pBueffel, "ERROR: cannot start device %s", name);
|
sprintf(pBueffel, "ERROR: cannot start device %s", name);
|
||||||
SCWrite(pCon, pBueffel, eError);
|
SCWrite(pCon, pBueffel, eError);
|
||||||
@ -143,7 +143,7 @@ int Drive(SConnection * pCon, SicsInterp * pInter, char *name, float fNew)
|
|||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int Start2Run(SConnection * pCon, SicsInterp * pInter, char *name,
|
int Start2Run(SConnection * pCon, SicsInterp * pInter, char *name,
|
||||||
float fNew)
|
int level, float fNew)
|
||||||
{
|
{
|
||||||
CommandList *pObject = NULL;
|
CommandList *pObject = NULL;
|
||||||
pObjectDescriptor pDes = NULL;
|
pObjectDescriptor pDes = NULL;
|
||||||
@ -199,7 +199,7 @@ int Start2Run(SConnection * pCon, SicsInterp * pInter, char *name,
|
|||||||
SCSetInterrupt(pCon, eAbortOperation);
|
SCSetInterrupt(pCon, eAbortOperation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
iRet = StartDevice(GetExecutor(), name, pDes, pDum, pCon, fNew);
|
iRet = StartDevice(GetExecutor(), name, pDes, pDum, pCon,level, fNew);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
@ -315,7 +315,7 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
SetStatus(eOld);
|
SetStatus(eOld);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
iRet = Start2Run(pCon, pSics, argv[i], dTarget);
|
iRet = Start2Run(pCon, pSics, argv[i], RUNDRIVE, dTarget);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
sprintf(pBueffel, "ERROR: cannot run %s to %s", argv[i],
|
sprintf(pBueffel, "ERROR: cannot run %s to %s", argv[i],
|
||||||
argv[i + 1]);
|
argv[i + 1]);
|
||||||
@ -407,7 +407,7 @@ int RunWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
SetStatus(eOld);
|
SetStatus(eOld);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
iRet = Start2Run(pCon, pSics, argv[i], dTarget);
|
iRet = Start2Run(pCon, pSics, argv[i], RUNRUN, dTarget);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
sprintf(pBueffel, "ERROR: cannot run %s to %s", argv[i],
|
sprintf(pBueffel, "ERROR: cannot run %s to %s", argv[i],
|
||||||
argv[i + 1]);
|
argv[i + 1]);
|
||||||
|
4
drive.h
4
drive.h
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
int Drive(SConnection * pCon, SicsInterp * pSics, char *name, float fNew);
|
int Drive(SConnection * pCon, SicsInterp * pSics, char *name, float fNew);
|
||||||
|
|
||||||
int Start2Run(SConnection * pCon, SicsInterp * pSics, char *name, float
|
int Start2Run(SConnection * pCon, SicsInterp * pSics, char *name,
|
||||||
fNew);
|
int level, float fNew);
|
||||||
|
|
||||||
int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
|
int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
|
@ -840,7 +840,7 @@ int EVCDrive(pEVControl self, SConnection * pCon, float fVal)
|
|||||||
|
|
||||||
/* start executing */
|
/* start executing */
|
||||||
iRet = StartDevice(GetExecutor(), self->pName, self->pDes,
|
iRet = StartDevice(GetExecutor(), self->pName, self->pDes,
|
||||||
self, pCon, fVal);
|
self, pCon, pCon->runLevel, fVal);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
sprintf(pBueffel, "ERROR: Failure to start %s", self->pName);
|
sprintf(pBueffel, "ERROR: Failure to start %s", self->pName);
|
||||||
SCWrite(pCon, pBueffel, eError);
|
SCWrite(pCon, pBueffel, eError);
|
||||||
|
@ -293,7 +293,7 @@ int DriveCenter(pFit self, SConnection * pCon, SicsInterp * pSics)
|
|||||||
|
|
||||||
iRet =
|
iRet =
|
||||||
StartMotor(pServ->pExecutor, pSics, pCon, self->pName,
|
StartMotor(pServ->pExecutor, pSics, pCon, self->pName,
|
||||||
self->fCenter);
|
RUNDRIVE, self->fCenter);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -477,6 +477,10 @@ static int *calculateTimeSum(HistInt * data, int iDet, int iTime)
|
|||||||
int i, j;
|
int i, j;
|
||||||
int *sum = NULL;
|
int *sum = NULL;
|
||||||
|
|
||||||
|
if(data == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
sum = (int *) malloc(iTime * sizeof(int));
|
sum = (int *) malloc(iTime * sizeof(int));
|
||||||
if (!sum) {
|
if (!sum) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -55,6 +55,9 @@ static int ClearTblCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
|||||||
|
|
||||||
node = GetHipadabaNode(self->objectNode,"data");
|
node = GetHipadabaNode(self->objectNode,"data");
|
||||||
if(node != NULL){
|
if(node != NULL){
|
||||||
|
if(CountHdbChildren(node) < 1){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
DeleteNodeData(node);
|
DeleteNodeData(node);
|
||||||
RemoveHdbNodeFromParent(node, pCon);
|
RemoveHdbNodeFromParent(node, pCon);
|
||||||
}
|
}
|
||||||
|
@ -12,5 +12,5 @@
|
|||||||
|
|
||||||
pSICSOBJ MakeHdbTable(char *name, char *hdbclass);
|
pSICSOBJ MakeHdbTable(char *name, char *hdbclass);
|
||||||
int ReadTableTemplate(pSICSOBJ self, SConnection *con);
|
int ReadTableTemplate(pSICSOBJ self, SConnection *con);
|
||||||
|
|
||||||
#endif /*HDBTABLE_H_*/
|
#endif /*HDBTABLE_H_*/
|
||||||
|
@ -972,9 +972,8 @@ int GetHipadabaPar(pHdb node, hdbValue *v, void *callData)
|
|||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
memset(v,0,sizeof(hdbValue));
|
||||||
v->dataType = node->value.dataType;
|
v->dataType = node->value.dataType;
|
||||||
v->doNotFree = 0;
|
|
||||||
v->v.text = NULL; /* this sets all pointers in the union to NULL */
|
|
||||||
|
|
||||||
status = SendDataMessage(node, get, v, callData);
|
status = SendDataMessage(node, get, v, callData);
|
||||||
copyHdbValue(&node->value, v);
|
copyHdbValue(&node->value, v);
|
||||||
|
13
histmem.c
13
histmem.c
@ -203,6 +203,7 @@ static int HistStartCount(void *pData, SConnection * pCon)
|
|||||||
}
|
}
|
||||||
SCWrite(pCon, "ERROR: failed to fix histogram memory problem", eError);
|
SCWrite(pCon, "ERROR: failed to fix histogram memory problem", eError);
|
||||||
SCSetInterrupt(pCon, eAbortBatch);
|
SCSetInterrupt(pCon, eAbortBatch);
|
||||||
|
ReleaseCountLock(self->pCountInt);
|
||||||
return HWFault;
|
return HWFault;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,12 +238,14 @@ static int HistPause(void *pData, SConnection * pCon)
|
|||||||
SCWrite(pCon, "ERROR: failed to fix histogram memory problem",
|
SCWrite(pCon, "ERROR: failed to fix histogram memory problem",
|
||||||
eError);
|
eError);
|
||||||
SCSetInterrupt(pCon, eAbortBatch);
|
SCSetInterrupt(pCon, eAbortBatch);
|
||||||
|
ReleaseCountLock(self->pCountInt);
|
||||||
return HWFault;
|
return HWFault;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SCWrite(pCon, "ERROR: failed to fix histogram memory problem", eError);
|
SCWrite(pCon, "ERROR: failed to fix histogram memory problem", eError);
|
||||||
SCSetInterrupt(pCon, eAbortBatch);
|
SCSetInterrupt(pCon, eAbortBatch);
|
||||||
|
ReleaseCountLock(self->pCountInt);
|
||||||
return HWFault;
|
return HWFault;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,11 +280,13 @@ static int HistContinue(void *pData, SConnection * pCon)
|
|||||||
SCWrite(pCon, "ERROR: failed to fix histogram memory problem",
|
SCWrite(pCon, "ERROR: failed to fix histogram memory problem",
|
||||||
eError);
|
eError);
|
||||||
SCSetInterrupt(pCon, eAbortBatch);
|
SCSetInterrupt(pCon, eAbortBatch);
|
||||||
|
ReleaseCountLock(self->pCountInt);
|
||||||
return HWFault;
|
return HWFault;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SCWrite(pCon, "ERROR: failed to fix histogram memory problem", eError);
|
SCWrite(pCon, "ERROR: failed to fix histogram memory problem", eError);
|
||||||
|
ReleaseCountLock(self->pCountInt);
|
||||||
SCSetInterrupt(pCon, eAbortBatch);
|
SCSetInterrupt(pCon, eAbortBatch);
|
||||||
return HWFault;
|
return HWFault;
|
||||||
}
|
}
|
||||||
@ -299,6 +304,7 @@ static int HistCountStatus(void *pData, SConnection * pCon)
|
|||||||
if (!self->iInit) {
|
if (!self->iInit) {
|
||||||
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
|
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
|
||||||
InvokeCallBack(self->pCall, COUNTEND, NULL);
|
InvokeCallBack(self->pCall, COUNTEND, NULL);
|
||||||
|
ReleaseCountLock(self->pCountInt);
|
||||||
return COTERM;
|
return COTERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,7 +732,7 @@ int HistDoCount(pHistMem self, SConnection * pCon)
|
|||||||
|
|
||||||
/* start */
|
/* start */
|
||||||
return StartDevice(GetExecutor(), "HistogramMemory", self->pDes, self,
|
return StartDevice(GetExecutor(), "HistogramMemory", self->pDes, self,
|
||||||
pCon, self->pDriv->fCountPreset);
|
pCon, RUNRUN, self->pDriv->fCountPreset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
@ -738,7 +744,7 @@ int HistBlockCount(pHistMem self, SConnection * pCon)
|
|||||||
|
|
||||||
/* start counting */
|
/* start counting */
|
||||||
iRet = StartDevice(GetExecutor(), "HistogramMemory", self->pDes, self,
|
iRet = StartDevice(GetExecutor(), "HistogramMemory", self->pDes, self,
|
||||||
pCon, self->pDriv->fCountPreset);
|
pCon, RUNDRIVE, self->pDriv->fCountPreset);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
/* error has already been reported */
|
/* error has already been reported */
|
||||||
return 0;
|
return 0;
|
||||||
@ -1569,7 +1575,8 @@ int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
/* getdelay */
|
/* getdelay */
|
||||||
else if(strcmp(argv[1],"getdelay") == 0){
|
else if(strcmp(argv[1],"getdelay") == 0){
|
||||||
if(self->pDriv->data->nTimeChan > 1) {
|
if(self->pDriv->data->nTimeChan > 1) {
|
||||||
SCPrintf(pCon,eValue,"hm.delay = %d", self->pDriv->data->timeBinning[0]);
|
iVal = (int)self->pDriv->data->timeBinning[0];
|
||||||
|
SCPrintf(pCon,eValue,"hm.delay = %d", iVal);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
SCPrintf(pCon,eError,"ERROR: no TOF configured");
|
SCPrintf(pCon,eError,"ERROR: no TOF configured");
|
||||||
|
@ -337,7 +337,7 @@ int HMControlAction(SConnection * pCon, SicsInterp * pSics,
|
|||||||
*/
|
*/
|
||||||
self->pCount->SetCountParameters(self, (float) dPreset, eMode);
|
self->pCount->SetCountParameters(self, (float) dPreset, eMode);
|
||||||
status = StartDevice(pServ->pExecutor, "hmcontrol", self->pDes,
|
status = StartDevice(pServ->pExecutor, "hmcontrol", self->pDes,
|
||||||
self, pCon, 99);
|
self, pCon, RUNRUN, 99);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
SCWrite(pCon, "ERROR: failed to start counting", eError);
|
SCWrite(pCon, "ERROR: failed to start counting", eError);
|
||||||
return 0;
|
return 0;
|
||||||
|
2
macro.c
2
macro.c
@ -931,7 +931,7 @@ static int TclAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
sprintf(pBueffel, "ERROR: you are not authorised to invoke %s",
|
sprintf(pBueffel, "ERROR: you are not authorised to invoke %s",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
SCWrite(pCon, pBueffel, eError);
|
SCWrite(pCon, pBueffel, eError);
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make a string */
|
/* make a string */
|
||||||
|
11
maximize.c
11
maximize.c
@ -80,12 +80,12 @@ static int maxDrive(void *pObject, char *pVarName,
|
|||||||
pDummy pDum;
|
pDummy pDum;
|
||||||
int status;
|
int status;
|
||||||
char pBueffel[132];
|
char pBueffel[132];
|
||||||
long lTask;
|
|
||||||
|
|
||||||
/* start */
|
/* start */
|
||||||
pDum = (pDummy) pObject;
|
pDum = (pDummy) pObject;
|
||||||
status = StartDevice(pServ->pExecutor,
|
status = StartDevice(pServ->pExecutor,
|
||||||
pVarName, pDum->pDescriptor, pObject, pCon, fPos);
|
pVarName, pDum->pDescriptor, pObject, pCon,
|
||||||
|
RUNDRIVE, fPos);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
sprintf(pBueffel, "ERROR: failed to start %s", pVarName);
|
sprintf(pBueffel, "ERROR: failed to start %s", pVarName);
|
||||||
SCWrite(pCon, pBueffel, eError);
|
SCWrite(pCon, pBueffel, eError);
|
||||||
@ -93,11 +93,8 @@ static int maxDrive(void *pObject, char *pVarName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* wait */
|
/* wait */
|
||||||
lTask = GetDevexecID(pServ->pExecutor);
|
while(DevExecLevelRunning(pServ->pExecutor,RUNDRIVE)){
|
||||||
if (lTask > 0) {
|
TaskYield(pServ->pTasker);
|
||||||
TaskWait(pServ->pTasker, lTask);
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check interrupts */
|
/* check interrupts */
|
||||||
|
6
motor.c
6
motor.c
@ -311,7 +311,7 @@ static int statusRunTo(pMotor self, SConnection * pCon)
|
|||||||
if (self->retryCount >= ObVal(self->ParArray, POSCOUNT)) {
|
if (self->retryCount >= ObVal(self->ParArray, POSCOUNT)) {
|
||||||
snprintf(pBueffel, 255, "ERROR: aborting motor %s after %d retries",
|
snprintf(pBueffel, 255, "ERROR: aborting motor %s after %d retries",
|
||||||
self->name, self->retryCount);
|
self->name, self->retryCount);
|
||||||
SCWrite(pCon, pBueffel, eError);
|
SCWrite(pCon, pBueffel, eLogError);
|
||||||
return HWFault;
|
return HWFault;
|
||||||
}
|
}
|
||||||
if (SCGetInterrupt(pCon) != eContinue) {
|
if (SCGetInterrupt(pCon) != eContinue) {
|
||||||
@ -320,7 +320,7 @@ static int statusRunTo(pMotor self, SConnection * pCon)
|
|||||||
self->retryCount++;
|
self->retryCount++;
|
||||||
snprintf(pBueffel, 255, "WARNING: restarting %s, %d time",
|
snprintf(pBueffel, 255, "WARNING: restarting %s, %d time",
|
||||||
self->name, self->retryCount);
|
self->name, self->retryCount);
|
||||||
SCWrite(pCon, pBueffel, eWarning);
|
SCWrite(pCon, pBueffel, eLog);
|
||||||
self->pDriver->RunTo(self->pDriver, self->fTarget);
|
self->pDriver->RunTo(self->pDriver, self->fTarget);
|
||||||
return HWBusy;
|
return HWBusy;
|
||||||
}
|
}
|
||||||
@ -345,7 +345,7 @@ static int checkPosition(pMotor self, SConnection * pCon)
|
|||||||
}
|
}
|
||||||
snprintf(pBueffel, 131, "WARNING: %s off position by %f",
|
snprintf(pBueffel, 131, "WARNING: %s off position by %f",
|
||||||
self->name, absf(fHard - self->fTarget));
|
self->name, absf(fHard - self->fTarget));
|
||||||
SCWrite(pCon, pBueffel, eWarning);
|
SCWrite(pCon, pBueffel, eLog);
|
||||||
status = statusRunTo(self, pCon);
|
status = statusRunTo(self, pCon);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
20
motorsec.c
20
motorsec.c
@ -96,7 +96,14 @@ static long SecMotorRun(void *sulf, SConnection * pCon, float fNew)
|
|||||||
{
|
{
|
||||||
pMotor self = (pMotor) sulf;
|
pMotor self = (pMotor) sulf;
|
||||||
hdbValue v;
|
hdbValue v;
|
||||||
|
int accesscode;
|
||||||
|
|
||||||
|
assert(SICSHdbGetPar(self, NULL, "accesscode", &v) == 1);
|
||||||
|
accesscode = (int)v.v.doubleValue;
|
||||||
|
if(!SCMatchRights(pCon, accesscode)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
v = MakeHdbFloat(fNew);
|
v = MakeHdbFloat(fNew);
|
||||||
return SetHipadabaPar(self->pDescriptor->parNode, v, pCon);
|
return SetHipadabaPar(self->pDescriptor->parNode, v, pCon);
|
||||||
}
|
}
|
||||||
@ -206,13 +213,13 @@ static int checkPosition(pMotor self, SConnection * pCon)
|
|||||||
SecMotorGetPar(self, "maxretry", &maxretry);
|
SecMotorGetPar(self, "maxretry", &maxretry);
|
||||||
if (ABS(target - hard) > precision) {
|
if (ABS(target - hard) > precision) {
|
||||||
if (self->retryCount >= (int) maxretry) {
|
if (self->retryCount >= (int) maxretry) {
|
||||||
SCPrintf(pCon, eError,
|
SCPrintf(pCon, eLogError,
|
||||||
"ERROR: Aborting %s after %d retries, off position by %f",
|
"ERROR: Aborting %s after %d retries, off position by %f",
|
||||||
self->name, (int) maxretry, target - hard);
|
self->name, (int) maxretry, target - hard);
|
||||||
return HWFault;
|
return HWFault;
|
||||||
}
|
}
|
||||||
self->retryCount++;
|
self->retryCount++;
|
||||||
SCPrintf(pCon, eWarning, "WARNING: %s off position by %f, restarting",
|
SCPrintf(pCon, eLog, "WARNING: %s off position by %f, restarting",
|
||||||
self->name, target - hard);
|
self->name, target - hard);
|
||||||
node = GetHipadabaNode(self->pDescriptor->parNode, "status");
|
node = GetHipadabaNode(self->pDescriptor->parNode, "status");
|
||||||
assert(node != NULL);
|
assert(node != NULL);
|
||||||
@ -279,6 +286,8 @@ static int SecMotorStatus(void *sulf, SConnection * pCon)
|
|||||||
v.v.text);
|
v.v.text);
|
||||||
status = HWFault;
|
status = HWFault;
|
||||||
}
|
}
|
||||||
|
ReleaseHdbValue(&v);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* when terminating: force an update of the position.
|
* when terminating: force an update of the position.
|
||||||
*/
|
*/
|
||||||
@ -608,8 +617,9 @@ pMotor SecMotorInit(char *name)
|
|||||||
free(pM);
|
free(pM);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* TODO: give it a sicsdev here */
|
|
||||||
node = pM->pDescriptor->parNode;
|
node = pM->pDescriptor->parNode;
|
||||||
|
SetHdbProperty(node,"type","drivable");
|
||||||
|
SetHdbProperty(node,"sicsdev", name);
|
||||||
pM->objectNode = node;
|
pM->objectNode = node;
|
||||||
AppendHipadabaCallback(pM->pDescriptor->parNode,
|
AppendHipadabaCallback(pM->pDescriptor->parNode,
|
||||||
MakeHipadabaCallback(SecMotorCallback, pM, NULL));
|
MakeHipadabaCallback(SecMotorCallback, pM, NULL));
|
||||||
@ -674,7 +684,7 @@ pMotor SecMotorInit(char *name)
|
|||||||
SetHdbProperty(child, "__save", "true");
|
SetHdbProperty(child, "__save", "true");
|
||||||
AddHipadabaChild(node, child, NULL);
|
AddHipadabaChild(node, child, NULL);
|
||||||
|
|
||||||
child = MakeSICSHdbPar("precision", usMugger, MakeHdbFloat(.1));
|
child = MakeSICSHdbPar("precision", usMugger, MakeHdbFloat(.01));
|
||||||
SetHdbProperty(child, "__save", "true");
|
SetHdbProperty(child, "__save", "true");
|
||||||
AddHipadabaChild(node, child, NULL);
|
AddHipadabaChild(node, child, NULL);
|
||||||
|
|
||||||
|
2
motreg.c
2
motreg.c
@ -118,7 +118,7 @@ int StartRegMot(pMotReg self, SConnection * pCon, float fValue)
|
|||||||
pDriv->SetValue = self->originalSetValue;
|
pDriv->SetValue = self->originalSetValue;
|
||||||
ret = StartDevice(pServ->pExecutor, self->motorName,
|
ret = StartDevice(pServ->pExecutor, self->motorName,
|
||||||
FindDescriptor(self->motorData),
|
FindDescriptor(self->motorData),
|
||||||
self->motorData, pCon, fValue);
|
self->motorData, pCon, pCon->runLevel, fValue);
|
||||||
/*
|
/*
|
||||||
sprintf(pBueffel,"anticollision started %s to %f",self->motorName,
|
sprintf(pBueffel,"anticollision started %s to %f",self->motorName,
|
||||||
fValue);
|
fValue);
|
||||||
|
@ -92,13 +92,14 @@ static int MMCCStart(void *pData, SConnection * pCon)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < self->nSlaves; i++) {
|
for (i = 0; i < self->nSlaves; i++) {
|
||||||
self->slaves[i]->SetCountParameters(self->slaveData[i],
|
ReleaseCountLock(self->slaves[i]);
|
||||||
|
self->slaves[i]->SetCountParameters(self->slaveData[i],
|
||||||
pCount->pDriv->fPreset,
|
pCount->pDriv->fPreset,
|
||||||
pCount->pDriv->eMode);
|
pCount->pDriv->eMode);
|
||||||
ReleaseCountLock(self->slaves[i]);
|
|
||||||
status = self->slaves[i]->StartCount(self->slaveData[i], pCon);
|
status = self->slaves[i]->StartCount(self->slaveData[i], pCon);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
MMCCHalt(pData);
|
MMCCHalt(pData);
|
||||||
|
ReleaseCountLock(pCount->pCountInt);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,6 +125,7 @@ static int MMCCStatus(void *pData, SConnection * pCon)
|
|||||||
|
|
||||||
if (self->nSlaves == 0) {
|
if (self->nSlaves == 0) {
|
||||||
pCount->pDriv->iErrorCode = NOCOUNTERS;
|
pCount->pDriv->iErrorCode = NOCOUNTERS;
|
||||||
|
ReleaseCountLock(pCount->pCountInt);
|
||||||
return HWFault;
|
return HWFault;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +144,7 @@ static int MMCCStatus(void *pData, SConnection * pCon)
|
|||||||
if (strcmp(pDum->pDescriptor->name, "HistMem") == 0) {
|
if (strcmp(pDum->pDescriptor->name, "HistMem") == 0) {
|
||||||
HistDirty((pHistMem) self->slaveData[i]);
|
HistDirty((pHistMem) self->slaveData[i]);
|
||||||
}
|
}
|
||||||
|
ReleaseCountLock(self->slaves[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
|
@ -445,7 +445,7 @@ static int ClimbDrive(SConnection * pCon, char *name, float value)
|
|||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = Start2Run(pCon, pServ->pSics, name, value);
|
status = Start2Run(pCon, pServ->pSics, name, RUNDRIVE, value);
|
||||||
if (status != 1) {
|
if (status != 1) {
|
||||||
return DRIVEERROR;
|
return DRIVEERROR;
|
||||||
}
|
}
|
||||||
|
2
proxy.c
2
proxy.c
@ -294,7 +294,7 @@ static hdbCallbackReturn ProxyCallback(pHdb node, void *userData,
|
|||||||
GetHdbProperty(node, "proxy", proxyDev, 80);
|
GetHdbProperty(node, "proxy", proxyDev, 80);
|
||||||
status = StartDevice(pServ->pExecutor, proxyDev,
|
status = StartDevice(pServ->pExecutor, proxyDev,
|
||||||
self->pDes, self, pCon,
|
self->pDes, self, pCon,
|
||||||
(float) set->v->v.doubleValue);
|
pCon->runLevel, (float) set->v->v.doubleValue);
|
||||||
if (status == 1) {
|
if (status == 1) {
|
||||||
return hdbContinue;
|
return hdbContinue;
|
||||||
} else {
|
} else {
|
||||||
|
2
remob.c
2
remob.c
@ -169,7 +169,7 @@ static int RemHandle(RemServer * remserver)
|
|||||||
static void RemCopy(RemChannel * rc, SConnection * pCon)
|
static void RemCopy(RemChannel * rc, SConnection * pCon)
|
||||||
{
|
{
|
||||||
if (pCon != NULL && rc->line[0] != '\0') {
|
if (pCon != NULL && rc->line[0] != '\0') {
|
||||||
SCPrintf(pCon, eWarning, " %s", rc->line);
|
SCPrintf(pCon, eValue, " %s", rc->line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +184,8 @@ int StartScanVar(pVarEntry pVar, SConnection * pCon, int i)
|
|||||||
fVal = pVar->fStart + i * pVar->fStep;
|
fVal = pVar->fStart + i * pVar->fStep;
|
||||||
status = StartDevice(pServ->pExecutor,
|
status = StartDevice(pServ->pExecutor,
|
||||||
pVar->Name,
|
pVar->Name,
|
||||||
pDum->pDescriptor, pVar->pObject, pCon, fVal);
|
pDum->pDescriptor, pVar->pObject, pCon,
|
||||||
|
RUNDRIVE, fVal);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
snprintf(pBueffel, 511, "ERROR: Failed to start %s", pVar->Name);
|
snprintf(pBueffel, 511, "ERROR: Failed to start %s", pVar->Name);
|
||||||
SCWrite(pCon, pBueffel, eError);
|
SCWrite(pCon, pBueffel, eError);
|
||||||
|
@ -304,7 +304,9 @@ static int SctMatch(void *data1, void *data2)
|
|||||||
|
|
||||||
return a->node == b->node && strcasecmp(a->name, b->name) == 0;
|
return a->node == b->node && strcasecmp(a->name, b->name) == 0;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* This routine is running the script chain
|
||||||
|
*/
|
||||||
static char *SctActionHandler(void *actionData, char *lastReply,
|
static char *SctActionHandler(void *actionData, char *lastReply,
|
||||||
int commError)
|
int commError)
|
||||||
{
|
{
|
||||||
@ -335,18 +337,41 @@ static char *SctActionHandler(void *actionData, char *lastReply,
|
|||||||
} else {
|
} else {
|
||||||
con = controller->conn;
|
con = controller->conn;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* If this is a followup call, the I/O system will have set the
|
||||||
|
* property result to the data from the device. Read this now and
|
||||||
|
* print it if diagnostics is required.
|
||||||
|
*/
|
||||||
SetProp(node, controller->node, "result", lastReply);
|
SetProp(node, controller->node, "result", lastReply);
|
||||||
script = NULL;
|
script = NULL;
|
||||||
if (!commError && controller->verbose && lastReply != NULL
|
if (!commError && controller->verbose && lastReply != NULL
|
||||||
&& *lastReply != '\0') {
|
&& *lastReply != '\0') {
|
||||||
SCPrintf(con, eLog, "reply : %s", lastReply);
|
SCPrintf(con, eLog, "reply : %s", lastReply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When this is a followup, we use the content of the
|
||||||
|
* state field as the property storing the next script to
|
||||||
|
* run. If this is the start of a chain this is set to the
|
||||||
|
* data->name which is either read or write
|
||||||
|
*/
|
||||||
state = GetProp(node, controller->node, "state");
|
state = GetProp(node, controller->node, "state");
|
||||||
if (state == NULL || strcasecmp(state, "idle") == 0) {
|
if (state == NULL || strcasecmp(state, "idle") == 0) {
|
||||||
state = data->name;
|
state = data->name;
|
||||||
SetProp(node, controller->node, "state", state);
|
SetProp(node, controller->node, "state", state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sometimes one wishes to call multiple scripts in succession
|
||||||
|
* before returning into I/O. Such scripts then do not set the
|
||||||
|
* send property. The loop is taking care of this. Not more
|
||||||
|
* then 10 scripts can be changed in this way.
|
||||||
|
*/
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
|
/*
|
||||||
|
* read the script to invoke from the property living
|
||||||
|
* in state
|
||||||
|
*/
|
||||||
script = GetProp(node, controller->node, state);
|
script = GetProp(node, controller->node, state);
|
||||||
if (script == NULL)
|
if (script == NULL)
|
||||||
script = state;
|
script = state;
|
||||||
@ -357,12 +382,18 @@ static char *SctActionHandler(void *actionData, char *lastReply,
|
|||||||
script = errorScript;
|
script = errorScript;
|
||||||
commError = 0;
|
commError = 0;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Set the context and invoke the script
|
||||||
|
*/
|
||||||
script = strdup(script);
|
script = strdup(script);
|
||||||
sct->sendNode = node;
|
sct->sendNode = node;
|
||||||
sct->sendCalled = 0;
|
sct->sendCalled = 0;
|
||||||
ret = SctCallInContext(con, script, node, controller, &result);
|
ret = SctCallInContext(con, script, node, controller, &result);
|
||||||
sct->sendNode = NULL;
|
sct->sendNode = NULL;
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
/*
|
||||||
|
* an error occurred in the script: complain bitterly
|
||||||
|
*/
|
||||||
snprintf(eprop, sizeof eprop, "error_during_%s", data->name);
|
snprintf(eprop, sizeof eprop, "error_during_%s", data->name);
|
||||||
emsg = GetHdbProp(node, eprop);
|
emsg = GetHdbProp(node, eprop);
|
||||||
if (emsg == NULL || con != controller->conn) {
|
if (emsg == NULL || con != controller->conn) {
|
||||||
@ -392,13 +423,24 @@ static char *SctActionHandler(void *actionData, char *lastReply,
|
|||||||
free(script);
|
free(script);
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* The script executed OK.
|
||||||
|
* The next state is the result
|
||||||
|
*/
|
||||||
state = result;
|
state = result;
|
||||||
|
/*
|
||||||
|
* if the new state is idle, clean everything up
|
||||||
|
* and terminate the script chain
|
||||||
|
*/
|
||||||
if (strcasecmp(state, "idle") == 0 || strcasecmp(state, "unpoll") == 0) {
|
if (strcasecmp(state, "idle") == 0 || strcasecmp(state, "unpoll") == 0) {
|
||||||
|
/*
|
||||||
|
* send an O.k. if there was no othe rreply on write's
|
||||||
|
*/
|
||||||
if (queueData == data && !data->answered) {
|
if (queueData == data && !data->answered) {
|
||||||
if (queueData->inMacro == 0) {
|
if (queueData->inMacro == 0) {
|
||||||
iMacro = SCinMacro(con);
|
iMacro = SCinMacro(con);
|
||||||
con->iMacro = 0;
|
con->iMacro = 0;
|
||||||
SCWrite(con, "o.k.", eWarning);
|
SCWrite(con, "o.k.", eValue);
|
||||||
SCsetMacro(con, iMacro);
|
SCsetMacro(con, iMacro);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -418,9 +460,16 @@ static char *SctActionHandler(void *actionData, char *lastReply,
|
|||||||
free(script);
|
free(script);
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* set the state property to the next state for
|
||||||
|
* the next invocation of this routine
|
||||||
|
*/
|
||||||
SetProp(node, controller->node, "state", state);
|
SetProp(node, controller->node, "state", state);
|
||||||
free(script);
|
free(script);
|
||||||
script = NULL;
|
script = NULL;
|
||||||
|
/*
|
||||||
|
* If there is data to send, check it and do so
|
||||||
|
*/
|
||||||
if (sct->sendCalled) {
|
if (sct->sendCalled) {
|
||||||
send = GetProp(node, controller->node, "send");
|
send = GetProp(node, controller->node, "send");
|
||||||
if (send == NULL)
|
if (send == NULL)
|
||||||
@ -470,6 +519,10 @@ static int SctMatchNode(void *vNode, void *vData)
|
|||||||
return node == d->node;
|
return node == d->node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the read callback for nodes particpating in the
|
||||||
|
* scriptcontext system
|
||||||
|
*/
|
||||||
static hdbCallbackReturn SctMainCallback(Hdb * node, void *userData,
|
static hdbCallbackReturn SctMainCallback(Hdb * node, void *userData,
|
||||||
hdbMessage * msg)
|
hdbMessage * msg)
|
||||||
{
|
{
|
||||||
@ -530,7 +583,10 @@ static hdbCallbackReturn SctMainCallback(Hdb * node, void *userData,
|
|||||||
|
|
||||||
return hdbContinue;
|
return hdbContinue;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* This is the callback registered for nodes which
|
||||||
|
* are written too.
|
||||||
|
*/
|
||||||
static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
|
static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
|
||||||
hdbMessage * msg)
|
hdbMessage * msg)
|
||||||
{
|
{
|
||||||
@ -602,6 +658,9 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
|
|||||||
prio = WritePRIO;
|
prio = WritePRIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check for duplicate sets on a node.
|
||||||
|
*/
|
||||||
if (data->conCtx != NULL) {
|
if (data->conCtx != NULL) {
|
||||||
if (data->inMacro == 0) {
|
if (data->inMacro == 0) {
|
||||||
GetHdbPath(node, path, sizeof path);
|
GetHdbPath(node, path, sizeof path);
|
||||||
@ -610,6 +669,11 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
|
|||||||
"%s target changed to %s before completion", path,
|
"%s target changed to %s before completion", path,
|
||||||
GetCharArray(text));
|
GetCharArray(text));
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* the node has already been queued for execution. But as we never
|
||||||
|
* know if the script chain is already running, the only clean
|
||||||
|
* solution is to requeue the node.
|
||||||
|
*/
|
||||||
SCDeleteConnection(data->conCtx);
|
SCDeleteConnection(data->conCtx);
|
||||||
}
|
}
|
||||||
DeleteDynString(text);
|
DeleteDynString(text);
|
||||||
@ -624,11 +688,11 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
|
|||||||
|
|
||||||
mm = GetHdbUpdateMessage(msg);
|
mm = GetHdbUpdateMessage(msg);
|
||||||
if (mm != NULL) {
|
if (mm != NULL) {
|
||||||
if (queueData != NULL && queueData->conCtx != NULL && !data->answered) {
|
if (queueData != NULL && queueData->conCtx != NULL && queueData->answered != 1) {
|
||||||
/* update called from a write action */
|
/* update called from a write action */
|
||||||
text = formatValue(*(mm->v), node);
|
text = formatValue(*(mm->v), node);
|
||||||
if (queueData->inMacro == 0 && queueData->node == node) {
|
if (queueData->inMacro == 0 && queueData->node == node) {
|
||||||
data->answered = 1;
|
queueData->answered = 1;
|
||||||
iMacro = SCinMacro(queueData->conCtx);
|
iMacro = SCinMacro(queueData->conCtx);
|
||||||
SCsetMacro(queueData->conCtx, 0);
|
SCsetMacro(queueData->conCtx, 0);
|
||||||
sicsCommand = GetHdbProp(node, "sicscommand");
|
sicsCommand = GetHdbProp(node, "sicscommand");
|
||||||
@ -915,7 +979,8 @@ void SctQueueNode(SctController * controller, Hdb * node,
|
|||||||
data->node = node;
|
data->node = node;
|
||||||
data->name = strdup(action);
|
data->name = strdup(action);
|
||||||
data->conCtx = NULL;
|
data->conCtx = NULL;
|
||||||
|
data->answered = 1;
|
||||||
|
|
||||||
if (!DevQueue(data->controller->devser, data, prio,
|
if (!DevQueue(data->controller->devser, data, prio,
|
||||||
SctWriteHandler, SctMatch, SctKillData)) {
|
SctWriteHandler, SctMatch, SctKillData)) {
|
||||||
if (data->name != NULL) {
|
if (data->name != NULL) {
|
||||||
|
@ -614,13 +614,13 @@ int MonoRun(pSicsSelector self, SConnection * pCon, float fWaveLength)
|
|||||||
/* start each motor in turn */
|
/* start each motor in turn */
|
||||||
iRet = StartDevice(GetExecutor(), self->pTheta->name,
|
iRet = StartDevice(GetExecutor(), self->pTheta->name,
|
||||||
self->pTheta->pDescriptor,
|
self->pTheta->pDescriptor,
|
||||||
self->pTheta, pCon, sNeu.fTheta);
|
self->pTheta, pCon, pCon->runLevel, sNeu.fTheta);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
iRet = StartDevice(GetExecutor(), self->pTwoTheta->name,
|
iRet = StartDevice(GetExecutor(), self->pTwoTheta->name,
|
||||||
self->pTwoTheta->pDescriptor,
|
self->pTwoTheta->pDescriptor,
|
||||||
self->pTwoTheta, pCon, sNeu.fTwoTheta);
|
self->pTwoTheta, pCon, pCon->runLevel, sNeu.fTwoTheta);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -630,7 +630,7 @@ int MonoRun(pSicsSelector self, SConnection * pCon, float fWaveLength)
|
|||||||
if (self->pBend1) {
|
if (self->pBend1) {
|
||||||
iRet = StartDevice(GetExecutor(), self->pBend1->name,
|
iRet = StartDevice(GetExecutor(), self->pBend1->name,
|
||||||
self->pBend1->pDescriptor,
|
self->pBend1->pDescriptor,
|
||||||
self->pBend1, pCon, sNeu.fVert);
|
self->pBend1, pCon, pCon->runLevel, sNeu.fVert);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -639,7 +639,7 @@ int MonoRun(pSicsSelector self, SConnection * pCon, float fWaveLength)
|
|||||||
if (self->pBend2) {
|
if (self->pBend2) {
|
||||||
iRet = StartDevice(GetExecutor(), self->pBend2->name,
|
iRet = StartDevice(GetExecutor(), self->pBend2->name,
|
||||||
self->pBend2->pDescriptor,
|
self->pBend2->pDescriptor,
|
||||||
self->pBend2, pCon, sNeu.fHor);
|
self->pBend2, pCon, pCon->runLevel, sNeu.fHor);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -687,6 +687,11 @@ int SICSHdbAdapter(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
*/
|
*/
|
||||||
pMot = (pMotor) FindCommandData(pSics, argv[2], "Motor");
|
pMot = (pMotor) FindCommandData(pSics, argv[2], "Motor");
|
||||||
if (pMot != NULL) {
|
if (pMot != NULL) {
|
||||||
|
if(pMot->ParArray == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: secong generation motors need to be linked rather then adapted",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
node = CreateMotorAdapter(argv[3], pMot);
|
node = CreateMotorAdapter(argv[3], pMot);
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
SCWrite(pCon, "ERROR: out of memory creating motor node", eError);
|
SCWrite(pCon, "ERROR: out of memory creating motor node", eError);
|
||||||
|
@ -258,10 +258,10 @@ static hdbCallbackReturn SICSDriveCallback(pHdb node, void *userData,
|
|||||||
assert(pCon != NULL && dum != NULL);
|
assert(pCon != NULL && dum != NULL);
|
||||||
if (GetHdbProperty(node, "sicsdev", pSicsdev, 79)) {
|
if (GetHdbProperty(node, "sicsdev", pSicsdev, 79)) {
|
||||||
status = StartDevice(pServ->pExecutor, pSicsdev, dum->pDescriptor,
|
status = StartDevice(pServ->pExecutor, pSicsdev, dum->pDescriptor,
|
||||||
userData, pCon, (float) v.v.doubleValue);
|
userData, pCon, RUNDRIVE, (float) v.v.doubleValue);
|
||||||
} else {
|
} else {
|
||||||
status = StartDevice(pServ->pExecutor, node->name, dum->pDescriptor,
|
status = StartDevice(pServ->pExecutor, node->name, dum->pDescriptor,
|
||||||
userData, pCon, (float) v.v.doubleValue);
|
userData, pCon, pCon->runLevel, (float) v.v.doubleValue);
|
||||||
}
|
}
|
||||||
if (status == 1) {
|
if (status == 1) {
|
||||||
return hdbContinue;
|
return hdbContinue;
|
||||||
|
@ -52,6 +52,7 @@ static void saveSICSNode(pHdb node, char *prefix, FILE * fd)
|
|||||||
fprintf(fd, "%s %s\n", prefix, GetCharArray(data));
|
fprintf(fd, "%s %s\n", prefix, GetCharArray(data));
|
||||||
DeleteDynString(data);
|
DeleteDynString(data);
|
||||||
}
|
}
|
||||||
|
ReleaseHdbValue(&v);
|
||||||
child = node->child;
|
child = node->child;
|
||||||
while (child != NULL) {
|
while (child != NULL) {
|
||||||
snprintf(newprefix, 1024, "%s/%s", prefix, child->name);
|
snprintf(newprefix, 1024, "%s/%s", prefix, child->name);
|
||||||
|
14
stdscan.c
14
stdscan.c
@ -846,9 +846,8 @@ int ScanDrive(pScanData self, int iPoint)
|
|||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
/* wait for finish */
|
/* wait for finish */
|
||||||
lTask = GetDevexecID(pServ->pExecutor);
|
while(DevExecLevelRunning(pServ->pExecutor, RUNDRIVE)){
|
||||||
if (lTask > 0) {
|
TaskYield(pServ->pTasker);
|
||||||
TaskWait(pServ->pTasker, lTask);
|
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -890,17 +889,16 @@ int ScanCount(pScanData self, int iPoint)
|
|||||||
iRet = StartDevice(pServ->pExecutor,
|
iRet = StartDevice(pServ->pExecutor,
|
||||||
"ScanCounter",
|
"ScanCounter",
|
||||||
pDum->pDescriptor,
|
pDum->pDescriptor,
|
||||||
self->pCounterData, self->pCon, self->fPreset);
|
self->pCounterData, self->pCon, RUNDRIVE,
|
||||||
|
self->fPreset);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
SCWrite(self->pCon, "ERROR: Cannot Count, Scan aborted", eLogError);
|
SCWrite(self->pCon, "ERROR: Cannot Count, Scan aborted", eLogError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
SetStatus(eCounting);
|
SetStatus(eCounting);
|
||||||
/* wait for finish */
|
/* wait for finish */
|
||||||
lTask = GetDevexecID(pServ->pExecutor);
|
while(DevExecLevelRunning(pServ->pExecutor, RUNDRIVE)){
|
||||||
if (lTask > 0);
|
TaskYield(pServ->pTasker);
|
||||||
{
|
|
||||||
TaskWait(pServ->pTasker, lTask);
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -646,7 +646,7 @@ static int TASUBScanDrive(pScanData self, int iPoint)
|
|||||||
pVar = (pVarEntry) pPtr;
|
pVar = (pVarEntry) pPtr;
|
||||||
if (pVar) {
|
if (pVar) {
|
||||||
StartMotor(pServ->pExecutor, self->pSics, self->pCon, pVar->Name,
|
StartMotor(pServ->pExecutor, self->pSics, self->pCon, pVar->Name,
|
||||||
pVar->fStart + iPoint * pVar->fStep);
|
RUNDRIVE, pVar->fStart + iPoint * pVar->fStep);
|
||||||
/*
|
/*
|
||||||
Ignore errors. TAS scans continues when a motor runs into
|
Ignore errors. TAS scans continues when a motor runs into
|
||||||
a limit.
|
a limit.
|
||||||
|
6
velo.c
6
velo.c
@ -516,7 +516,7 @@ int VSSetTiltRot(pVelSel self, SConnection * pCon, float fNewRot,
|
|||||||
if (fDelta > ObVal(self->pPar, TILTPREC)) { /* yes */
|
if (fDelta > ObVal(self->pPar, TILTPREC)) { /* yes */
|
||||||
/* first stop the Rotation of the selector */
|
/* first stop the Rotation of the selector */
|
||||||
iRet = StartDevice(GetExecutor(), "Velocity Selector Rot",
|
iRet = StartDevice(GetExecutor(), "Velocity Selector Rot",
|
||||||
self->pDes, self, pCon, -10.);
|
self->pDes, self, pCon, RUNDRIVE, -10.);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -539,7 +539,7 @@ int VSSetTiltRot(pVelSel self, SConnection * pCon, float fNewRot,
|
|||||||
SCSetRights(pCon, usInternal);
|
SCSetRights(pCon, usInternal);
|
||||||
iRet = StartDevice(GetExecutor(), "Velocity Selector Tilt",
|
iRet = StartDevice(GetExecutor(), "Velocity Selector Tilt",
|
||||||
self->pTilt->pDescriptor, self->pTilt,
|
self->pTilt->pDescriptor, self->pTilt,
|
||||||
pCon, fNewTilt);
|
pCon, RUNDRIVE, fNewTilt);
|
||||||
|
|
||||||
/* wait for this to finish */
|
/* wait for this to finish */
|
||||||
SCWrite(pCon, "Driving tilt-angle", eWarning);
|
SCWrite(pCon, "Driving tilt-angle", eWarning);
|
||||||
@ -559,7 +559,7 @@ int VSSetTiltRot(pVelSel self, SConnection * pCon, float fNewRot,
|
|||||||
|
|
||||||
/* drive rotation */
|
/* drive rotation */
|
||||||
iRet = StartDevice(GetExecutor(), "Velocity Selector Rot",
|
iRet = StartDevice(GetExecutor(), "Velocity Selector Rot",
|
||||||
self->pDes, self, pCon, fNewRot);
|
self->pDes, self, pCon, RUNDRIVE, fNewRot);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user