- 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:
koennecke
2009-04-17 12:52:01 +00:00
parent 50b0a5c4a7
commit 99d2485d22
39 changed files with 422 additions and 200 deletions

View File

@ -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;

View File

@ -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;
} }
} }

View File

@ -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)
{ {

View File

@ -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? */

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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
View File

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

View File

@ -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@*/@\\

View File

@ -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
View File

@ -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]);

View File

@ -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[]);

View File

@ -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);

View File

@ -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;
} }

View File

@ -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;

View File

@ -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);
} }

View File

@ -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_*/

View File

@ -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);

View File

@ -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");

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -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;
} }

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;
} }

View File

@ -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 {

View File

@ -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);
} }
} }

View File

@ -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);

View File

@ -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) {

View File

@ -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;
} }

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
} }

View File

@ -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
View File

@ -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;
} }