Merge branch 'master' into maverick

- Removed epicsmotor from motor.c
- Fixed a bad define in tasscanub.h
Conflicts:
	makefile_macosx
This commit is contained in:
2015-03-17 14:01:40 +01:00
85 changed files with 2332 additions and 459 deletions

View File

@ -543,6 +543,7 @@ void DeleteInterp(SicsInterp * self)
call KillSicsUnknown instead to clean up all memory properly. M.Z., Apr 05 call KillSicsUnknown instead to clean up all memory properly. M.Z., Apr 05
*/ */
Tcl_DeleteInterp(pTcl);
KillSicsUnknown(); KillSicsUnknown();
} }

View File

@ -155,7 +155,7 @@ void *FindCommandData(SicsInterp * pSics, char *name, char *comclass);
*/ */
pObjectDescriptor FindCommandDescriptor(SicsInterp * pSics, char *name); pObjectDescriptor FindCommandDescriptor(SicsInterp * pSics, char *name);
/*------------------------------------------------------------------------ /*---------------------------------------------------------------------
FindDrivable tries to find Drivable object by the name given. Returns a FindDrivable tries to find Drivable object by the name given. Returns a
pointer to the drivable interface in the case of success, NULL in pointer to the drivable interface in the case of success, NULL in
case of failure. In order to save me fixing header files the pointer must case of failure. In order to save me fixing header files the pointer must

View File

@ -36,11 +36,18 @@ long sumWindow(int *data, int xstart, int xend, int xlength,
} }
for(j = ystart; j < yend; j++){ /* for(j = ystart; j < yend; j++){ */
row = data + j*xlength; /* row = data + j*xlength; */
/* for(i = xstart; i < xend; i++){ */
/* result += row[i]; */
/* } */
/* } */
for(i = xstart; i < xend; i++){ for(i = xstart; i < xend; i++){
result += row[i]; row = data + i*ylength;
for(j = ystart; j < yend; j++){
result += row[j];
} }
} }
return result; return result;
} }

View File

@ -45,7 +45,8 @@
#define MAXCONNECTIONS 1024 #define MAXCONNECTIONS 1024
#define RBUFFERSIZE 262144 /* 256kb */ #define RBUFFERSIZE 262144 /* 256kb */
#define WBUFFERSIZE 20*262144 #define WBUFFERSIZE 20*262144
/* #define WBUFFERSIZE 100*262144 /* /* #define WBUFFERSIZE 100*262144 */
#define MAXWBUFFERSIZE 128*1000*1024
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
typedef struct { typedef struct {
int socket; int socket;
@ -204,7 +205,7 @@ int ANETregisterSocket(int socket)
flags =1; flags =1;
setsockopt(socket,IPPROTO_TCP,TCP_NODELAY,(char *) &flags, sizeof(int)); setsockopt(socket,IPPROTO_TCP,TCP_NODELAY,(char *) &flags, sizeof(int));
socke.readBuffer = MakeRWPuffer(RBUFFERSIZE); socke.readBuffer = MakeRWPuffer(RBUFFERSIZE);
socke.writeBuffer = MakeRWPuffer(WBUFFERSIZE); socke.writeBuffer = MakeBigRWPuffer(WBUFFERSIZE, MAXWBUFFERSIZE);
if (socke.readBuffer == NULL || socke.writeBuffer == NULL) { if (socke.readBuffer == NULL || socke.writeBuffer == NULL) {
return ANETMEM; return ANETMEM;
} }
@ -247,6 +248,7 @@ int ANETconnect(char *name, int iPort)
status = connect(socke, (struct sockaddr *) &addresse, status = connect(socke, (struct sockaddr *) &addresse,
sizeof(struct sockaddr_in)); sizeof(struct sockaddr_in));
if (status < 0) { if (status < 0) {
close(socke);
anetLog(ANETERROR, "Failed to open socket to %s:%d", name, iPort); anetLog(ANETERROR, "Failed to open socket to %s:%d", name, iPort);
return ANETOPENFAIL; return ANETOPENFAIL;
} }
@ -497,7 +499,20 @@ int ANETinfo(int handle, char *hostname, int hostnameLen)
} }
return 1; return 1;
} }
/*---------------------------------------------------------------------------*/
int ANETcanWrite(int handle, void *buffer, int count)
{
pSocketDescriptor con = NULL;
int status;
con = findSocketDescriptor(handle);
if (con == NULL) {
return ANETDISCONNECTED;
} else {
ANETprocess();
return CanStoreRWBuffer(con->writeBuffer, buffer, count);
}
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int ANETwrite(int handle, void *buffer, int count) int ANETwrite(int handle, void *buffer, int count)
{ {

View File

@ -145,6 +145,14 @@ int ANETinfo(int handle, char *hostname, int hostNameLen);
* \return 1 on success, 0 on failure * \return 1 on success, 0 on failure
*/ */
int ANETwrite(int handle, void *buffer, int count); int ANETwrite(int handle, void *buffer, int count);
/**
* \brief Test if the buffer can be written to the network
* \param handle The handle for the connection
* \param buffer A pointer to the data to write
* \param count The number of bytes to write.
* \return 1 when possible, 0 when buffer overrun
*/
int ANETcanWrite(int handle, void *buffer, int count);
/** /**
* \brief copy at max bufferLength bytes into buffer. The data is not deleted from * \brief copy at max bufferLength bytes into buffer. The data is not deleted from
* the read buffer yet. * the read buffer yet.

View File

@ -9,7 +9,7 @@
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
#ifndef COMMANDLOG #ifndef COMMANDLOG
#define COMMANDLOG #define COMMANDLOG
void WriteToCommandLog(char *prompt, char *pText); void WriteToCommandLog(const char *prompt, const char *pText);
void WriteToCommandLogId(char *prompt, int id, char *text); void WriteToCommandLogId(char *prompt, int id, char *text);
void WriteToCommandLogCmd(int id, char *text); void WriteToCommandLogCmd(int id, char *text);
int CompactCommandLog(void); int CompactCommandLog(void);

3
cone.c
View File

@ -171,7 +171,6 @@ static long ConeSetValue(void *pData, SConnection * pCon, float fVal)
*/ */
SICSHdbGetPar(obj, pCon, "target", &v); SICSHdbGetPar(obj, pCon, "target", &v);
target.h = v.v.floatArray[0]; target.h = v.v.floatArray[0];
target.k = v.v.floatArray[1];
target.l = v.v.floatArray[2]; target.l = v.v.floatArray[2];
SICSHdbGetPar(obj, pCon, "qscale", &v); SICSHdbGetPar(obj, pCon, "qscale", &v);
/* /*
@ -198,7 +197,7 @@ static long ConeSetValue(void *pData, SConnection * pCon, float fVal)
mat_free(csToPsi); mat_free(csToPsi);
if (status != 1) { if (status != 1) {
SCWrite(pCon, "ERROR: cannot get cone vector into scattering position", SCWrite(pCon, "ERROR: cannot get cone vector into scattering position",
eError); eLogError);
SCSetInterrupt(pCon, eAbortOperation); SCSetInterrupt(pCon, eAbortOperation);
return 0; return 0;
} }

View File

@ -1016,7 +1016,6 @@ int SCPureSockWrite(SConnection * self, char *buffer, int iOut)
return 1; return 1;
} }
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
special for ClientLog. Do not use elsewhere without check special for ClientLog. Do not use elsewhere without check
----------------------------------------------------------------------------*/ ----------------------------------------------------------------------------*/
@ -1044,6 +1043,18 @@ int SCLogWrite(SConnection * self, char *buffer, int iOut)
if(pPtr != pBueffel){ if(pPtr != pBueffel){
free(pPtr); free(pPtr);
} }
} else if(self->iProtocolID == 2) {
if (strlen(buffer) + 30 > 1024) {
pPtr = (char *) malloc((strlen(buffer) + 30) * sizeof(char));
memset(pPtr, 0, strlen(buffer) + 20);
} else {
pPtr = pBueffel;
}
sprintf(pPtr,"%s@@%s",buffer,pCode[iOut]);
testAndWriteSocket(self, pPtr, iOut);
if(pPtr != pBueffel){
free(pPtr);
}
} else { } else {
testAndWriteSocket(self, buffer, iOut); testAndWriteSocket(self, buffer, iOut);
} }
@ -1178,6 +1189,8 @@ int SCWriteZipped(SConnection * self, char *pName, void *pData,
SCWrite(self, "ERROR: no data to write in SCWriteZiped", eError); SCWrite(self, "ERROR: no data to write in SCWriteZiped", eError);
return 0; return 0;
} }
pBuf = malloc(iDataLen*sizeof(char)); pBuf = malloc(iDataLen*sizeof(char));
memset(pBuf,0,iDataLen*sizeof(char)); memset(pBuf,0,iDataLen*sizeof(char));
@ -1204,6 +1217,19 @@ int SCWriteZipped(SConnection * self, char *pName, void *pData,
} }
compressedLength = compStream.total_out; compressedLength = compStream.total_out;
/*
If data is large, test if we can do it
*/
if(compressedLength > 2*1000*1024) {
if(!ANETcanWrite(self->sockHandle,pData,compressedLength)){
SCWrite(self,"WARNING: skipping excessive data in SCWriteZipped",eLogError);
deflateEnd(&compStream);
free(pBuf);
return 0;
}
}
/* write header line */ /* write header line */
memset(outBuf, 0, 65536); memset(outBuf, 0, 65536);
@ -1270,6 +1296,16 @@ int SCWriteBinary(SConnection * self, char *pName, void *pData,
return 0; return 0;
} }
/*
If data is large, test if we can do it
*/
if(iDataLen > 2*1000*1024) {
if(!ANETcanWrite(self->sockHandle,pData,iDataLen)){
SCWrite(self,"WARNING: skipping excessive data in SCWriteBinary",eLogError);
return 0;
}
}
/* write header line */ /* write header line */
memset(outBuf, 0, 65536); memset(outBuf, 0, 65536);
@ -1521,8 +1557,6 @@ int SCPrompt(SConnection * pCon, char *pPrompt, char *pResult, int iLen)
SCWrite(pCon, pPrompt, eWarning); SCWrite(pCon, pPrompt, eWarning);
master = SCfindMaster(pCon); master = SCfindMaster(pCon);
eOld = GetStatus();
SetStatus(eInput);
CostaUnlock(master->pStack); CostaUnlock(master->pStack);
while (1) { while (1) {
/* /*
@ -1542,14 +1576,12 @@ int SCPrompt(SConnection * pCon, char *pPrompt, char *pResult, int iLen)
/* do we have data ? */ /* do we have data ? */
iRet = CostaPop(master->pStack, &pPtr); iRet = CostaPop(master->pStack, &pPtr);
if (iRet == 1) { if (iRet == 1) {
SetStatus(eOld);
CostaLock(master->pStack); CostaLock(master->pStack);
strlcpy(pResult, pPtr, iLen); strlcpy(pResult, pPtr, iLen);
WriteToCommandLogId(" prompted>", pCon->sockHandle, pPtr); WriteToCommandLogId(" prompted>", pCon->sockHandle, pPtr);
return 1; return 1;
} }
} }
SetStatus(eOld);
CostaLock(master->pStack); CostaLock(master->pStack);
return 0; return 0;
} }
@ -1570,8 +1602,6 @@ int SCPromptTMO(SConnection * pCon, char *pPrompt, char *pResult, int iLen, int
SCWrite(pCon, pPrompt, eWarning); SCWrite(pCon, pPrompt, eWarning);
master = SCfindMaster(pCon); master = SCfindMaster(pCon);
eOld = GetStatus();
SetStatus(eInput);
CostaUnlock(master->pStack); CostaUnlock(master->pStack);
for(i = 0; i < timeout; i++) { for(i = 0; i < timeout; i++) {
/* /*
@ -1591,14 +1621,12 @@ int SCPromptTMO(SConnection * pCon, char *pPrompt, char *pResult, int iLen, int
/* do we have data ? */ /* do we have data ? */
iRet = CostaPop(master->pStack, &pPtr); iRet = CostaPop(master->pStack, &pPtr);
if (iRet == 1) { if (iRet == 1) {
SetStatus(eOld);
CostaLock(master->pStack); CostaLock(master->pStack);
strlcpy(pResult, pPtr, iLen); strlcpy(pResult, pPtr, iLen);
WriteToCommandLogId(" prompted>", pCon->sockHandle, pPtr); WriteToCommandLogId(" prompted>", pCon->sockHandle, pPtr);
return 1; return 1;
} }
} }
SetStatus(eOld);
CostaLock(master->pStack); CostaLock(master->pStack);
return 0; return 0;
} }
@ -1724,10 +1752,8 @@ int SCInvoke(SConnection * self, SicsInterp * pInter, char *pCommand)
return 0; return 0;
} }
strlcpy(pCopy->deviceID, pBueffel, SCDEVIDLEN); strlcpy(pCopy->deviceID, pBueffel, SCDEVIDLEN);
/* SCAdvanceContext(self,pBueffel); */
traceCommand(ConID(self),"in:%s", pCommand); traceCommand(ConID(self),"in:%s", pCommand);
iRet = InterpExecute(pInter, pCopy, pCommand); iRet = InterpExecute(pInter, pCopy, pCommand);
/* SCPopContext(self); */
SCDeleteConnection(pCopy); SCDeleteConnection(pCopy);
StatusFileTask(NULL); /* save changed parameters */ StatusFileTask(NULL); /* save changed parameters */

View File

@ -265,7 +265,7 @@ static int CheckCountStatus(void *pData, SConnection * pCon)
int eCt; int eCt;
char pError[80], pBueffel[132]; char pError[80], pBueffel[132];
int iErr; int iErr;
float fControl, rate; float fControl = .0, rate;
MonEvent sMon; MonEvent sMon;
self = (pCounter) pData; self = (pCounter) pData;
@ -409,8 +409,6 @@ int DoCount(pCounter self, float fPreset, SConnection * pCon, int iBlock)
return 0; return 0;
} }
eOld = GetStatus();
SetStatus(eCounting);
/* set Preset */ /* set Preset */
SetCounterPreset(self, fPreset); SetCounterPreset(self, fPreset);
@ -423,7 +421,6 @@ int DoCount(pCounter self, float fPreset, SConnection * pCon, int iBlock)
iRet = StartDevice(GetExecutor(), self->name, self->pDes, self, pCon, iRet = StartDevice(GetExecutor(), self->name, self->pDes, self, pCon,
level, fPreset); level, fPreset);
if (!iRet) { if (!iRet) {
SetStatus(eOld);
SCWrite(pCon, "Counting aborted", eError); SCWrite(pCon, "Counting aborted", eError);
return 0; return 0;
} }
@ -444,7 +441,6 @@ int DoCount(pCounter self, float fPreset, SConnection * pCon, int iBlock)
SCWrite(pCon, "Counting finished", eValue); SCWrite(pCon, "Counting finished", eValue);
iRet = 1; iRet = 1;
} }
SetStatus(eOld);
return iRet; return iRet;
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
@ -835,7 +831,8 @@ int CountAction(SConnection * pCon, SicsInterp * pSics, void *pData,
{"getpar", 2, {FUPATEXT, FUPAOPT}}, {"getpar", 2, {FUPATEXT, FUPAOPT}},
{"getnmon", 0, {0, 0}}, {"getnmon", 0, {0, 0}},
{"state", 0, {0, 0}}, {"state", 0, {0, 0}},
{"error", 0, {0, 0}} {"error", 0, {0, 0}},
{"countstatus", 0, {0, 0}}
}; };
char *pMode[] = { char *pMode[] = {
"timer", "timer",
@ -852,7 +849,7 @@ int CountAction(SConnection * pCon, SicsInterp * pSics, void *pData,
argtolower(argc, argv); argtolower(argc, argv);
argx = &argv[1]; argx = &argv[1];
iRet = iRet =
EvaluateFuPa((pFuncTemplate) & ActionTemplate, 25, argc - 1, argx, EvaluateFuPa((pFuncTemplate) & ActionTemplate, 26, argc - 1, argx,
&PaRes); &PaRes);
if (iRet < 0) { if (iRet < 0) {
snprintf(pBueffel, 255,"%s", PaRes.pError); snprintf(pBueffel, 255,"%s", PaRes.pError);
@ -961,6 +958,7 @@ int CountAction(SConnection * pCon, SicsInterp * pSics, void *pData,
SCSendOK(pCon); SCSendOK(pCon);
return 1; return 1;
case 11: /* status */ case 11: /* status */
case 25:
self->pCountInt->TransferData(self, pCon); self->pCountInt->TransferData(self, pCon);
if (GetCounterMode(self) == ePreset) { if (GetCounterMode(self) == ePreset) {
lVal = GetCounterPreset(self); lVal = GetCounterPreset(self);

View File

@ -9,6 +9,7 @@
* *
* Mark Koennecke, February 2009 * Mark Koennecke, February 2009
*/ */
#include <math.h>
#include <time.h> #include <time.h>
#include <sics.h> #include <sics.h>
#include <counter.h> #include <counter.h>
@ -507,6 +508,41 @@ static int InterestCmd(pSICSOBJ ccmd, SConnection * con,
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
static int CountStatusCmd(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
float preset, done;
int exponent;
pHdb node, data;
node = GetHipadabaNode(ccmd->objectNode,"preset");
assert(node != NULL);
preset = node->value.v.doubleValue;
node = GetHipadabaNode(ccmd->objectNode,"mode");
assert(node != NULL);
strtolower(node->value.v.text);
if(strcmp(node->value.v.text,"timer") == 0) {
data = GetHipadabaNode(ccmd->objectNode,"time");
assert(data != NULL);
done = data->value.v.doubleValue;
} else {
data = GetHipadabaNode(ccmd->objectNode,"values");
assert(data != NULL);
done = data->value.v.intArray[0];
data = GetHipadabaNode(ccmd->objectNode,"exponent");
assert(data != NULL);
exponent = data->value.v.intValue;
if(exponent != 0){
done /= pow(10,exponent);
}
}
SCPrintf(con,eValue,"%s.CountStatus = %f %f",
ccmd->objectNode->name, preset, done);
return 1;
}
/*--------------------------------------------------------------------------*/
pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length) pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
{ {
pCounter pRes = NULL; pCounter pRes = NULL;
@ -634,6 +670,7 @@ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
child = AddSICSHdbPar(node,"pause", usUser, MakeSICSFunc(PauseCmd)); child = AddSICSHdbPar(node,"pause", usUser, MakeSICSFunc(PauseCmd));
child = AddSICSHdbPar(node,"continue", usUser, MakeSICSFunc(ContinueCmd)); child = AddSICSHdbPar(node,"continue", usUser, MakeSICSFunc(ContinueCmd));
child = AddSICSHdbPar(node,"interest", usUser, MakeSICSFunc(InterestCmd)); child = AddSICSHdbPar(node,"interest", usUser, MakeSICSFunc(InterestCmd));
child = AddSICSHdbPar(node,"countstatus", usUser, MakeSICSFunc(CountStatusCmd));
return pRes; return pRes;
} }

View File

@ -188,6 +188,7 @@ pExeList CreateExeList(pTaskMan pTask)
pRes->pCall = CreateCallBackInterface(); pRes->pCall = CreateCallBackInterface();
pRes->lastRun = time(NULL); pRes->lastRun = time(NULL);
pRes->pDes->GetInterface = DevexecInterface; pRes->pDes->GetInterface = DevexecInterface;
pRes->instStatus = eEager;
return pRes; return pRes;
} }
@ -295,7 +296,6 @@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
taskID = StartDriveTask(pData, pCon, name, fNew); taskID = StartDriveTask(pData, pCon, name, fNew);
if(taskID > 0 && self->instStatus != eCounting){ if(taskID > 0 && self->instStatus != eCounting){
self->instStatus = eDriving; self->instStatus = eDriving;
SetStatus(eDriving);
} }
if(taskID > 0 && self->drivePrint == 1){ if(taskID > 0 && self->drivePrint == 1){
oldVal = pDrivInt->GetValue(pData, pCon); oldVal = pDrivInt->GetValue(pData, pCon);
@ -307,7 +307,6 @@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
taskID = StartCountTask(pData,pCon,name); taskID = StartCountTask(pData,pCon,name);
if(taskID > 0){ if(taskID > 0){
self->instStatus = eCounting; self->instStatus = eCounting;
SetStatus(eCounting);
} }
} else { } else {
SCPrintf(pCon,eLogError, "ERROR: type unkonw, cannot start %s", name); SCPrintf(pCon,eLogError, "ERROR: type unkonw, cannot start %s", name);
@ -530,7 +529,6 @@ int PauseExecution(pExeList self)
if(IsCounting(self)){ if(IsCounting(self)){
TaskSignalGroup(self->pTask, IPAUSE, &interrupt, self->waitID); TaskSignalGroup(self->pTask, IPAUSE, &interrupt, self->waitID);
TaskSignalGroup(self->pTask, IPAUSE, &interrupt, self->runID); TaskSignalGroup(self->pTask, IPAUSE, &interrupt, self->runID);
SetStatus(ePaused);
} }
return 1; return 1;
@ -559,7 +557,6 @@ int ContinueExecution(pExeList self)
if(GetStatus() == ePaused){ if(GetStatus() == ePaused){
TaskSignalGroup(self->pTask, CONTINUE, &interrupt, self->waitID); TaskSignalGroup(self->pTask, CONTINUE, &interrupt, self->waitID);
TaskSignalGroup(self->pTask, CONTINUE, &interrupt, self->runID); TaskSignalGroup(self->pTask, CONTINUE, &interrupt, self->runID);
SetStatus(eCounting);
} }
return 1; return 1;
} }
@ -716,7 +713,6 @@ int Success(SConnection * pCon, SicsInterp * pSics, void *pData,
pExeList self = (pExeList)pData; pExeList self = (pExeList)pData;
eOld = GetStatus(); eOld = GetStatus();
SetStatus(eRunning);
if(argc > 1){ if(argc > 1){
if(strcmp(argv[1],"RUNDRIVE") == 0){ if(strcmp(argv[1],"RUNDRIVE") == 0){
@ -758,7 +754,6 @@ int Success(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, "Level done", eValue); SCWrite(pCon, "Level done", eValue);
iRet = 1; iRet = 1;
} }
SetStatus(eEager);
return iRet; return iRet;
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
@ -894,7 +889,6 @@ int DevExecTask(void *pData)
self->lTask = -1; self->lTask = -1;
self->iRun = 0; self->iRun = 0;
self->instStatus = eEager; self->instStatus = eEager;
SetStatus(eEager);
/* /*
This is sort of unclean. Setting DEVERROR has to be done in the This is sort of unclean. Setting DEVERROR has to be done in the
device task function as it is the only one that knows about this. device task function as it is the only one that knows about this.
@ -965,3 +959,12 @@ void SetDevexecStatus(pExeList pExe, int code)
pExe->iStatus = code; pExe->iStatus = code;
} }
} }
/*------------------------------------------------------------------------*/
int GetDevExecInstStatus(pExeList self)
{
if(self->lTask < 0){
return eEager;
} else {
return self->instStatus;
}
}

View File

@ -1,5 +1,5 @@
#line 202 "devexec.w" #line 204 "devexec.w"
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -57,7 +57,7 @@
int StartCounter(pExeList self, SicsInterp *pSics, SConnection *pCon, int StartCounter(pExeList self, SicsInterp *pSics, SConnection *pCon,
int level, char *name); int level, char *name);
#line 249 "devexec.w" #line 251 "devexec.w"
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
@ -77,8 +77,10 @@
int DevExecTask(void *pEL); int DevExecTask(void *pEL);
void DevExecSignal(void *pEL, int iSignal, void *pSigData); void DevExecSignal(void *pEL, int iSignal, void *pSigData);
int GetDevExecInstStatus(pExeList self);
#line 251 "devexec.w"
#line 253 "devexec.w"
/* /*
@ -98,7 +100,7 @@
*/ */
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#line 142 "devexec.w" #line 144 "devexec.w"
int StopExe(pExeList self, char *name); int StopExe(pExeList self, char *name);
int StopExeWait(pExeList self); int StopExeWait(pExeList self);
@ -122,7 +124,7 @@
int ContinueExecution(pExeList self); int ContinueExecution(pExeList self);
#line 269 "devexec.w" #line 271 "devexec.w"
/*-------------------------- Commands ------------------------------------*/ /*-------------------------- Commands ------------------------------------*/
int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData, int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData,
@ -164,13 +166,13 @@
/*--------------------------- Locking ---------------------------------*/ /*--------------------------- Locking ---------------------------------*/
#line 190 "devexec.w" #line 192 "devexec.w"
void LockDeviceExecutor(pExeList self); void LockDeviceExecutor(pExeList self);
void UnlockDeviceExecutor(pExeList self); void UnlockDeviceExecutor(pExeList self);
#line 309 "devexec.w" #line 311 "devexec.w"
/* -------------------------- Executor management -------------------------*/ /* -------------------------- Executor management -------------------------*/

View File

@ -101,6 +101,8 @@ From within the SICS main loops this special function is called:
int DevExecTask(void *pEL); int DevExecTask(void *pEL);
void DevExecSignal(void *pEL, int iSignal, void *pSigData); void DevExecSignal(void *pEL, int iSignal, void *pSigData);
int GetDevExecInstStatus(pExeList self);
@} @}
CheckExeList then scan through its list of executing objects and request a CheckExeList then scan through its list of executing objects and request a
status from each of them. The next action depend on the status returned from status from each of them. The next action depend on the status returned from

View File

@ -333,7 +333,8 @@ static void DevReset(DevSer * devser)
devser->current->kill(devser->current->data); devser->current->kill(devser->current->data);
} }
devser->killCurrent = 0; devser->killCurrent = 0;
/* free(devser->current); */ free(devser->current);
devser->current = NULL;
} }
} }

13
drive.c
View File

@ -302,19 +302,16 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
} }
/* interprete arguments as pairs name value and try to start */ /* interprete arguments as pairs name value and try to start */
SetStatus(eDriving);
for (i = 1; i < argc; i += 2) { for (i = 1; i < argc; i += 2) {
if (argv[i + 1] == NULL) { if (argv[i + 1] == NULL) {
snprintf(pBueffel, 511, "ERROR: no value found for driving %s", argv[i]); snprintf(pBueffel, 511, "ERROR: no value found for driving %s", argv[i]);
SCWrite(pCon, pBueffel, eError); SCWrite(pCon, pBueffel, eError);
SetStatus(eOld);
return 0; return 0;
} }
iRet = Tcl_GetDouble(tcl_interp, argv[i + 1], &dTarget); iRet = Tcl_GetDouble(tcl_interp, argv[i + 1], &dTarget);
if (iRet == TCL_ERROR) { if (iRet == TCL_ERROR) {
SCWrite(pCon, Tcl_GetStringResult(tcl_interp), eError); SCWrite(pCon, Tcl_GetStringResult(tcl_interp), eError);
StopExe(GetExecutor(), "ALL"); StopExe(GetExecutor(), "ALL");
SetStatus(eOld);
return 0; return 0;
} }
iRet = Start2Run(pCon, pSics, argv[i], RUNDRIVE, dTarget); iRet = Start2Run(pCon, pSics, argv[i], RUNDRIVE, dTarget);
@ -328,7 +325,6 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
} }
SCWrite(pCon, pBueffel, eError); SCWrite(pCon, pBueffel, eError);
StopExe(GetExecutor(), "ALL"); StopExe(GetExecutor(), "ALL");
SetStatus(eOld);
return 0; return 0;
} }
} }
@ -351,17 +347,14 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
sprintf(pBueffel, "Driving finished with problem"); sprintf(pBueffel, "Driving finished with problem");
SCWrite(pCon, pBueffel, eError); SCWrite(pCon, pBueffel, eError);
ClearExecutor(GetExecutor()); ClearExecutor(GetExecutor());
SetStatus(eOld);
return 0; return 0;
} else if (iRet == DEVINT) { } else if (iRet == DEVINT) {
sprintf(pBueffel, "ERROR: Driving Interrupted!"); sprintf(pBueffel, "ERROR: Driving Interrupted!");
SCWrite(pCon, pBueffel, eError); SCWrite(pCon, pBueffel, eError);
ClearExecutor(GetExecutor()); ClearExecutor(GetExecutor());
SetStatus(eOld);
return 0; return 0;
} }
SCWrite(pCon, "Driving finished sucessfully", eValue); SCWrite(pCon, "Driving finished sucessfully", eValue);
SetStatus(eOld);
return 1; return 1;
} }
@ -399,19 +392,16 @@ int RunWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
} }
/* interprete arguments as pairs name value and try to start */ /* interprete arguments as pairs name value and try to start */
SetStatus(eDriving);
for (i = 1; i < argc; i += 2) { for (i = 1; i < argc; i += 2) {
if (argv[i + 1] == NULL) { if (argv[i + 1] == NULL) {
snprintf(pBueffel,511, "ERROR: no value found for driving %s", argv[i]); snprintf(pBueffel,511, "ERROR: no value found for driving %s", argv[i]);
SCWrite(pCon, pBueffel, eError); SCWrite(pCon, pBueffel, eError);
SetStatus(eOld);
return 0; return 0;
} }
iRet = Tcl_GetDouble(tcl_interp, argv[i + 1], &dTarget); iRet = Tcl_GetDouble(tcl_interp, argv[i + 1], &dTarget);
if (iRet == TCL_ERROR) { if (iRet == TCL_ERROR) {
SCWrite(pCon, Tcl_GetStringResult(tcl_interp), eError); SCWrite(pCon, Tcl_GetStringResult(tcl_interp), eError);
StopExe(GetExecutor(), "ALL"); StopExe(GetExecutor(), "ALL");
SetStatus(eOld);
return 0; return 0;
} }
iRet = Start2Run(pCon, pSics, argv[i], RUNRUN, dTarget); iRet = Start2Run(pCon, pSics, argv[i], RUNRUN, dTarget);
@ -420,7 +410,6 @@ int RunWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
argv[i + 1]); argv[i + 1]);
SCWrite(pCon, pBueffel, eError); SCWrite(pCon, pBueffel, eError);
StopExe(GetExecutor(), "ALL"); StopExe(GetExecutor(), "ALL");
SetStatus(eOld);
return 0; return 0;
} }
} }
@ -466,14 +455,12 @@ int MoveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
if (argv[i + 1] == NULL) { if (argv[i + 1] == NULL) {
snprintf(pBueffel,511, "ERROR: no value found for driving %s", argv[i]); snprintf(pBueffel,511, "ERROR: no value found for driving %s", argv[i]);
SCWrite(pCon, pBueffel, eError); SCWrite(pCon, pBueffel, eError);
SetStatus(eOld);
return 0; return 0;
} }
iRet = Tcl_GetDouble(tcl_interp, argv[i + 1], &dTarget); iRet = Tcl_GetDouble(tcl_interp, argv[i + 1], &dTarget);
if (iRet == TCL_ERROR) { if (iRet == TCL_ERROR) {
SCWrite(pCon, Tcl_GetStringResult(tcl_interp), eError); SCWrite(pCon, Tcl_GetStringResult(tcl_interp), eError);
StopExe(GetExecutor(), "ALL"); StopExe(GetExecutor(), "ALL");
SetStatus(eOld);
return 0; return 0;
} }
obj = FindCommandData(pSics,argv[i],NULL); obj = FindCommandData(pSics,argv[i],NULL);

View File

@ -80,12 +80,9 @@ static long EVIDrive(void *pData, SConnection * pCon, float fVal)
assert(pCon); assert(pCon);
if (self->runScript != NULL) { if (self->runScript != NULL) {
savedStatus = GetStatus();
SetStatus(eBatch);
pTcl = InterpGetTcl(pServ->pSics); pTcl = InterpGetTcl(pServ->pSics);
snprintf(pBueffel, sizeof(pBueffel), "%s %f", self->runScript, fVal); snprintf(pBueffel, sizeof(pBueffel), "%s %f", self->runScript, fVal);
iRet = Tcl_Eval(pTcl, pBueffel); iRet = Tcl_Eval(pTcl, pBueffel);
SetStatus(savedStatus);
if (iRet != TCL_OK) { if (iRet != TCL_OK) {
SCPrintf(pCon, eError, SCPrintf(pCon, eError,
"ERROR: %s while processing runscript for %s", "ERROR: %s while processing runscript for %s",
@ -423,7 +420,6 @@ static int ErrPause(void *pData)
} }
/* OK now, continue */ /* OK now, continue */
SetStatus(eEager);
self->iWarned = 0; self->iWarned = 0;
ContinueExecution(pExe); ContinueExecution(pExe);
return 1; return 1;

View File

@ -323,7 +323,6 @@ int exeBufProcess(pExeBuf self, SicsInterp * pSics,
DeleteDynString(command); DeleteDynString(command);
if (SCGetInterrupt(pCon) >= eAbortBatch) { if (SCGetInterrupt(pCon) >= eAbortBatch) {
SCWrite(pCon, "ERROR: batch processing interrupted", eError); SCWrite(pCon, "ERROR: batch processing interrupted", eError);
SetStatus(eEager);
if (pCall != NULL) { if (pCall != NULL) {
InvokeCallBack(pCall, BATCHEND, self->name); InvokeCallBack(pCall, BATCHEND, self->name);
} }
@ -375,7 +374,6 @@ int exeBufProcessErrList(pExeBuf self, SicsInterp * pSics,
DeleteDynString(command); DeleteDynString(command);
if (SCGetInterrupt(pCon) >= eAbortBatch) { if (SCGetInterrupt(pCon) >= eAbortBatch) {
SCWrite(pCon, "ERROR: batch processing interrupted", eError); SCWrite(pCon, "ERROR: batch processing interrupted", eError);
SetStatus(eEager);
return 0; return 0;
} else { } else {
SCSetInterrupt(pCon, eContinue); SCSetInterrupt(pCon, eContinue);

View File

@ -224,7 +224,16 @@ pDynString findBatchFile(SicsInterp * pSics, char *name)
} }
return locateBatchBuffer(self, name); return locateBatchBuffer(self, name);
} }
/*--------------------------------------------------------------------*/
int isBatchRunning()
{
pExeMan self = (pExeMan) FindCommandData(pServ->pSics, "exe", "ExeManager");
if(self != NULL && self->exeStackPtr > 0){
return 1;
} else {
return 0;
}
}
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
static int runBatchBuffer(pExeMan self, SConnection * pCon, static int runBatchBuffer(pExeMan self, SConnection * pCon,
SicsInterp * pSics, char *name) SicsInterp * pSics, char *name)

View File

@ -19,4 +19,6 @@ pDynString findBatchFile(SicsInterp * pSics, char *name);
int exeHdbBuffer(SConnection * pCon, SicsInterp * pSics, char *name); int exeHdbBuffer(SConnection * pCon, SicsInterp * pSics, char *name);
int exeHdbNode(pHdb exeNode, SConnection * pCon); int exeHdbNode(pHdb exeNode, SConnection * pCon);
int isBatchRunning();
#endif #endif

View File

@ -753,11 +753,11 @@ static int GenInconsumerate(pSICSOBJ self, SConnection * pCon,
{ {
double hkl[3], qvec[3]; double hkl[3], qvec[3];
pFourMess priv = self->pPrivate; pFourMess priv = self->pPrivate;
int i, j; int i, j, iGen = 0, startCount;
if (nPar < 3) { if (nPar < 3) {
SCWrite(pCon, SCWrite(pCon,
"ERROR: need q displacement vector with three compononts", "ERROR: need q displacement vector with three components",
eError); eError);
return 0; return 0;
} }
@ -765,31 +765,32 @@ static int GenInconsumerate(pSICSOBJ self, SConnection * pCon,
qvec[1] = par[1]->value.v.doubleValue; qvec[1] = par[1]->value.v.doubleValue;
qvec[2] = par[2]->value.v.doubleValue; qvec[2] = par[2]->value.v.doubleValue;
for (i = 0; i < priv->masterCount; i++) { startCount = priv->masterCount;
for (i = 0; i < startCount; i++) {
GetRefIndex(priv->messList, i, hkl); GetRefIndex(priv->messList, i, hkl);
if(ABS(hkl[0])+ABS(hkl[1])+ABS(hkl[2]) < .3){
/*
* Stop generation for 0,0,0,
*/
continue;
}
for (j = 0; j < 3; j++) { for (j = 0; j < 3; j++) {
hkl[j] += qvec[j]; hkl[j] += qvec[j];
} }
AddRefIdx(priv->messList, hkl); AddRefIdx(priv->messList, hkl);
iGen++;
GetRefIndex(priv->messList, i, hkl); GetRefIndex(priv->messList, i, hkl);
for (j = 0; j < 3; j++) { for (j = 0; j < 3; j++) {
hkl[j] -= qvec[j]; hkl[j] -= qvec[j];
} }
if(FindHKL(priv->messList, hkl[0], hkl[1], hkl[2]) == NULL){
AddRefIdx(priv->messList, hkl); AddRefIdx(priv->messList, hkl);
iGen++;
}
if(SCGetInterrupt(pCon) != eContinue){ if(SCGetInterrupt(pCon) != eContinue){
SCWrite(pCon,"ERROR: generating incommensurate reflections aborted", eError); SCWrite(pCon,"ERROR: generating incommensurate reflections aborted", eError);
return 0; return 0;
} }
if( (i % 50) == 0 ){
SCPrintf(pCon,eLog, "%d of %d input reflections processed", i, startCount);
}
} }
SCPrintf(pCon, eValue, SCPrintf(pCon, eValue,
"%d additional inconsumerate reflections generated", "%d additional inconsumerate reflections generated", iGen);
priv->masterCount*2);
return 1; return 1;
} }

View File

@ -22,6 +22,7 @@ static char update[] = { "update" };
static char treeChange[] = { "treeChange" }; static char treeChange[] = { "treeChange" };
static char dataSearch[] = { "dataSearch" }; static char dataSearch[] = { "dataSearch" };
static char killNode[] = { "killNode" }; static char killNode[] = { "killNode" };
static char propertyChange[] = { "propertyChange" };
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
pHdbDataMessage GetHdbSetMessage(pHdbMessage toTest) pHdbDataMessage GetHdbSetMessage(pHdbMessage toTest)
@ -77,6 +78,15 @@ pHdbMessage GetHdbKillNodeMessage(pHdbMessage toTest)
return NULL; return NULL;
} }
/*-------------------------------------------------------------------------*/
pHdbPropertyChange GetPropertyChangeMessage(pHdbMessage toTest)
{
if (toTest->type == propertyChange) {
return (pHdbPropertyChange)toTest;
}
return NULL;
}
/*================== internal functions ===================================*/ /*================== internal functions ===================================*/
void DeleteCallbackChain(pHdb node) void DeleteCallbackChain(pHdb node)
{ {
@ -1140,6 +1150,8 @@ static int calcDataLength(pHdb node, int testLength)
/*============================= Property Functions ==========================*/ /*============================= Property Functions ==========================*/
void SetHdbProperty(pHdb node, char *key, char *value) void SetHdbProperty(pHdb node, char *key, char *value)
{ {
hdbPropertyChange propMes;
if (node != NULL && key != NULL && node->properties != NULL) { if (node != NULL && key != NULL && node->properties != NULL) {
if (value == NULL) { if (value == NULL) {
StringDictDelete(node->properties, key); StringDictDelete(node->properties, key);
@ -1148,6 +1160,10 @@ void SetHdbProperty(pHdb node, char *key, char *value)
} else { } else {
StringDictAddPair(node->properties, key, value); StringDictAddPair(node->properties, key, value);
} }
propMes.type = propertyChange;
propMes.key = key;
propMes.value = value;
InvokeCallbackChain(node,(pHdbMessage)&propMes);
} }
} }

View File

@ -26,6 +26,8 @@
* Added support for properties, Mark Koennecke, January 2007 * Added support for properties, Mark Koennecke, January 2007
* *
* Refactored callback handling, Markus Zolliker, Mark Koennecke, March 2008 * Refactored callback handling, Markus Zolliker, Mark Koennecke, March 2008
*
* Added property chnage events. Mark Koennecke, February 2015
*/ */
#ifndef HIPADABA #ifndef HIPADABA
#define HIPADABA #define HIPADABA
@ -71,11 +73,12 @@ typedef struct __hipadaba {
struct __hdbcallback *callBackChain; struct __hdbcallback *callBackChain;
char *name; char *name;
hdbValue value; hdbValue value;
int protected; int iprotected;
pStringDict properties; pStringDict properties;
} Hdb, *pHdb; } Hdb, *pHdb;
/*-------------- return values for callback functions -------------------------*/ /*-------------- return values for callback functions -------------------------*/
typedef enum { hdbContinue, typedef enum {
hdbContinue,
hdbAbort, hdbAbort,
hdbKill hdbKill
} hdbCallbackReturn; } hdbCallbackReturn;
@ -101,6 +104,12 @@ typedef struct {
void *result; void *result;
} hdbDataSearch, *pHdbDataSearch; } hdbDataSearch, *pHdbDataSearch;
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
typedef struct {
char *type;
char *key;
char *value;
} hdbPropertyChange, *pHdbPropertyChange;
/*-------------------------------------------------------------------------------*/
typedef hdbCallbackReturn(*hdbCallbackFunction) (pHdb currentNode, typedef hdbCallbackReturn(*hdbCallbackFunction) (pHdb currentNode,
void *userData, void *userData,
pHdbMessage message); pHdbMessage message);
@ -156,6 +165,14 @@ pHdbDataSearch GetHdbDataSearchMessage(pHdbMessage toTest);
* pointer if it is. * pointer if it is.
*/ */
pHdbMessage GetHdbKillNodeMessage(pHdbMessage toTest); pHdbMessage GetHdbKillNodeMessage(pHdbMessage toTest);
/**
* Test a message if it is a property change message
* @param toTest The message to test.
* @return NULL if the message is no property chnage message or a message
* pointer if it is.
*/
pHdbPropertyChange GetPropertyChangeMessage(pHdbMessage toTest);
/*======================== Function protoypes: hdbData ========================*/ /*======================== Function protoypes: hdbData ========================*/
/** /**
* make a hdbValue with the given datatype and length * make a hdbValue with the given datatype and length

View File

@ -44,7 +44,7 @@ static int initArray(pCounter self, int value)
assert(datalength != NULL); assert(datalength != NULL);
length = dim->value.v.intArray[0]; length = dim->value.v.intArray[0];
for(i = 1; i < rank->value.v.intValue; i++){ for(i = 1; i < dim->value.arrayLength; i++){
length *= dim->value.v.intArray[i]; length *= dim->value.v.intArray[i];
} }
/* printf("initArray called with length %d\n", length);*/ /* printf("initArray called with length %d\n", length);*/
@ -262,6 +262,22 @@ static int SumCmd(pSICSOBJ ccmd, SConnection * pCon,
} }
return 1; return 1;
} }
/*-------------------------------------------------------------------------*/
static int TotalCmd(pSICSOBJ ccmd, SConnection * pCon,
Hdb * cmdNode, Hdb * par[], int nPar)
{
pHdb dataNode = NULL;
long lSum = 0;
int i;
dataNode = GetHipadabaNode(ccmd->objectNode,"data");
assert(dataNode != NULL);
for(i = 0, lSum = 0; i < dataNode->value.arrayLength; i++){
lSum += dataNode->value.v.intArray[i];
}
SCPrintf(pCon,eValue,"%s.total = %ld", ccmd->objectNode->name, lSum);
return 1;
}
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
static int InitCmd(pSICSOBJ ccmd, SConnection * con, static int InitCmd(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar) Hdb * cmdNode, Hdb * par[], int nPar)
@ -382,6 +398,8 @@ int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
AddSICSHdbPar(child, "ystart", usSpy, MakeHdbInt(0)); AddSICSHdbPar(child, "ystart", usSpy, MakeHdbInt(0));
AddSICSHdbPar(child, "yend", usSpy, MakeHdbInt(0)); AddSICSHdbPar(child, "yend", usSpy, MakeHdbInt(0));
child = AddSICSHdbPar(node,"total", usSpy, MakeSICSFunc(TotalCmd));
/* /*
* test TOF option * test TOF option
*/ */

View File

@ -77,6 +77,7 @@ static int SimConfig(pHistDriver self, SConnection * pCon,
self->pPriv = NewSIMCounter("HistoSim", fFail); self->pPriv = NewSIMCounter("HistoSim", fFail);
} }
/* /*
configured test value configured test value
*/ */

View File

@ -126,6 +126,9 @@ static int HMCStatus(void *pData, SConnection * pCon)
assert(self); assert(self);
if(self->checkSlaves == 0) { if(self->checkSlaves == 0) {
/*
check master
*/
status = self->slaves[0]->CheckCountStatus(self->slaveData[0], pCon); status = self->slaves[0]->CheckCountStatus(self->slaveData[0], pCon);
/* /*
Warning: this assumes that slaves 1 - MAXSLAVE are histogram memories. Warning: this assumes that slaves 1 - MAXSLAVE are histogram memories.
@ -194,7 +197,7 @@ static int HMCBoaStatus(void *pData, SConnection * pCon)
HMCHalt(self); HMCHalt(self);
ReleaseCountLock(self->pCount); ReleaseCountLock(self->pCount);
self->checkSlaves = 0; self->checkSlaves = 0;
for(j = 0; j < 100; j++){ for(j = 0; j < 200; j++){
SicsWait(1); SicsWait(1);
status = self->slaves[i]->CheckCountStatus(self->slaveData[i], pCon); status = self->slaves[i]->CheckCountStatus(self->slaveData[i], pCon);
if(status == HWIdle || status == HWFault) { if(status == HWIdle || status == HWFault) {

View File

@ -176,6 +176,7 @@ int GetDrivablePosition(void *pObject, SConnection * pCon, float *fPos)
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
typedef struct { typedef struct {
int id;
void *obj; void *obj;
pIDrivable pDriv; pIDrivable pDriv;
SConnection *pCon; SConnection *pCon;
@ -195,6 +196,7 @@ static void KillDriveTaskData(void *data)
if(taskData->pCon != NULL){ if(taskData->pCon != NULL){
SCDeleteConnection(taskData->pCon); SCDeleteConnection(taskData->pCon);
} }
free(taskData);
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static void DriveTaskSignal(void *data, int iSignal, void *pSigData) static void DriveTaskSignal(void *data, int iSignal, void *pSigData)
@ -235,9 +237,11 @@ static int DriveTaskFunc(void *data)
DevexecLog("STOP",taskData->name); DevexecLog("STOP",taskData->name);
if(status == HWIdle || status == OKOK){ if(status == HWIdle || status == OKOK){
ExeInterest(pServ->pExecutor,taskData->name, "finished"); ExeInterest(pServ->pExecutor,taskData->name, "finished");
} else { } else {
ExeInterest(pServ->pExecutor,taskData->name, "finished with problem"); ExeInterest(pServ->pExecutor,taskData->name, "finished with problem");
} }
traceSys("drive","DriveTask %s finished with state %d", taskData->name,status);
return 0; return 0;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
@ -250,7 +254,7 @@ long StartDriveTask(void *obj, SConnection *pCon, char *name, float fTarget)
pDriv = GetDrivableInterface(obj); pDriv = GetDrivableInterface(obj);
if(pDriv == NULL){ if(pDriv == NULL){
SCPrintf(pCon,eError,"ERROR: %s is not drivable", name); SCPrintf(pCon,eError,"ERROR: %s is not drivable", name);
return 1; return -1;
} }
if(pDriv->CheckLimits(obj,fTarget,error,sizeof(error)) != OKOK){ if(pDriv->CheckLimits(obj,fTarget,error,sizeof(error)) != OKOK){
SCPrintf(pCon,eError,"ERROR: %s cannot reach %f, reason %s", name, SCPrintf(pCon,eError,"ERROR: %s cannot reach %f, reason %s", name,
@ -269,6 +273,7 @@ long StartDriveTask(void *obj, SConnection *pCon, char *name, float fTarget)
DevexecLog("START",name); DevexecLog("START",name);
InvokeNewTarget(pServ->pExecutor,name,fTarget); InvokeNewTarget(pServ->pExecutor,name,fTarget);
taskData->id = DRIVEID;
taskData->obj = obj; taskData->obj = obj;
taskData->pDriv = pDriv; taskData->pDriv = pDriv;
taskData->pCon = SCCopyConnection(pCon); taskData->pCon = SCCopyConnection(pCon);
@ -315,6 +320,7 @@ int isRunning(pICountable self)
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
typedef struct { typedef struct {
int id;
void *obj; void *obj;
pICountable pCount; pICountable pCount;
SConnection *pCon; SConnection *pCon;
@ -334,6 +340,7 @@ static void KillCountTaskData(void *data)
if(taskData->pCon != NULL){ if(taskData->pCon != NULL){
SCDeleteConnection(taskData->pCon); SCDeleteConnection(taskData->pCon);
} }
free(taskData);
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static void CountTaskSignal(void *data, int iSignal, void *pSigData) static void CountTaskSignal(void *data, int iSignal, void *pSigData)
@ -366,13 +373,10 @@ static int CountTaskFunc(void *data)
status = taskData->pCount->CheckCountStatus(taskData->obj,taskData->pCon); status = taskData->pCount->CheckCountStatus(taskData->obj,taskData->pCon);
if(status == HWBusy) { if(status == HWBusy) {
SetStatus(eCounting);
return 1; return 1;
} else if(status == HWNoBeam){ } else if(status == HWNoBeam){
SetStatus(eOutOfBeam);
return 1; return 1;
} else if(status == HWPause){ } else if(status == HWPause){
SetStatus(ePaused);
return 1; return 1;
} }
@ -388,6 +392,7 @@ static int CountTaskFunc(void *data)
} else { } else {
ExeInterest(pServ->pExecutor,taskData->name, "finished with problem"); ExeInterest(pServ->pExecutor,taskData->name, "finished with problem");
} }
traceSys("count","CountTask %s finished with state %d", taskData->name,status);
return 0; return 0;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
@ -414,6 +419,7 @@ long StartCountTask(void *obj, SConnection *pCon, char *name)
ExeInterest(pServ->pExecutor,name,"started"); ExeInterest(pServ->pExecutor,name,"started");
DevexecLog("START",name); DevexecLog("START",name);
taskData->id = COUNTID;
taskData->obj = obj; taskData->obj = obj;
taskData->pCount = pCount; taskData->pCount = pCount;
taskData->pCon = SCCopyConnection(pCon); taskData->pCon = SCCopyConnection(pCon);

View File

@ -11,3 +11,4 @@ MFLAGS=-f makefile_linux$(DUMMY)
HDFROOT=/usr/local HDFROOT=/usr/local
TCLINC=/usr/include/tcl TCLINC=/usr/include/tcl
EPICS=/usr/local/epics

View File

@ -11,5 +11,6 @@
MFLAGS=-f makefile_macosx MFLAGS=-f makefile_macosx
HDFROOT=/usr/pkg HDFROOT=/usr/pkg
EPICS=/usr/local/epics
EPICSLIBS=-L$(EPICS)/lib/darwin-x86 -lca -lCom

View File

@ -474,8 +474,6 @@ int MacroFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
} }
/* handle status first */ /* handle status first */
eOld = GetStatus();
SetStatus(eBatch);
SICSLogWrite("Evaluating in MacroFileEval", eValue); SICSLogWrite("Evaluating in MacroFileEval", eValue);
SICSLogWrite(argv[1], eValue); SICSLogWrite(argv[1], eValue);
@ -500,7 +498,6 @@ int MacroFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
Tcl_DStringAppend(&command, pBueffel, -1); Tcl_DStringAppend(&command, pBueffel, -1);
pCom = Tcl_DStringValue(&command); pCom = Tcl_DStringValue(&command);
if (Tcl_CommandComplete(pCom)) { if (Tcl_CommandComplete(pCom)) {
SetStatus(eEager);
FirstWord(pCom, pBueffel); FirstWord(pCom, pBueffel);
if (FindCommand(pInter, pBueffel) != NULL) { if (FindCommand(pInter, pBueffel) != NULL) {
snprintf(pBueffel,sizeof(pBueffel)-1, "%s:%d>> %s", pFile, iLine, pCom); snprintf(pBueffel,sizeof(pBueffel)-1, "%s:%d>> %s", pFile, iLine, pCom);
@ -512,7 +509,6 @@ int MacroFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
iLine++; iLine++;
} }
iRet = Tcl_Eval(pTcl, pCom); iRet = Tcl_Eval(pTcl, pCom);
SetStatus(eBatch);
if (iRet != TCL_OK) { if (iRet != TCL_OK) {
/* write TCL error and check for total interrupt */ /* write TCL error and check for total interrupt */
if (Tcl_GetVar(pTcl, SICSERROR, TCL_GLOBAL_ONLY) == NULL) { /* Tcl error */ if (Tcl_GetVar(pTcl, SICSERROR, TCL_GLOBAL_ONLY) == NULL) { /* Tcl error */
@ -537,7 +533,6 @@ int MacroFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
fclose(fp); fclose(fp);
Tcl_DStringFree(&command); Tcl_DStringFree(&command);
SCWrite(pCon, "ERROR: batch processing interrupted", eError); SCWrite(pCon, "ERROR: batch processing interrupted", eError);
SetStatus(eEager);
return 0; return 0;
} else { } else {
SCSetInterrupt(pCon, eContinue); SCSetInterrupt(pCon, eContinue);
@ -555,7 +550,6 @@ int MacroFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
/* clean up */ /* clean up */
fclose(fp); fclose(fp);
Tcl_DStringFree(&command); Tcl_DStringFree(&command);
SetStatus(eOld);
SCSendOK(pCon); SCSendOK(pCon);
return 1; return 1;
} }

View File

@ -46,7 +46,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.o \ rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.o \
histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.o\ histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.o\
singlebinb.o taskobj.o sctcomtask.o tasmono.o multicountersec.o \ singlebinb.o taskobj.o sctcomtask.o tasmono.o multicountersec.o \
messagepipe.o sicsget.o messagepipe.o sicsget.o remoteobject.o
MOTOROBJ = motor.o simdriv.o MOTOROBJ = motor.o simdriv.o
COUNTEROBJ = countdriv.o simcter.o counter.o COUNTEROBJ = countdriv.o simcter.o counter.o
@ -63,7 +63,7 @@ OBJ = $(SOBJ) $(MOTOROBJ) $(COUNTEROBJ) $(VELOOBJ) $(DIFIL) $(EXTRA) $(EPICSOBJ)
#--- This .SECONDARY. target is necessary to preserve generated .c files for debugging #--- This .SECONDARY. target is necessary to preserve generated .c files for debugging
.SECONDARY.: sicspoll.c polldriv.c .SECONDARY.: sicspoll.c polldriv.c
all: libmat libhlib libtecsl libpsi SICServer all: libmat libhlib libpsi SICServer
# use this target when some of the libraries SUBLIBS might be incomplete # use this target when some of the libraries SUBLIBS might be incomplete
full: purge all full: purge all
@ -81,12 +81,7 @@ $(SICSROOT)/sicspsi/hardsup/libhlib.a: libhlib
libhlib: libhlib:
cd $(SICSROOT)/sicspsi/hardsup; make $(MFLAGS) libhlib.a cd $(SICSROOT)/sicspsi/hardsup; make $(MFLAGS) libhlib.a
$(SICSROOT)/sicspsi/tecs/libtecsl.a: libtecsl $(SICSROOT)/sicspsi/libpsi.a: libpsi
libtecsl:
cd $(SICSROOT)/sicspsi/tecs; make $(MFLAGS) libtecsl.a
$SICSROOT)/sicspsi/libpsi.a: libpsi
libpsi: libpsi:
cd $(SICSROOT)/sicspsi; make $(MFLAGS) libpsi.a cd $(SICSROOT)/sicspsi; make $(MFLAGS) libpsi.a
@ -98,7 +93,6 @@ clean:
rm -f *.o *.d SICServer rm -f *.o *.d SICServer
cd $(SICSROOT)/sicspsi/hardsup; make $(MFLAGS) clean cd $(SICSROOT)/sicspsi/hardsup; make $(MFLAGS) clean
cd matrix; make $(MFLAGS) clean cd matrix; make $(MFLAGS) clean
cd $(SICSROOT)/sicspsi/tecs; make $(MFLAGS) clean
cd $(SICSROOT)/sicspsi; make $(MFLAGS) clean cd $(SICSROOT)/sicspsi; make $(MFLAGS) clean
Dbg.o: Dbg.c Dbg.o: Dbg.c

View File

@ -1,22 +1,4 @@
# M. Zolliker 03.2005 # when SICS_MAKE_VERSION is defined: use this makefile version
# if not: show usage (see makefile_)
%: usage include makefile_$(SICS_MAKE_VERSION)
@echo
%.o: usage
@echo
default: usage
usage:
@ echo ""
@ echo "Usage:"
@ echo ""
@ echo " make -f makefile_xxx [target]"
@ echo ""
@ echo ' where makefile_xxx is one of'
@ echo ""
@ ls -1 makefile_* | pr -t -o 4
# DO NOT DELETE

25
makefile_ Normal file
View File

@ -0,0 +1,25 @@
# M. Zolliker 03.2005
# this file shows the correct usage of make in the sics source directory
%: usage
@echo
%.o: usage
@echo
default: usage
usage:
@ echo ""
@ echo "Usage:"
@ echo ""
@ echo " make -f makefile_xxx [target]"
@ echo ""
@ echo ' where makefile_xxx is one of'
@ echo ""
@ ls -1 makefile_?* | pr -t -o 4
@ echo ""
@ echo " or use make without args:"
@ echo ""
@ echo " setenv SICS_MAKE_VERSION slinux"
@ echo " make [target]"

View File

@ -19,8 +19,7 @@ CFLAGS = -I$(HDFROOT)/include $(DFORTIFY) -DHDF4 -DHDF5 \
-g -std1 -warnprotos -g -std1 -warnprotos
BINTARGET = bin BINTARGET = bin
EXTRA= EXTRA=
SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \ SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a
psi/tecs/libtecsl.a
LIBS = -L$(HDFROOT)/lib $(SUBLIBS) \ LIBS = -L$(HDFROOT)/lib $(SUBLIBS) \
-ltcl -lfor $(HDFROOT)/lib/libhdf5.a \ -ltcl -lfor $(HDFROOT)/lib/libhdf5.a \
$(HDFROOT)/lib/libmfhdf.a $(HDFROOT)/lib/libdf.a \ $(HDFROOT)/lib/libmfhdf.a $(HDFROOT)/lib/libdf.a \

View File

@ -22,8 +22,7 @@ CFLAGS = -I$(HDFROOT)/include -I/usr/include/hdf -I$(TCLINC) -DHDF4 -DHDF5 \
BINTARGET = bin BINTARGET = bin
EXTRA=nintf.o EXTRA=nintf.o
SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \ SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a
psi/tecs/libtecsl.a
LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\ LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\
-ltcl -lNeXus -lhdf5 -lmfhdf -ldf \ -ltcl -lNeXus -lhdf5 -lmfhdf -ldf \
-lmxml -lghttp -ljpeg -ljson -ldl -lz -lm -lc -lmxml -lghttp -ljpeg -ljson -ldl -lz -lm -lc

View File

@ -26,8 +26,8 @@ BINTARGET = bin
EXTRA=nintf.o EXTRA=nintf.o
SUBLIBS = $(SICSROOT)/sicspsi/libpsi.a $(SICSROOT)/sicspsi/hardsup/libhlib.a matrix/libmatrix.a \ SUBLIBS = $(SICSROOT)/sicspsi/libpsi.a $(SICSROOT)/sicspsi/hardsup/libhlib.a matrix/libmatrix.a \
$(SICSROOT)/sicspsi/tecs/libtecsl.a $(SICSROOT)/sicspsi/tecs/libtecsl.a
LIBS = -L$(HDFROOT)/lib -L/usr/local/lib $(SUBLIBS) $(NILIB)\ LIBS = -L$(HDFROOT)/lib -L/usr/local/lib $(SUBLIBS) $(NILIB) -L$(EPICS)/lib/darwin-x86 \
-ltcl -lhdf5 -lNeXus -ljson -lghttp -ldl -lz -lmxml -lm -lc -ltcl -lhdf5 -lNeXus -ljson -lghttp $(EPICSLIBS) -ldl -lz -lmxml -lm -lc
include make_gen include make_gen

View File

@ -12,11 +12,14 @@ NI= -DHAVENI
NIOBJ= nigpib.o NIOBJ= nigpib.o
NILIB=$(SINQDIR)/sl6/lib/cib.o NILIB=$(SINQDIR)/sl6/lib/cib.o
EPICSLIBS=-L$(SINQDIR)/sl6/lib/linux-x86 -lezca -lca -lCom EPICSDIR=$(SINQDIR)/sl6/lib/linux-x86
EPICSLIBS=$(EPICSDIR)/libezca.a $(EPICSDIR)/libca.a $(EPICSDIR)/libCom.a -lreadline -lhistory
#EPICSLIBS=-L$(EPICSDIR) -lezca -lca -lCom
include sllinux_def include sllinux_def
CC = gcc CC = gcc
CFLAGS = -I$(HDFROOT)/include -DNXXML -DHDF5 $(NI) \ CFLAGS = -I$(HDFROOT)/include -DNXXML -DHDF5 $(NI) \
-I$(SICSROOT)/sicspsi/hardsup -I$(SICSROOT) -I. -MMD \ -I$(SICSROOT)/sicspsi/hardsup -I$(SICSROOT) -I. -MMD \
-Werror -DCYGNUS -DNONINTF $(DBG) $(DFORTIFY) \ -Werror -DCYGNUS -DNONINTF $(DBG) $(DFORTIFY) \
@ -25,7 +28,7 @@ CFLAGS = -I$(HDFROOT)/include -DNXXML -DHDF5 $(NI) \
BINTARGET = bin BINTARGET = bin
EXTRA=nintf.o EXTRA=nintf.o
SUBLIBS = $(SICSROOT)/sicspsi/libpsi.a $(SICSROOT)/sicspsi/hardsup/libhlib.a \ SUBLIBS = $(SICSROOT)/sicspsi/libpsi.a $(SICSROOT)/sicspsi/hardsup/libhlib.a \
matrix/libmatrix.a $(SICSROOT)/sicspsi/tecs/libtecsl.a matrix/libmatrix.a
LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB) $(EPICSLIBS) \ LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB) $(EPICSLIBS) \
-ltcl -lNeXus $(HDFROOT)/lib/libhdf5.a \ -ltcl -lNeXus $(HDFROOT)/lib/libhdf5.a \
$(HDFROOT)/lib/libsz.a \ $(HDFROOT)/lib/libsz.a \

View File

@ -1,21 +1,34 @@
# M. Zolliker 03.2005 #---------------------------------------------------------------------------
# Makefile for the Matrix library
#
# Mark Koennecke, November 1996
#--------------------------------------------------------------------------
OBJ= matadd.o matcreat.o matdet.o matdump.o matdurbn.o materr.o \
matinv.o matmul.o matsolve.o matsub.o matsubx.o mattoepz.o \
mattran.o
%: usage #---------- for Redhat linux
@echo #CC= gcc
#CFLAGS= -I/usr/local/include -I. -I../ -DLINUX -g -c
%.o: usage #------------ for DigitalUnix
@echo CC=cc
CFLAGS= -I/data/koenneck/include -I. -I../ -std1 -g -c
#------------ for DigitalUnix with Fortify
#CFLAGS= -I/data/koenneck/include -DFORTIFY -I. -I../ -std1 -g -c
default: usage #------------ for CYGNUS toolchain on Win32
#CC=gcc
#CFLAGS= -I. -I../ -DCYGNUS -g -c
usage: .c.o:
@ echo "" $(CC) $(CFLAGS) $*.c
@ echo "Usage:"
@ echo ""
@ echo " make -f makefile_xxx [target]"
@ echo ""
@ echo ' where makefile_xxx is one of'
@ echo ""
@ ls -1 makefile_* | pr -t -o 4
matrix: $(OBJ)
- rm -f libmatrix.a
ar cr libmatrix.a $(OBJ)
ranlib libmatrix.a
clean:
rm -f *.o
rm -f *.a

13
motor.c
View File

@ -1066,19 +1066,6 @@ int MotorCreate(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, pBueffel, eLogError); SCWrite(pCon, pBueffel, eLogError);
return 0; return 0;
} }
/*
} else if (strcmp(argv[2], "epics") == 0) {
if(argc > 3){
pDriver = epicsMakeMotorDriver(argv[3]);
if (!pDriver) {
return 0;
}
} else {
SCWrite(pCon,"ERROR: missing basename argument to create EPICS motor",eError);
return 0;
}
*/
} else { } else {
site = getSite(); site = getSite();
if (site != NULL) { if (site != NULL) {

View File

@ -47,6 +47,7 @@
#define ABS(x) (x < 0 ? -(x) : (x)) #define ABS(x) (x < 0 ? -(x) : (x))
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static void SecMotorSetError(pMotor self, char *text) static void SecMotorSetError(pMotor self, char *text)
{ {
@ -268,9 +269,6 @@ static int checkPosition(pMotor self, SConnection * pCon)
node = GetHipadabaNode(self->pDescriptor->parNode, "hardposition"); node = GetHipadabaNode(self->pDescriptor->parNode, "hardposition");
assert(node != NULL); assert(node != NULL);
SetHipadabaPar(node, MakeHdbFloat(target), pCon); SetHipadabaPar(node, MakeHdbFloat(target), pCon);
node = GetHipadabaNode(self->pDescriptor->parNode, "targetposition");
assert(node != NULL);
SetHipadabaPar(node, MakeHdbFloat(target), pCon);
return HWBusy; return HWBusy;
} }
return HWIdle; return HWIdle;
@ -377,7 +375,7 @@ static float SecMotorGetValue(void *pData, SConnection * pCon)
assert(pData); assert(pData);
status = GetHdbProperty(self->pDescriptor->parNode,"geterror", error,sizeof(error)); status = GetHdbProperty(self->pDescriptor->parNode,"geterror", error,sizeof(error));
if(status == 1 && strcmp(error,"none") != 0) { if(status == 1 && strcmp(error,"none") != 0) {
SCPrintf(pCon,eValue,"ERROR: Failed to read %s with %s", self->name, error); SCPrintf(pCon,eError,"ERROR: Failed to read %s with %s", self->name, error);
return -9999999.99; return -9999999.99;
} }
status = GetHipadabaPar(self->pDescriptor->parNode, &v, pCon); status = GetHipadabaPar(self->pDescriptor->parNode, &v, pCon);
@ -467,7 +465,7 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
pHdb child = NULL; pHdb child = NULL;
pMotor self = NULL; pMotor self = NULL;
float fHard, fVal, sign, zero; float fHard, fVal, sign, zero;
char pBueffel[512], pError[132]; char pBueffel[512], pError[132], *pPtr = NULL;
int status; int status;
self = (pMotor) userData; self = (pMotor) userData;
@ -511,6 +509,7 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
self->name); self->name);
SCWrite(pCon, pBueffel, eWarning); SCWrite(pCon, pBueffel, eWarning);
self->errorCount = 0; self->errorCount = 0;
self->pDrivInt->iErrorCount = 0;
} }
/* /*
@ -527,6 +526,8 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
ServerWriteGlobal(pBueffel, eError); ServerWriteGlobal(pBueffel, eError);
SCSetInterrupt(pCon, eAbortBatch); SCSetInterrupt(pCon, eAbortBatch);
self->pDrivInt->iErrorCount = 0; self->pDrivInt->iErrorCount = 0;
child = GetHipadabaNode(self->pDescriptor->parNode, "status");
UpdateHipadabaPar(child, MakeHdbText("run"), pCon);
return hdbAbort; return hdbAbort;
} }
@ -548,6 +549,12 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
if (mm != NULL) { if (mm != NULL) {
pCon = (SConnection *) mm->callData; pCon = (SConnection *) mm->callData;
SecMotorGetPar(self, "hardposition", &fVal); SecMotorGetPar(self, "hardposition", &fVal);
child = GetHipadabaNode(self->pDescriptor->parNode, "hardposition");
if((pPtr = GetHdbProp(child,"geterror")) != NULL){
SetHdbProperty(node,"geterror",pPtr);
} else {
SetHdbProperty(node,"geterror",NULL);
}
fVal = hardToSoftPosition(self, fVal); fVal = hardToSoftPosition(self, fVal);
node->value.v.doubleValue = fVal; node->value.v.doubleValue = fVal;
mm->v->v.doubleValue = fVal; mm->v->v.doubleValue = fVal;
@ -562,6 +569,7 @@ static hdbCallbackReturn HardUpdateCallback(pHdb node, void *userData,
pHdbMessage message) pHdbMessage message)
{ {
pHdbDataMessage mm = NULL; pHdbDataMessage mm = NULL;
pHdbPropertyChange pm = NULL;
pMotor self = (pMotor) userData; pMotor self = (pMotor) userData;
float fVal; float fVal;
hdbValue v; hdbValue v;
@ -576,6 +584,18 @@ static hdbCallbackReturn HardUpdateCallback(pHdb node, void *userData,
UpdateHipadabaPar(self->pDescriptor->parNode, v, mm->callData); UpdateHipadabaPar(self->pDescriptor->parNode, v, mm->callData);
return hdbContinue; return hdbContinue;
} }
/*
forward geterror
*/
pm = GetPropertyChangeMessage(message);
if(pm != NULL){
if(strstr(pm->key,"geterror") != NULL){
SetHdbProperty(self->pDescriptor->parNode,pm->key, pm->value);
}
}
return hdbContinue; return hdbContinue;
} }
@ -655,6 +675,80 @@ static hdbCallbackReturn SecMotorZeroCallback(pHdb node, void *userData,
return hdbContinue; return hdbContinue;
} }
/*--------------------------------------------------------------------------*/
typedef struct {
char *pName;
SConnection *pCon;
float lastValue;
} MotInfo, *pMotInfo;
/*--------------------------------------------------------------------------*/
static void KillInfo(void *pData)
{
pMotInfo self = NULL;
assert(pData);
self = (pMotInfo) pData;
if (self->pName) {
free(self->pName);
}
if (self->pCon != NULL) {
SCDeleteConnection(self->pCon);
}
free(self);
}
/*-------------------------------------------------------------------------*/
static hdbCallbackReturn InterestCallback(pHdb node, void *userData,
pHdbMessage message)
{
pHdbDataMessage mm = NULL;
pMotor self = (pMotor) userData;
float fVal;
hdbValue v;
pMotInfo priv = (pMotInfo)userData;
assert(self != NULL);
mm = GetHdbUpdateMessage(message);
if (mm != NULL) {
v = *mm->v;
if(!SCisConnected(priv->pCon)){
return hdbKill;
}
if(ABS(v.v.doubleValue - priv->lastValue) > .1) {
SCPrintf(priv->pCon,eValue,"%s.position = %f",
priv->pName, v.v.doubleValue);
priv->lastValue = v.v.doubleValue;
}
return hdbContinue;
}
return hdbContinue;
}
/*---------------------------------------------------------------------------*/
static int InterestCmd(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
pMotInfo priv = NULL;
priv = malloc(sizeof(MotInfo));
if(priv == NULL){
SCWrite(con,"ERROR: out of memory registering interest",eError);
return 0;
}
if(nPar >= 1 && (strcmp(par[0]->value.v.text,"UNKNOWN") != 0)) {
priv->pName = strdup(par[0]->value.v.text);
} else {
priv->pName = strdup(ccmd->objectNode->name);
}
priv->lastValue = .0;
priv->pCon = SCCopyConnection(con);
AppendHipadabaCallback(ccmd->objectNode,
MakeHipadabaCallback(InterestCallback,priv,KillInfo));
SCSendOK(con);
return 1;
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
pMotor SecMotorInit(char *name) pMotor SecMotorInit(char *name)
{ {
@ -793,6 +887,10 @@ pMotor SecMotorInit(char *name)
child = MakeHipadabaNode("error", HIPTEXT, 1); child = MakeHipadabaNode("error", HIPTEXT, 1);
AddHipadabaChild(node, child, NULL); AddHipadabaChild(node, child, NULL);
child = AddSICSHdbPar(node,"interest", usUser, MakeSICSFunc(InterestCmd));
AddSICSHdbPar(child, "name", usUser, MakeHdbText("UNKNOWN"));
pM->endScriptID = 0; pM->endScriptID = 0;
/* initialise Drivable interface */ /* initialise Drivable interface */

View File

@ -15,7 +15,14 @@
#include <counter.h> #include <counter.h>
#include <stptok.h> #include <stptok.h>
#include <macro.h> #include <macro.h>
#include <status.h>
#include "sicshipadaba.h" #include "sicshipadaba.h"
/*---------------------------------------------------------------------------*/
typedef struct {
float fPreset;
float fCurrent;
char *pName;
} MonEvent, *pMonEvent;
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static void SecCounterSetError(pCounter self, char *text) static void SecCounterSetError(pCounter self, char *text)
{ {
@ -134,6 +141,7 @@ static void startMultiCounting(pHdb self, SConnection *pCon)
assert(sID != NULL); assert(sID != NULL);
assert(mID != NULL); assert(mID != NULL);
strtolower(mode->value.v.text);
if(strcmp(mode->value.v.text,"timer") == 0) { if(strcmp(mode->value.v.text,"timer") == 0) {
eMode = eTimer; eMode = eTimer;
} else { } else {
@ -231,15 +239,46 @@ static hdbCallbackReturn MultiSecControllCallback(pHdb node,
return hdbContinue; return hdbContinue;
} }
/*-------------------------------------------------------------------------2-*/
static int MultiSecTransfer(void *pData, SConnection * pCon)
{
int i, retVal = OKOK, tclStatus;
char pBueffel[132];
pCounter pCount = NULL;
pHdb transfer;
SConnection *myCon;
pCount = (pCounter) pData;
transfer = GetHipadabaNode(pCount->objectNode,"transfer");
if(transfer != NULL){
myCon = SCCopyConnection(pCon);
SCsetMacro(myCon,1);
MacroPush(myCon);
tclStatus = Tcl_Eval(InterpGetTcl(pServ->pSics), transfer->value.v.text);
if (tclStatus != TCL_OK) {
snprintf(pBueffel, 131, "ERROR: TransferScript returned: %s",
Tcl_GetStringResult(InterpGetTcl(pServ->pSics)));
SCWrite(pCon, pBueffel, eError);
MacroPop();
SCDeleteConnection(myCon);
return HWFault;
}
MacroPop();
SCDeleteConnection(myCon);
}
return retVal;
}
/*-------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------*/
static int isMultiMasterRunning(pCounter self, SConnection *pCon, int *status) static int isMultiMasterRunning(pCounter self, SConnection *pCon, int *status)
{ {
pHdb mID, master, myStatus, control, ccd, stopTime; pHdb mID, master, myStatus, control, ccd, stopTime, timeNode;
hdbValue v; hdbValue v;
long mlID; long mlID;
void *data; void *data;
pICountable pCount; pICountable pCount;
float controlVal; float controlVal, tVal;
MonEvent sMon;
mID = GetHipadabaNode(self->objectNode,"masterID"); mID = GetHipadabaNode(self->objectNode,"masterID");
master = GetHipadabaNode(self->objectNode,"master"); master = GetHipadabaNode(self->objectNode,"master");
@ -247,12 +286,14 @@ static int isMultiMasterRunning(pCounter self, SConnection *pCon, int *status)
control = GetHipadabaNode(self->objectNode,"control"); control = GetHipadabaNode(self->objectNode,"control");
ccd = GetHipadabaNode(self->objectNode,"ccd"); ccd = GetHipadabaNode(self->objectNode,"ccd");
stopTime = GetHipadabaNode(self->objectNode,"stopTime"); stopTime = GetHipadabaNode(self->objectNode,"stopTime");
timeNode = GetHipadabaNode(self->objectNode,"time");
assert(mID != NULL); assert(mID != NULL);
assert(master != NULL); assert(master != NULL);
assert(myStatus != NULL); assert(myStatus != NULL);
assert(control != NULL); assert(control != NULL);
assert(ccd != NULL); assert(ccd != NULL);
assert(stopTime != NULL); assert(stopTime != NULL);
assert(timeNode != NULL);
mlID = mID->value.v.intValue; mlID = mID->value.v.intValue;
@ -269,6 +310,8 @@ static int isMultiMasterRunning(pCounter self, SConnection *pCon, int *status)
*status = pCount->CheckCountStatus(data,pCon); *status = pCount->CheckCountStatus(data,pCon);
controlVal = GetControlValue((pCounter)data); controlVal = GetControlValue((pCounter)data);
UpdateHipadabaPar(control,MakeHdbFloat(controlVal),pCon); UpdateHipadabaPar(control,MakeHdbFloat(controlVal),pCon);
tVal = GetCountTime((pCounter)data,pCon);
UpdateHipadabaPar(timeNode,MakeHdbFloat(tVal),pCon);
SecCounterSetError(self,"None"); SecCounterSetError(self,"None");
switch(*status){ switch(*status){
case HWFault: case HWFault:
@ -279,13 +322,25 @@ static int isMultiMasterRunning(pCounter self, SConnection *pCon, int *status)
break; break;
case HWPause: case HWPause:
UpdateHipadabaPar(myStatus,MakeHdbText("paused"),pCon); UpdateHipadabaPar(myStatus,MakeHdbText("paused"),pCon);
*status = HWPause;
break; break;
case HWNoBeam: case HWNoBeam:
UpdateHipadabaPar(myStatus,MakeHdbText("nobeam"),pCon); UpdateHipadabaPar(myStatus,MakeHdbText("nobeam"),pCon);
*status = HWNoBeam;
break; break;
default: default:
*status = HWBusy; *status = HWBusy;
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon); UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
if (self->iCallbackCounter > 20) {
MultiSecTransfer(self,pCon);
sMon.fCurrent = controlVal;
sMon.fPreset = GetCounterPreset(self);
sMon.pName = self->name;
InvokeCallBack(self->pCall, MONITOR, &sMon);
self->iCallbackCounter = 0;
} else {
self->iCallbackCounter++;
}
break; break;
} }
} else { } else {
@ -296,6 +351,8 @@ static int isMultiMasterRunning(pCounter self, SConnection *pCon, int *status)
*status = HWBusy; *status = HWBusy;
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon); UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon); UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon);
tVal = GetCountTime((pCounter)data,pCon);
UpdateHipadabaPar(timeNode,MakeHdbFloat(tVal),pCon);
if(ccd->value.v.intValue != 1) { if(ccd->value.v.intValue != 1) {
doCountCommand(self->objectNode,pCon,1011); doCountCommand(self->objectNode,pCon,1011);
} }
@ -334,7 +391,6 @@ static int areSlavesRunning(pCounter self, SConnection *pCon, int *status)
} }
SCWrite(pCon,"ERROR: failed to stop overrun CCD",eLogError); SCWrite(pCon,"ERROR: failed to stop overrun CCD",eLogError);
*status = HWFault; *status = HWFault;
return 0;
} else { } else {
*status = HWBusy; *status = HWBusy;
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon); UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
@ -353,7 +409,7 @@ static void multiEndCounting(pCounter self, SConnection *pCon)
InvokeCallBack(self->pCall, COUNTEND, NULL); InvokeCallBack(self->pCall, COUNTEND, NULL);
ReleaseCountLock(self->pCountInt); ReleaseCountLock(self->pCountInt);
MultiSecTransfer(self,pCon);
} }
/*-------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------*/
@ -378,32 +434,6 @@ static int MultiSecStatus(void *pData, SConnection * pCon)
return HWIdle; return HWIdle;
} }
/*--------------------------------------------------------------------------*/
static int MultiSecTransfer(void *pData, SConnection * pCon)
{
int i, retVal = OKOK, tclStatus;
char pBueffel[132];
pCounter pCount = NULL;
pHdb transfer;
pCount = (pCounter) pData;
transfer = GetHipadabaNode(pCount->objectNode,"transfer");
if(transfer != NULL){
MacroPush(pCon);
tclStatus = Tcl_Eval(InterpGetTcl(pServ->pSics), transfer->value.v.text);
if (tclStatus != TCL_OK) {
snprintf(pBueffel, 131, "ERROR: TransferScript returned: %s",
Tcl_GetStringResult(InterpGetTcl(pServ->pSics)));
SCWrite(pCon, pBueffel, eError);
MacroPop();
return HWFault;
}
MacroPop();
}
return retVal;
}
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
Forward unknown commands to the master counter Forward unknown commands to the master counter
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/

View File

@ -67,7 +67,7 @@ struct timeval lastclose = { -1, 0 };
/*----------------------------------------------------------------------- /*-----------------------------------------------------------------------
Redefine this function if another means of error reporting is necessary. Redefine this function if another means of error reporting is necessary.
*/ */
static void NetError(char *pText) static void NetError(const char pText[])
{ {
/* /*
SICSLogWrite(pText,eError); SICSLogWrite(pText,eError);
@ -287,8 +287,9 @@ mkChannel *NETConnectWithFlags(char *name, int port, int flags)
iRet = connect(pRes->sockid, (struct sockaddr *) &(pRes->adresse), iRet = connect(pRes->sockid, (struct sockaddr *) &(pRes->adresse),
sizeof(struct sockaddr_in)); sizeof(struct sockaddr_in));
if (iRet < 0) { if (iRet < 0 && errno ) {
if (errno != EINPROGRESS) { if (errno != EINPROGRESS) {
close(pRes->sockid);
free(pRes); free(pRes);
return NULL; return NULL;
} }
@ -607,7 +608,7 @@ int NETReadTillTerm(mkChannel * self, long timeout,
gettimeofday(&start, NULL); gettimeofday(&start, NULL);
if (pTerm == NULL) if (pTerm == NULL)
pTerm = ""; pTerm = strdup("");
length = strlen(pTerm); length = strlen(pTerm);
memset(pBuffer, 0, iBufLen); memset(pBuffer, 0, iBufLen);
@ -842,8 +843,9 @@ mkChannel *UDPOpen(int iPort)
i = 1; i = 1;
setsockopt(pRes->sockid, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(int)); setsockopt(pRes->sockid, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(int));
/*
assert(pRes->sockid < (sizeof(long) * 8)); assert(pRes->sockid < (sizeof(long) * 8));
/* if this fails the masks for select will be to if this fails the masks for select will be to
short. short.
*/ */

View File

@ -221,7 +221,6 @@ int InitServer(char *file, pServer * pServ)
printf("Cannot find InterruptPort number in options file %s\n", printf("Cannot find InterruptPort number in options file %s\n",
"This value is required!"); "This value is required!");
DeleteInterp(self->pSics); DeleteInterp(self->pSics);
IFDeleteOptions(pSICSOptions);
return 0; return 0;
} }
iRet = sscanf(pText, "%d", &iPort); iRet = sscanf(pText, "%d", &iPort);
@ -234,6 +233,8 @@ int InitServer(char *file, pServer * pServ)
} }
/* install a secret fully priviledged entry point for ME */ /* install a secret fully priviledged entry point for ME */
AddUser("Achterbahn", "Kiel", usInternal); AddUser("Achterbahn", "Kiel", usInternal);
/* install a secret entry point for remote objects */
AddUser("RemoteMaster","3ed4c656a15f0aa45e02fd5ec429225bb93b762e7eb06cc81a0b4f6c35c76184",usInternal);
/* install environment monitor */ /* install environment monitor */
self->pMonitor = GetEnvMon(self->pSics); self->pMonitor = GetEnvMon(self->pSics);
@ -263,6 +264,9 @@ int InitServer(char *file, pServer * pServ)
INIT(StatusFileInit); INIT(StatusFileInit);
/* install status task */
InitStatus();
/* exit handlers need to be installed here */ /* exit handlers need to be installed here */
atexit(StopExit); atexit(StopExit);
(void)Fortify_CheckAllMemory(); (void)Fortify_CheckAllMemory();
@ -455,14 +459,10 @@ int UserWait(SConnection * pCon, SicsInterp * pSics, void *pData,
return 1; return 1;
} }
eOld = GetStatus();
SetStatus(eUserWait);
sWait.dFinish = DoubleTime() + (double)fVal; sWait.dFinish = DoubleTime() + (double)fVal;
sWait.iEnd = 0; sWait.iEnd = 0;
lID = TaskRegisterN(pTask,"wait", WaitTask, WaitSignal, NULL, &sWait, 1); lID = TaskRegisterN(pTask,"wait", WaitTask, WaitSignal, NULL, &sWait, 1);
TaskWait(pTask, lID); TaskWait(pTask, lID); if (SCGetInterrupt(pCon) != eContinue) {
SetStatus(eOld);
if (SCGetInterrupt(pCon) != eContinue) {
return 0; return 0;
} else { } else {
return 1; return 1;

View File

@ -235,6 +235,7 @@ static int handleFileOperations(SConnection * pCon, pNXScript self,
SCWrite(pCon, buffer, eError); SCWrite(pCon, buffer, eError);
return -1; return -1;
} }
traceIO("datafile", "Opening %s", argv[2]);
SCSendOK(pCon); SCSendOK(pCon);
return 1; return 1;
} }
@ -1491,6 +1492,38 @@ static int SPutAddType(void *message, void *userData)
} }
return MPCONTINUE; return MPCONTINUE;
} }
/*-----------------------------------------------------------------------
Writing should not fail due to some error in padding. Thus this routine
protects against errors but does not fail
------------------------------------------------------------------------*/
static int SPutPadding(void *message, void *userData)
{
pPutMessage self = (pPutMessage)message;
char *pPtr = NULL, *pEnd = NULL;
unsigned int len = 0, i;
if(self->v.dataType == HIPTEXT && strstr(self->v.v.text,"@len") != NULL){
pPtr = strchr(self->v.v.text,'=');
pPtr++;
pEnd = strchr(pPtr,'@');
if(pPtr != NULL && pEnd != NULL){
*pEnd = '\0';
len = atoi(pPtr);
}
pPtr = malloc((len+7)*sizeof(char));
if(pPtr != NULL){
memset(pPtr,0,len*sizeof(char));
strncpy(pPtr,pEnd+1,len);
for(i = strlen(pPtr); i < len-2; i++){
pPtr[i] = ' ';
}
pPtr[len-1] = '!';
free(self->v.v.text);
self->v.v.text = pPtr;
}
}
return MPCONTINUE;
}
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
static int SPutDim(void *message, void *userData) static int SPutDim(void *message, void *userData)
{ {
@ -1518,7 +1551,11 @@ static int SPutDim(void *message, void *userData)
self->dim[0] = self->v.arrayLength; self->dim[0] = self->v.arrayLength;
break; break;
case HIPTEXT: case HIPTEXT:
if(self->v.v.text != NULL){
self->dim[0] = strlen(self->v.v.text)+1; self->dim[0] = strlen(self->v.v.text)+1;
} else {
self->dim[0] = 1;
}
break; break;
default: default:
snprintf(self->error, sizeof(self->error),"invalid data type %d", snprintf(self->error, sizeof(self->error),"invalid data type %d",
@ -1604,6 +1641,7 @@ static void configurePutPipe()
AppendMPFilter(putPipe,SGetData, NULL,NULL); AppendMPFilter(putPipe,SGetData, NULL,NULL);
AppendMPFilter(putPipe,GetDefString, NULL,NULL); AppendMPFilter(putPipe,GetDefString, NULL,NULL);
AppendMPFilter(putPipe,SPutAddType, NULL,NULL); AppendMPFilter(putPipe,SPutAddType, NULL,NULL);
AppendMPFilter(putPipe,SPutPadding, NULL,NULL);
AppendMPFilter(putPipe,SPutDim, NULL,NULL); AppendMPFilter(putPipe,SPutDim, NULL,NULL);
AppendMPFilter(putPipe,SPutWrite, NULL,NULL); AppendMPFilter(putPipe,SPutWrite, NULL,NULL);
} }
@ -2123,3 +2161,20 @@ int MakeNXScript(SConnection * pCon, SicsInterp * pSics, void *pData,
} }
return 1; return 1;
} }
static pNXScript sysScript= NULL;
/*-----------------------------------------------------------------------------------*/
int isNXScriptWriting(void)
{
if(sysScript == NULL){
sysScript = FindCommandData(pServ->pSics,"nxscript","NXScript");
}
if(sysScript != NULL && sysScript->fileHandle != NULL){
return 1;
} else {
return 0;
}
}

View File

@ -21,6 +21,7 @@ int NXScriptAction(SConnection * pCon, SicsInterp * pSics, void *pData,
char *makeFilename(SicsInterp * pSics, SConnection * pCon); char *makeFilename(SicsInterp * pSics, SConnection * pCon);
void changeExtension(char *filename, char *newExtension); void changeExtension(char *filename, char *newExtension);
int isNXScriptWriting(void);
/*============== a personal data structure ============================*/ /*============== a personal data structure ============================*/
typedef struct { typedef struct {
pObjectDescriptor pDes; pObjectDescriptor pDes;

1
ofac.c
View File

@ -48,6 +48,7 @@ static void InitGeneral(void)
INIT(AddSyncedProt); INIT(AddSyncedProt);
INIT(MakeTrace); INIT(MakeTrace);
INIT(InitTaskOBJ); INIT(InitTaskOBJ);
INIT(RemoteObjectInit);
INIT(SiteInit); /* site specific initializations */ INIT(SiteInit); /* site specific initializations */
} }

View File

@ -26,5 +26,5 @@ static char *pCode[] = {
"logerror", "logerror",
NULL NULL
}; };
static int iNoCodes = 13; static int iNoCodes = 15;
#endif #endif

View File

@ -290,7 +290,7 @@ static int ProtocolSet(SConnection * pCon, Protocol * pPro, char *pProName)
SCSetWriteFunc(pCon, SCWriteJSON_String); SCSetWriteFunc(pCon, SCWriteJSON_String);
SCSetWriteFunc(pMaster, SCWriteJSON_String); SCSetWriteFunc(pMaster, SCWriteJSON_String);
break; break;
case 5: case 5: /* ACT */
SCSetWriteFunc(pMaster, SCACTWrite); SCSetWriteFunc(pMaster, SCACTWrite);
SCSetWriteFunc(pCon, SCACTWrite); SCSetWriteFunc(pCon, SCACTWrite);
break; break;

View File

@ -25,6 +25,8 @@ static char undef[] = "Undefined";
#define IDXFMT " %8.4f" #define IDXFMT " %8.4f"
#define ANGFMT " %8.2f" #define ANGFMT " %8.2f"
#define ABS(x) (x < 0 ? -(x) : (x))
int CountTblCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, int CountTblCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar); /* from hdbtable.c */ pHdb par[], int nPar); /* from hdbtable.c */
@ -369,6 +371,32 @@ static int ShowCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
return 1; return 1;
} }
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
const char *FindHKL(pSICSOBJ self, double h, double k, double l)
{
pHdb node, idx;
node = GetHipadabaNode(self->objectNode, "data");
node = node->child;
while(node != NULL){
idx = node->child;
if(ABS(idx->value.v.doubleValue-h) > .1){
node = node->next;
continue;
}
idx = idx->next;
if(ABS(idx->value.v.doubleValue-k) > .1){
node = node->next;
continue;
}
idx = idx->next;
if(ABS(idx->value.v.doubleValue-l) < .1){
return node->name;
}
node = node->next;
}
return NULL;
}
/*-----------------------------------------------------------------------*/
static int NamesCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, static int NamesCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
pHdb par[], int nPar) pHdb par[], int nPar)
{ {
@ -394,6 +422,28 @@ static int NamesCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
return 1; return 1;
} }
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
static int RelabelCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
pHdb par[], int nPar)
{
char buffer[10];
pHdb node = NULL;
int count = 0;
node = GetHipadabaNode(self->objectNode, "data");
node = node->child;
while (node != NULL) {
snprintf(buffer,sizeof(buffer),"%4.4d", count);
if(node->name != NULL){
free(node->name);
node->name = strdup(buffer);
}
count++;
node = node->next;
}
return 1;
}
/*----------------------------------------------------------------------*/
static int SetIndexCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, static int SetIndexCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
pHdb par[], int nPar) pHdb par[], int nPar)
{ {
@ -557,6 +607,11 @@ pSICSOBJ CreateReflectionList(SConnection * pCon, SicsInterp * pSics,
cmd = AddSICSHdbPar(pNew->objectNode, "count", usUser, cmd = AddSICSHdbPar(pNew->objectNode, "count", usUser,
MakeSICSFunc(CountTblCmd)); MakeSICSFunc(CountTblCmd));
cmd = AddSICSHdbPar(pNew->objectNode, "relabel", usUser,
MakeSICSFunc(RelabelCmd));
AddCommand(pSics, name, InterInvokeSICSOBJ, KillSICSOBJ, pNew); AddCommand(pSics, name, InterInvokeSICSOBJ, KillSICSOBJ, pNew);
return pNew; return pNew;
} }

View File

@ -57,4 +57,6 @@ int GetRefFlag(pSICSOBJ refl, int idx);
char *GetRefName(pSICSOBJ refl, int idx); char *GetRefName(pSICSOBJ refl, int idx);
const char *FindHKL(pSICSOBJ self, double h, double k, double l);
#endif /*REFLIST_H_ */ #endif /*REFLIST_H_ */

1008
remoteobject.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,11 @@
* copyright: see file COPYRIGHT * copyright: see file COPYRIGHT
* *
* Mark Koennecke, January 2009 * Mark Koennecke, January 2009
*
* added resizing option and MakeBigRWPuffer in order to support transfer
* of large amounts of image data on few connections
*
* Mark Koennecke, August 2014
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -15,6 +20,7 @@ typedef struct __RWBuffer {
int length; int length;
int startPtr; int startPtr;
int endPtr; int endPtr;
int maxSize;
} RWBuffer; } RWBuffer;
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
prwBuffer MakeRWPuffer(int size) prwBuffer MakeRWPuffer(int size)
@ -32,9 +38,18 @@ prwBuffer MakeRWPuffer(int size)
self->length = size; self->length = size;
self->startPtr = 0; self->startPtr = 0;
self->endPtr = 0; self->endPtr = 0;
self->maxSize = size;
return self; return self;
} }
/*------------------------------------------------------------------------*/
prwBuffer MakeBigRWPuffer(int size, int maxSize)
{
prwBuffer result = MakeRWPuffer(size);
if(result != NULL){
result->maxSize = maxSize;
}
return result;
}
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
void KillRWBuffer(prwBuffer self) void KillRWBuffer(prwBuffer self)
{ {
@ -46,17 +61,52 @@ void KillRWBuffer(prwBuffer self)
} }
free(self); free(self);
} }
/*------------------------------------------------------------------------*/
int CanStoreRWBuffer(prwBuffer self, void *data, int count)
{
int length;
char *ptr;
length = self->endPtr - self->startPtr;
if (count + length >= self->length ) {
if(self->length < self->maxSize){
ptr = calloc(self->maxSize,sizeof(char));
if(ptr == NULL) {
return 0;
}
memcpy(ptr,self->data, length*sizeof(char));
free(self->data);
self->data = ptr;
self->length = self->maxSize;
} else {
return 0;
}
}
return 1;
}
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
int StoreRWBuffer(prwBuffer self, void *data, int count) int StoreRWBuffer(prwBuffer self, void *data, int count)
{ {
int length; int length;
char *ptr;
length = self->endPtr - self->startPtr; length = self->endPtr - self->startPtr;
if (count + length >= self->length ) { if (count + length >= self->length ) {
if(self->length < self->maxSize){
ptr = calloc(self->maxSize,sizeof(char));
if(ptr == NULL) {
printf("HELP: RWBuffer overrun!!!!\n"); printf("HELP: RWBuffer overrun!!!!\n");
return 0; return 0;
} }
memcpy(ptr,self->data, length*sizeof(char));
free(self->data);
self->data = ptr;
self->length = self->maxSize;
} else {
printf("HELP: RWBuffer overrun!!!!\n");
return 0;
}
}
if (count + self->endPtr > self->length) { if (count + self->endPtr > self->length) {
memmove(self->data, self->data + self->startPtr, length); memmove(self->data, self->data + self->startPtr, length);
self->startPtr = 0; self->startPtr = 0;
@ -81,5 +131,6 @@ void RemoveRWBufferData(prwBuffer self, int count)
if (self->startPtr >= self->endPtr) { if (self->startPtr >= self->endPtr) {
self->startPtr = 0; self->startPtr = 0;
self->endPtr = 0; self->endPtr = 0;
memset(self->data,0,self->length*sizeof(char));
} }
} }

View File

@ -16,6 +16,13 @@ typedef struct __RWBuffer *prwBuffer;
* \return NULL on success, else a pointer to t a new rwPuffer * \return NULL on success, else a pointer to t a new rwPuffer
*/ */
prwBuffer MakeRWPuffer(int size); prwBuffer MakeRWPuffer(int size);
/**
* \brief create a RW buffer which can grow.
* \param size The size of the buffer.
* \param maxSize The maximum size of the buffer.
* \return NULL on success, else a pointer to t a new rwPuffer
*/
prwBuffer MakeBigRWPuffer(int size, int maxSize);
/** /**
* \brief delete a rw buffer. * \brief delete a rw buffer.
* \param self The rwPuffer to delete. * \param self The rwPuffer to delete.
@ -29,6 +36,14 @@ void KillRWBuffer(prwBuffer self);
* \return 1 on success, 0 on failure * \return 1 on success, 0 on failure
*/ */
int StoreRWBuffer(prwBuffer self, void *data, int count); int StoreRWBuffer(prwBuffer self, void *data, int count);
/**
* \brief Test if the data can be stored in the rwBuffer
* \param self The rw buffer to store the data in
* \param data pointer to the data to store
* \param count The number of bytes to store
* \return 1 when OK, 0 when buffer full
*/
int CanStoreRWBuffer(prwBuffer self, void *data, int count);
/** /**
* \brief Get a pointer to the current buffer data * \brief Get a pointer to the current buffer data
* \param self the buffer to get the data from * \param self the buffer to get the data from

12
scan.c
View File

@ -999,7 +999,11 @@ int GetScanVarName(pScanData self, int iWhich, char *pName, int iLength)
return 0; return 0;
} }
} }
/*---------------------------------------------------------------------*/
int isScanRunning(pScanData self)
{
return self->iActive;
}
/*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/
int GetScanVarStep(pScanData self, int iWhich, float *fStep) int GetScanVarStep(pScanData self, int iWhich, float *fStep)
{ {
@ -1720,6 +1724,12 @@ int ScanWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, pBueffel, eValue); SCWrite(pCon, pBueffel, eValue);
return 1; return 1;
} }
/*-------- isactive */
else if (strcmp(argv[1], "isactive") == 0) {
snprintf(pBueffel,sizeof(pBueffel)-1, "%s.active = %d", argv[0], self->iActive);
SCWrite(pCon, pBueffel, eValue);
return 1;
}
/*--------- getvardata */ /*--------- getvardata */
else if (strcmp(argv[1], "getvardata") == 0) { else if (strcmp(argv[1], "getvardata") == 0) {
/* we need an integer parameter saying which */ /* we need an integer parameter saying which */

1
scan.h
View File

@ -40,6 +40,7 @@ int GetScanVarStep(pScanData self, int iWhich, float *fStep);
int GetScanMonitor(pScanData self, int iWhich, long *lData, int iDataLen); int GetScanMonitor(pScanData self, int iWhich, long *lData, int iDataLen);
int GetScanNP(pScanData self); int GetScanNP(pScanData self);
float GetScanPreset(pScanData self); float GetScanPreset(pScanData self);
int isScanRunning(pScanData self);
int ScanIntegrate(pScanData self, float *fSum, float *fVariance); int ScanIntegrate(pScanData self, float *fSum, float *fVariance);

View File

@ -143,11 +143,17 @@ int SetSICSInterrupt(SConnection * pCon, SicsInterp * pSics, void *pData,
return 1; return 1;
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------
This method does nothing anymore. Status is now calculated from the state
of SICS and no longer explicitly set. I left the code in because I am to
lazy to find all use cases and eliminate them
M.K. 07/2014
--------------------------------------------------------------------------*/
int SetSICSStatus(SConnection * pCon, SicsInterp * pSics, void *pData, int SetSICSStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]) int argc, char *argv[])
{ {
int iInt; int iInt = 0;
char pBueffel[132]; char pBueffel[132];
assert(pCon); assert(pCon);
@ -166,6 +172,13 @@ int SetSICSStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
return 0; return 0;
} }
SCWrite(pCon,"Status is calculated, cannot be set manually any longer", eValue);
return 1;
/*
The code below is defunct and just here for documentary reasons
*/
/* is there a value ? */ /* is there a value ? */
if (argc < 2) { if (argc < 2) {
SCWrite(pCon, "ERROR: missing parameter for SetStatus", eError); SCWrite(pCon, "ERROR: missing parameter for SetStatus", eError);
@ -174,7 +187,7 @@ int SetSICSStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
/* actually do a job */ /* actually do a job */
strtolower(argv[1]); strtolower(argv[1]);
iInt = SetStatusFromText(argv[1]); /* iInt = SetStatusFromText(argv[1]); */
if (iInt) { if (iInt) {
SCSendOK(pCon); SCSendOK(pCon);
return 1; return 1;
@ -193,7 +206,7 @@ static int isNum(char *pText)
for (i = 0; i < strlen(pText); i++) { for (i = 0; i < strlen(pText); i++) {
if (!isdigit(pText[i])) { if (!isdigit(pText[i])) {
if (!((pText[i] == '+') || (pText[i] == '-') || (pText[i] == '.'))) { if (!((pText[i] == '+') || (pText[i] == '-') || (pText[i] == '.') || (tolower(pText[i]) == 'e' ))) {
iRet = 0; iRet = 0;
break; break;
} }

View File

@ -1552,6 +1552,7 @@ static int SctProcessCmd(pSICSOBJ ccmd, SConnection * con,
{ {
SctData *data = NULL; SctData *data = NULL;
SctController *c; SctController *c;
time_t startTime;
c = (SctController *) ccmd->pPrivate; c = (SctController *) ccmd->pPrivate;
@ -1581,9 +1582,10 @@ static int SctProcessCmd(pSICSOBJ ccmd, SConnection * con,
data->busy = 1; data->busy = 1;
data->inMacro = SCinMacro(con); data->inMacro = SCinMacro(con);
startTime = time(NULL);
DevQueue(c->devser, data, WritePRIO, DevQueue(c->devser, data, WritePRIO,
SctWriteHandler, SctMatch, NULL, SctDataInfo); SctWriteHandler, SctTransactMatch, NULL, SctDataInfo);
while (data->busy == 1) { while (data->busy == 1 && time(NULL) < startTime + 20) {
TaskYield(pServ->pTasker); TaskYield(pServ->pTasker);
} }
SctKillData(data); SctKillData(data);

View File

@ -174,11 +174,11 @@ static int SCTDRIVCheckStatus(void *data, SConnection * pCon)
SCPrintf(pCon, eError, " script %s returned %s", script, result); SCPrintf(pCon, eError, " script %s returned %s", script, result);
} }
} }
if (strstr(result, "busy") != NULL) { if (strstr(result, "run") != NULL) {
return HWBusy; return HWBusy;
} else if (strstr(result, "posfault") != NULL) { } else if (strstr(result, "posfault") != NULL) {
return HWPosFault; return HWPosFault;
} else if (strstr(result, "fault") != NULL) { } else if (strstr(result, "error") != NULL) {
return HWFault; return HWFault;
} else if (strstr(result, "idle") != NULL) { } else if (strstr(result, "idle") != NULL) {
return HWIdle; return HWIdle;

View File

@ -212,11 +212,11 @@ static int SCTDRIVCheckStatus(void *data, SConnection * pCon)
SCPrintf(pCon, eError, " script %s returned %s", script, result); SCPrintf(pCon, eError, " script %s returned %s", script, result);
} }
} }
if (strstr(result, "busy") != NULL) { if (strstr(result, "run") != NULL) {
return HWBusy; return HWBusy;
} else if (strstr(result, "posfault") != NULL) { } else if (strstr(result, "posfault") != NULL) {
return HWPosFault; return HWPosFault;
} else if (strstr(result, "fault") != NULL) { } else if (strstr(result, "error") != NULL) {
return HWFault; return HWFault;
} else if (strstr(result, "idle") != NULL) { } else if (strstr(result, "idle") != NULL) {
return HWIdle; return HWIdle;

View File

@ -954,7 +954,7 @@ static int copyToNode(pSICSData self, int argc, char *argv[],
} }
node->value.arrayLength = length; node->value.arrayLength = length;
} }
memcpy(node->value.v.intArray, self->data, length*sizeof(int)); memcpy(node->value.v.intArray, self->data + start, length*sizeof(int));
break; break;
case HIPFLOATAR: case HIPFLOATAR:
case HIPFLOATVARAR: case HIPFLOATVARAR:

View File

@ -81,15 +81,19 @@ static int SICSGetCommand(SConnection * pCon, SicsInterp * pSics, void *pData,
if(status){ if(status){
data = formatValue(v,NULL); data = formatValue(v,NULL);
if(data != NULL){ if(data != NULL){
SCPrintf(pCon,eValue,"%s",trim(GetCharArray(data))); SCWrite(pCon,trim(GetCharArray(data)),eValue);
DeleteDynString(data); DeleteDynString(data);
} else { } else {
SCPrintf(pCon,eError,"ERROR: formatting value for %s failed", argv[1]); SCPrintf(pCon,eError,"ERROR: formatting value for %s failed", argv[1]);
ReleaseHdbValue(&v); ReleaseHdbValue(&v);
return 0; return 0;
} }
} else {
if(v.dataType == HIPTEXT && strstr(v.v.text,"ERROR") != NULL){
SCPrintf(pCon,eError,v.v.text);
} else { } else {
SCPrintf(pCon,eError,"ERROR: value for %s not found", argv[1]); SCPrintf(pCon,eError,"ERROR: value for %s not found", argv[1]);
}
return 0; return 0;
} }
ReleaseHdbValue(&v); ReleaseHdbValue(&v);
@ -137,16 +141,22 @@ static int SICSPutCommand(SConnection * pCon, SicsInterp * pSics, void *pData,
static int InvokeSICSFunc(void *ms, void *userData) static int InvokeSICSFunc(void *ms, void *userData)
{ {
pParseMessage self = (pParseMessage)ms; pParseMessage self = (pParseMessage)ms;
SConnection *pCon = NULL;
int status; int status;
SCsetMacro(pServ->dummyCon,1); pCon = SCCreateDummyConnection(pServ->pSics);
status = InterpExecute(pServ->pSics, pServ->dummyCon, self->command); if(pCon == NULL){
SCsetMacro(pServ->dummyCon,0); return MPSTOP;
}
SCsetMacro(pCon,1);
status = InterpExecute(pServ->pSics, pCon, self->command);
SCsetMacro(pCon,0);
if(!status){ if(!status){
self->success = 0; self->success = 0;
return MPSTOP; return MPSTOP;
} }
self->response = strdup(Tcl_GetStringResult(InterpGetTcl(pServ->pSics))); self->response = strdup(Tcl_GetStringResult(InterpGetTcl(pServ->pSics)));
SCDeleteConnection(pCon);
return MPCONTINUE; return MPCONTINUE;
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
@ -174,12 +184,26 @@ static int SplitOffEqual(void *ms, void *userData)
return MPCONTINUE; return MPCONTINUE;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int isExtra(char c)
{
char extra[] = {"{}"};
int i;
for(i = 0; i < strlen(extra); i++){
if(extra[i] == c ){
return 1;
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
static int isNumber(char *txt) static int isNumber(char *txt)
{ {
if(*txt == '\0' || *txt == ' '){ if(*txt == '\0' || *txt == ' '){
return 1; return 1;
} }
if(isalpha(*txt)){ if(isalpha(*txt) || isExtra(*txt)){
return 0; return 0;
} else { } else {
return isNumber(txt+1); return isNumber(txt+1);
@ -192,7 +216,7 @@ static int countWords(char *txt)
int count = 0; int count = 0;
char *pPtr = txt; char *pPtr = txt;
while(pPtr != NULL){ while(pPtr != NULL && strlen(pPtr) > 0){
count++; count++;
pPtr = stptok(pPtr,number,sizeof(number)," "); pPtr = stptok(pPtr,number,sizeof(number)," ");
} }
@ -280,8 +304,12 @@ static void configureSICSPipe()
static int FindTclVar(void *ms, void *userData) static int FindTclVar(void *ms, void *userData)
{ {
pParseMessage self = (pParseMessage)ms; pParseMessage self = (pParseMessage)ms;
char *pPtr = NULL;
self->response = Tcl_GetVar(InterpGetTcl(pServ->pSics),self->command, TCL_GLOBAL_ONLY); pPtr = Tcl_GetVar(InterpGetTcl(pServ->pSics),self->command, TCL_GLOBAL_ONLY);
if(pPtr != NULL){
self->response = strdup(pPtr);
}
if(self->response == NULL){ if(self->response == NULL){
return MPSTOP; return MPSTOP;
} }
@ -302,10 +330,20 @@ static int GetHdbFunc(void *ms, void *userData)
{ {
pSSGMessage self = (pSSGMessage)ms; pSSGMessage self = (pSSGMessage)ms;
pHdb node = NULL; pHdb node = NULL;
char *geterror = NULL, error[512];
hdbValue ve;
node = FindHdbNode(NULL,self->name,NULL); node = FindHdbNode(NULL,self->name,NULL);
if(node != NULL){ if(node != NULL){
geterror = GetHdbProp(node,"geterror");
if(geterror != NULL){
snprintf(error,sizeof(error),"ERROR: %s",geterror);
ve = MakeHdbText(strdup(error));
cloneHdbValue(&ve, self->v);
ReleaseHdbValue(&ve);
} else {
cloneHdbValue(&node->value, self->v); cloneHdbValue(&node->value, self->v);
}
self->success = 1; self->success = 1;
return MPSTOP; return MPSTOP;
} else { } else {
@ -357,14 +395,28 @@ static int GetDrivableFunc(void *ms, void *userData)
pIDrivable pDriv = NULL; pIDrivable pDriv = NULL;
float fVal; float fVal;
hdbValue v; hdbValue v;
int oldMacro;
data = FindCommandData(pServ->pSics, self->name,NULL); data = FindCommandData(pServ->pSics, self->name,NULL);
if(data != NULL){ if(data != NULL){
pDriv = GetDrivableInterface(data); pDriv = GetDrivableInterface(data);
if(pDriv != NULL){ if(pDriv != NULL){
/*
All this macro flag handling is there to get hold of a
error message stored in the Tcl interpreter if there is
one.
*/
oldMacro = SCinMacro(pServ->dummyCon);
SCsetMacro(pServ->dummyCon,1);
fVal = pDriv->GetValue(data,pServ->dummyCon); fVal = pDriv->GetValue(data,pServ->dummyCon);
SCsetMacro(pServ->dummyCon,oldMacro);
if(fVal < -900000) {
v = MakeHdbText(Tcl_GetStringResult(InterpGetTcl(pServ->pSics)));
self->success = 0;
} else {
v = MakeHdbFloat(fVal); v = MakeHdbFloat(fVal);
self->success = 1; self->success = 1;
}
cloneHdbValue(&v,self->v); cloneHdbValue(&v,self->v);
return MPSTOP; return MPSTOP;
} }
@ -419,7 +471,7 @@ static int PutHdbFunc(void *ms, void *userData)
node = FindHdbNode(NULL,self->name,NULL); node = FindHdbNode(NULL,self->name,NULL);
if(node != NULL){ if(node != NULL){
status = UpdateHipadabaPar(node,*(self->v),NULL); status = SetHipadabaPar(node,*(self->v),NULL);
self->success = status; self->success = status;
if(status == 1){ if(status == 1){
return MPSTOP; return MPSTOP;

View File

@ -315,7 +315,7 @@ static pHdb CreateMotorAdapter(char *name, pMotor pMot)
DeleteHipadabaNode(result, NULL); DeleteHipadabaNode(result, NULL);
return NULL; return NULL;
} }
result->protected = 1; result->iprotected = 1;
return result; return result;
} }
@ -499,7 +499,7 @@ static pHdb MakeSicsVarNode(pSicsVariable pVar, char *name)
snprintf(command, 1023, "%s ", pVar->name); snprintf(command, 1023, "%s ", pVar->name);
SetHdbProperty(node, "sicscommand", command); SetHdbProperty(node, "sicscommand", command);
node->protected = 1; node->iprotected = 1;
return node; return node;
} }

View File

@ -339,6 +339,7 @@ static int MakeCommandNode(pHdb parent, char *name, SConnection * pCon,
node->value.v.text = strdup(argv[3]); node->value.v.text = strdup(argv[3]);
node->value.arrayLength = strlen(argv[3]); node->value.arrayLength = strlen(argv[3]);
SetHdbProperty(node, "sicscommand", argv[3]); SetHdbProperty(node, "sicscommand", argv[3]);
SetHdbProperty(node, "scriptcommand", "yes");
kalle = MakeHipadabaCallback(CommandSetCallback, NULL, NULL); kalle = MakeHipadabaCallback(CommandSetCallback, NULL, NULL);
if (kalle == NULL) { if (kalle == NULL) {

View File

@ -289,9 +289,8 @@ hdbCallbackReturn SICSValueCheckCallback(pHdb node, void *userData,
} }
return hdbAbort; return hdbAbort;
} }
/*-------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------*/
static hdbCallbackReturn SICSDriveCallback(pHdb node, void *userData, static hdbCallbackReturn SICSDriveCallback(pHdb node, void *userData,
pHdbMessage message) pHdbMessage message)
@ -693,7 +692,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
SCPureSockWrite(cbInfo->pCon, GetCharArray(result), outCode); SCPureSockWrite(cbInfo->pCon, GetCharArray(result), outCode);
DeleteDynString(printedData); DeleteDynString(printedData);
} else { } else {
formatNameValue(protocol, pPath, "!!datachange!!", result, HIPTEXT); formatNameValue(protocol, updatePath, "!!datachange!!", result, HIPTEXT);
SCWrite(cbInfo->pCon, GetCharArray(result), outCode); SCWrite(cbInfo->pCon, GetCharArray(result), outCode);
} }
DeleteDynString(result); DeleteDynString(result);
@ -2342,7 +2341,7 @@ static int isNodeProtected(pHdb node)
{ {
pHdb current = NULL; pHdb current = NULL;
if (node->protected == 1) { if (node->iprotected == 1) {
return 1; return 1;
} }
current = node->child; current = node->child;
@ -2524,7 +2523,7 @@ static int UpdateHdbNode(SConnection * pCon, SicsInterp * pSics,
} }
status = UpdateHipadabaPar(targetNode, newValue, pCon); status = UpdateHipadabaPar(targetNode, newValue, pCon);
ReleaseHdbValue(&newValue); ReleaseHdbValue(&newValue);
if (status == 1) { if (status == 1 && SCinMacro(pCon) == 0) {
SCSendOK(pCon); SCSendOK(pCon);
} }
return status; return status;
@ -2708,10 +2707,10 @@ static int GetHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData,
return 0; return 0;
} }
/* /*
* if transfer = zip, redirect to zip * if transfer = zip or bin, redirect to zip
*/ */
if (GetHdbProperty(targetNode, "transfer", value, 80) == 1) { if (GetHdbProperty(targetNode, "transfer", value, 80) == 1) {
if (strstr(value, "zip") != NULL) { if (strstr(value, "zip") != NULL || strstr(value,"bin") != NULL) {
return ZipGetHdbNode(pCon, pSics, pData, argc, argv); return ZipGetHdbNode(pCon, pSics, pData, argc, argv);
} }
} }
@ -3131,6 +3130,7 @@ static int RemoveHdbCallback(SConnection * pCon, SicsInterp * pSics,
{ {
int id; int id;
hdbIDMessage m; hdbIDMessage m;
pObjectDescriptor pObj = NULL;
if (argc < 2) { if (argc < 2) {
SCWrite(pCon, "ERROR: need callback id to remove", eError); SCWrite(pCon, "ERROR: need callback id to remove", eError);
@ -3139,7 +3139,14 @@ static int RemoveHdbCallback(SConnection * pCon, SicsInterp * pSics,
id = atoi(argv[1]); id = atoi(argv[1]);
m.type = killID; m.type = killID;
m.ID = id; m.ID = id;
if(argc < 3){
RecurseCallbackChains(root, (pHdbMessage) & m); RecurseCallbackChains(root, (pHdbMessage) & m);
} else {
pObj = FindCommandDescriptor(pSics,argv[2]);
if(pObj != NULL && pObj->parNode != NULL){
RecurseCallbackChains(pObj->parNode,(pHdbMessage)&m);
}
}
SCSendOK(pCon); SCSendOK(pCon);
return 1; return 1;
} }

View File

@ -12,4 +12,5 @@ MFLAGS=-f makefile_linux$(DUMMY)
HDFROOT=/afs/psi.ch/project/sinq/sl6 HDFROOT=/afs/psi.ch/project/sinq/sl6
TCLINC=. TCLINC=.
#DBG= -g -fstack-protector-all
DBG= -g DBG= -g

View File

@ -124,7 +124,7 @@ static int StateInterest(int iEvent, void *pEvent, void *pUser)
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
static pHdb recurseInterestNode(pHdb current, char *pDevice) static pHdb recurseInterestNode(pHdb current, char *pDevice)
{ {
char pSicsdev[131], pAlias[132]; char pSicsdev[132], pAlias[132];
pHdb result = NULL; pHdb result = NULL;
char *alias = NULL, *pPtr = NULL; char *alias = NULL, *pPtr = NULL;

185
status.c
View File

@ -13,6 +13,10 @@
Reworked restore to keep parameters from uninitialized devices Reworked restore to keep parameters from uninitialized devices
Mark Koennecke, November 2007 Mark Koennecke, November 2007
Reworked to determine the status from the state of the machine rather then
from explicit sets on a global variable. Which caused trouble, trouble and more
trouble. Mark Koennecke, July 2015
Copyright: Copyright:
Labor fuer Neutronenstreuung Labor fuer Neutronenstreuung
@ -52,6 +56,10 @@
#include "status.h" #include "status.h"
#include "interrupt.h" #include "interrupt.h"
#include "sicshipadaba.h" #include "sicshipadaba.h"
#include "messagepipe.h"
#include "scan.h"
#include "exeman.h"
#include "nxscript.h"
#undef VALUECHANGE #undef VALUECHANGE
#define VALUECHANGE 2 #define VALUECHANGE 2
@ -97,6 +105,8 @@ static char *iText[] = {
static pICallBack pCall = NULL; static pICallBack pCall = NULL;
static int fixed = 0; static int fixed = 0;
static Status eCode = eEager; static Status eCode = eEager;
static int userWait = 0;
static double lastStatus = .0;
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
void KillStatus(void *pData) void KillStatus(void *pData)
{ {
@ -108,24 +118,35 @@ void KillStatus(void *pData)
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void SetStatus(Status eNew) void SetStatus(Status eNew)
{ {
if (!fixed) { /* if (!fixed) {
if (eCode == eNew) { if (eCode == eNew) {
return; return;
} }
eCode = eNew; eCode = eNew;
InvokeCallBack(pCall, VALUECHANGE, NULL); InvokeCallBack(pCall, VALUECHANGE, NULL);
} }
*/
/*
This now only manages the userWait status
*/
if(eNew == eUserWait){
userWait = 1;
} else {
if(userWait == 1){
userWait = 0;
}
}
} }
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
void SetStatusFixed(Status eNew) void SetStatusFixed(Status eNew)
{ {
if (eCode == eNew) { // if (eCode == eNew) {
return; // return;
} // }
eCode = eNew; // eCode = eNew;
InvokeCallBack(pCall, VALUECHANGE, NULL); // InvokeCallBack(pCall, VALUECHANGE, NULL);
fixed = 1; // fixed = 1;
} }
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
@ -279,7 +300,9 @@ int ResetStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, "Insufficient authorisation to reset server", eError); SCWrite(pCon, "Insufficient authorisation to reset server", eError);
return 0; return 0;
} }
SetStatus(eEager); // SetStatus(eEager);
eCode = eEager;
InvokeCallBack(pCall, VALUECHANGE, NULL);
SetInterrupt(eContinue); SetInterrupt(eContinue);
ClearExecutor(GetExecutor()); ClearExecutor(GetExecutor());
SCsetMacro(pCon, 0); SCsetMacro(pCon, 0);
@ -337,3 +360,149 @@ int RedirectControl(SConnection * pCon, SicsInterp * pSics, void *pData,
pOwner->sockHandle = pCon->sockHandle; pOwner->sockHandle = pCon->sockHandle;
return 1; return 1;
} }
/*----------------------------------------------------------------------------
Message pipe based new status calculation code
------------------------------------------------------------------------------*/
static int DevexecStatusFunc(void *message, void *userData)
{
int *status = (int *)message;
*status = GetDevExecInstStatus(pServ->pExecutor);
return MPCONTINUE;
}
/*-----------------------------------------------------------------------------
This must be identical to the definition in interface.c As this structure is only
required in interface.c and here, I choose not to put it into an header file.
-------------------------------------------------------------------------------*/
typedef struct {
int id;
void *obj;
pICountable pCount;
SConnection *pCon;
char *name;
}CountTaskData;
/*-----------------------------------------------------------------------------*/
static int CheckCountStatus(void *message, void *userData)
{
int *status = (int *)message;
int testStatus;
pTaskHead it;
CountTaskData *countTask = NULL;
if(*status == eCounting){
for(it = TaskIteratorStart(pServ->pTasker); it != NULL; it = TaskIteratorNext(it)){
countTask = (CountTaskData *)GetTaskData(it);
if(countTask != NULL && countTask->id == COUNTID){
testStatus = countTask->pCount->CheckCountStatus(countTask->obj,pServ->dummyCon);
if(testStatus == HWNoBeam){
*status = eOutOfBeam;
}
if(testStatus == HWPause){
*status = ePaused;
}
}
}
return MPSTOP;
}
return MPCONTINUE;
}
/*---------------------------------------------------------------------------*/
static pScanData scan = NULL;
static int CheckScan(void *message, void *userData)
{
char *scannames[] = {"xxxscan","iscan", NULL};
unsigned int count = 0;
int *status = (int *)message;
if(*status == eEager){
if(scan == NULL){
while(scannames[count] != NULL){
scan = FindCommandData(pServ->pSics, scannames[count],NULL);
if(scan != NULL){
break;
}
count++;
}
}
if(scan != NULL){
if(isScanRunning(scan)){
*status = eScanning;
return MPCONTINUE;
}
}
}
return MPCONTINUE;
}
/*----------------------------------------------------------------------------*/
static int CheckExe(void *message, void *userData)
{
int *status = (int *)message;
if(*status == eEager){
if(isBatchRunning()){
*status = eBatch;
}
}
return MPCONTINUE;
}
/*------------------------------------------------------------------------------*/
static int CheckUserWait(void *message, void *userData)
{
int *status = (int *)message;
if(*status == eEager){
if(isTaskRunning(pServ->pTasker,"wait")){
*status = eUserWait;
}
}
return MPCONTINUE;
}
/*--------------------------------------------------------------------------------*/
static int CheckNXScript(void *message, void *userData)
{
int *status = (int *)message;
if(*status == eEager){
if(isNXScriptWriting()){
*status = eWriting;
}
}
return MPCONTINUE;
}
/*--------------------------------------------------------------------------------*/
static pMP statusPipe = NULL;
static void BuildStatusChain(void)
{
statusPipe = MakeMP();
AppendMPFilter(statusPipe,DevexecStatusFunc,NULL,NULL);
AppendMPFilter(statusPipe,CheckCountStatus,NULL,NULL);
AppendMPFilter(statusPipe,CheckScan,NULL,NULL);
AppendMPFilter(statusPipe,CheckExe,NULL,NULL);
AppendMPFilter(statusPipe,CheckUserWait,NULL,NULL);
AppendMPFilter(statusPipe,CheckNXScript,NULL,NULL);
}
/*-------------------------------------------------------------------------------*/
static int StatusTask(void *data)
{
int status = eEager;
MPprocess(statusPipe,&status);
if(status != eCode && DoubleTime() > lastStatus + .1){
eCode = status;
lastStatus = DoubleTime();
InvokeCallBack(pCall, VALUECHANGE, NULL);
}
return 1;
}
/*---------------------------------------------------------------------------------*/
void InitStatus(void)
{
BuildStatusChain();
TaskRegisterN(pServ->pTasker,"statustask",StatusTask, NULL, NULL, NULL,1);
}

View File

@ -27,19 +27,7 @@ typedef enum {
} Status; } Status;
/* for status display */ /* for status display */
void SetStatus(Status eNew);
int SetStatusFromText(char *text);
void KillStatus(void *pData); void KillStatus(void *pData);
/**
* set a status and disallow any further changes to the status. This serves
* in order to prevent massive message flows to the client from status
* changes while processing synchronisation files
*/
void SetStatusFixed(Status eNew);
/**
* clear a fixed status again, status will be updated again.
*/
void ClearFixedStatus(Status eNew);
Status GetStatus(void); Status GetStatus(void);
void GetStatusText(char *buf, int iBufLen); void GetStatusText(char *buf, int iBufLen);
@ -49,5 +37,6 @@ int UserStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]); int argc, char *argv[]);
int ResetStatus(SConnection * pCon, SicsInterp * pSics, void *pData, int ResetStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]); int argc, char *argv[]);
void InitStatus(void);
#endif #endif

View File

@ -903,7 +903,6 @@ int ScanCount(pScanData self, int iPoint)
SCWrite(self->pCon, "ERROR: Cannot Count, Scan aborted", eLogError); SCWrite(self->pCon, "ERROR: Cannot Count, Scan aborted", eLogError);
return 0; return 0;
} }
SetStatus(eCounting);
/* wait for finish */ /* wait for finish */
while(DevExecLevelRunning(pServ->pExecutor, RUNDRIVE)){ while(DevExecLevelRunning(pServ->pExecutor, RUNDRIVE)){
TaskYield(pServ->pTasker); TaskYield(pServ->pTasker);

View File

@ -163,10 +163,10 @@ long SyncedBegin(long syncid)
return SYNCED_NO_MEMORY; return SYNCED_NO_MEMORY;
} }
} }
sp++;
if (sp >= NSTACK) { if (sp >= NSTACK) {
return SYNCED_STACK_OVERFLOW; return SYNCED_STACK_OVERFLOW;
} }
sp++;
sync->count++; sync->count++;
actualSync = sync; actualSync = sync;
return sync->id; return sync->id;
@ -181,13 +181,13 @@ long SyncedEnd(long syncid)
if (sp <= 0) { if (sp <= 0) {
return SYNCED_STACK_UNDERFLOW; return SYNCED_STACK_UNDERFLOW;
} }
sync = actualSync;
sp--; sp--;
sync = actualSync;
actualSync = stack[sp]; actualSync = stack[sp];
sync->count--; if (sync->count <= 0) {
if (sync->count < 0) {
return SYNCED_COUNT_UNDERFLOW; return SYNCED_COUNT_UNDERFLOW;
} }
sync->count--;
if (syncid != 0 && syncid != sync->id) { if (syncid != 0 && syncid != sync->id) {
return SYNCED_ID_MISMATCH; return SYNCED_ID_MISMATCH;
} }

View File

@ -175,7 +175,6 @@ tryagain:
/* /*
first tell the remote server to backup first tell the remote server to backup
*/ */
SetStatusFixed(eBatch);
strcpy(pBueffel, "transact syncbackup"); strcpy(pBueffel, "transact syncbackup");
if (syncFile != NULL) { if (syncFile != NULL) {
strcat(pBueffel, " "); strcat(pBueffel, " ");
@ -187,7 +186,6 @@ tryagain:
NETClosePort(connection); NETClosePort(connection);
free(connection); free(connection);
connection = NULL; connection = NULL;
ClearFixedStatus(eEager);
if (try > 0) if (try > 0)
goto tryagain; goto tryagain;
SCWrite(pCon, "ERROR: Failed to contact main SICS server", eError); SCWrite(pCon, "ERROR: Failed to contact main SICS server", eError);
@ -207,7 +205,6 @@ tryagain:
NETClosePort(connection); NETClosePort(connection);
free(connection); free(connection);
connection = NULL; connection = NULL;
ClearFixedStatus(eEager);
pServ->simMode = 1; pServ->simMode = 1;
if (try > 0) if (try > 0)
goto tryagain; goto tryagain;
@ -247,7 +244,6 @@ tryagain:
internalCon = SCCreateDummyConnection(pSics); internalCon = SCCreateDummyConnection(pSics);
if (internalCon == NULL) { if (internalCon == NULL) {
SCWrite(pCon, "ERROR: out of memory in sync", eError); SCWrite(pCon, "ERROR: out of memory in sync", eError);
ClearFixedStatus(eEager);
return 0; return 0;
} }
@ -258,7 +254,6 @@ tryagain:
} }
test = InterpExecute(pSics, internalCon, pBueffel); test = InterpExecute(pSics, internalCon, pBueffel);
SCDeleteConnection(internalCon); SCDeleteConnection(internalCon);
ClearFixedStatus(eEager);
if (test != 1) { if (test != 1) {
SCWrite(pCon, "ERROR: Failed to read sync information", eError); SCWrite(pCon, "ERROR: Failed to read sync information", eError);
return 0; return 0;

View File

@ -352,6 +352,7 @@ static int startMotors(ptasMot self, tasAngles angles,
{ {
double curve; double curve;
int status, silent, stopFixed; int status, silent, stopFixed;
long monoID;
silent = self->math->silent; silent = self->math->silent;
stopFixed = self->math->stopFixed; stopFixed = self->math->stopFixed;
@ -364,11 +365,24 @@ static int startMotors(ptasMot self, tasAngles angles,
*/ */
status = self->math->mono->SetValue(self->math->monoData, status = self->math->mono->SetValue(self->math->monoData,
pCon,angles.monochromator_two_theta); pCon,angles.monochromator_two_theta);
/*
The call to CheckStatus is necessary because the eiger monochromator may not
start until then. Deferred until all parameters are known.
*/
self->math->mono->CheckStatus(self->math->monoData,pCon);
if(status != OKOK){ if(status != OKOK){
return status; return status;
} else { } else {
AddTaskToGroup(pServ->pTasker, self->math->monoTaskID, self->math->groupID); AddTaskToGroup(pServ->pTasker, self->math->monoTaskID, self->math->groupID);
} }
/* monoID = StartDriveTask(self->math->monoData, pCon,"mono", */
/* angles.monochromator_two_theta); */
/* self->math->mono->CheckStatus(self->math->monoData,pCon); */
/* if(monoID < 0){ */
/* SCWrite(pCon,"ERROR: failed to start monochromator",eLogError); */
/* } else { */
/* AddTaskToGroup(pServ->pTasker,monoID, self->math->groupID); */
/* } */
/* /*
analyzer analyzer
@ -583,7 +597,8 @@ static int checkMotors(ptasMot self, SConnection * pCon)
{ {
self->math->mustRecalculate = 1; self->math->mustRecalculate = 1;
if(isTaskGroupRunning(pServ->pTasker,self->math->groupID)){ if(isTaskGroupRunning(pServ->pTasker,self->math->groupID) ||
isTaskGroupRunning(pServ->pTasker,self->math->monoTaskID)){
return HWBusy; return HWBusy;
} else { } else {
return HWIdle; return HWIdle;

32
task.c
View File

@ -24,8 +24,12 @@
#define READY 1 #define READY 1
#define WAITING 2 #define WAITING 2
#define YIELDING 3 #define YIELDING 3
#define IDUNDEFINED 0L
#define TASKMAGIC 777111999
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
typedef struct __TaskHead { typedef struct __TaskHead {
long magic;
long lID; long lID;
long groupID; long groupID;
int iStatus; int iStatus;
@ -46,8 +50,12 @@ typedef struct __TaskMan {
pTaskHead pCurrent; /* Think trice before you interfere with this! */ pTaskHead pCurrent; /* Think trice before you interfere with this! */
pTaskHead pHead; pTaskHead pHead;
} TaskMan; } TaskMan;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------
static long lIDMama = 0L; The 7 below solves a subtle bug which occurs when a groupID in user code
has been initialized to 0 and starting fails. Then it seems as if this
group keeps running. As there will always be some task running at 0.
----------------------------------------------------------------------------*/
static long lIDMama = 7L;
#define TASKERID 123399 #define TASKERID 123399
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -62,6 +70,7 @@ static pTaskHead MakeTaskHead(char *name, TaskFunc pTask, SignalFunc pSignal,
} }
memset(pNew, 0, sizeof(TaskHead)); memset(pNew, 0, sizeof(TaskHead));
pNew->magic = TASKMAGIC;
pNew->name = strdup(name); pNew->name = strdup(name);
pNew->start_time = time(NULL); pNew->start_time = time(NULL);
pNew->pRun = pTask; pNew->pRun = pTask;
@ -71,9 +80,10 @@ static pTaskHead MakeTaskHead(char *name, TaskFunc pTask, SignalFunc pSignal,
lIDMama++; lIDMama++;
pNew->lID = lIDMama; pNew->lID = lIDMama;
pNew->iStatus = READY; pNew->iStatus = READY;
pNew->groupID = IDUNDEFINED;
if(lIDMama < 0){ if(lIDMama < 0){
lIDMama = 0; lIDMama = 7;
} }
return pNew; return pNew;
@ -99,6 +109,7 @@ static void DeleteTaskHead(pTaskHead self)
if (self->pNext != NULL) { if (self->pNext != NULL) {
self->pNext->pPrevious = self->pPrevious; self->pNext->pPrevious = self->pPrevious;
} }
memset(self,0,sizeof(TaskHead));
free(self); free(self);
} }
@ -485,7 +496,7 @@ pTaskHead TaskIteratorStart(pTaskMan self)
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
pTaskHead TaskIteratorNext(pTaskHead it) pTaskHead TaskIteratorNext(pTaskHead it)
{ {
if(it != NULL){ if(it != NULL && it->magic == TASKMAGIC){
return it->pNext; return it->pNext;
} }
return NULL; return NULL;
@ -537,6 +548,15 @@ const char * GetTaskName(pTaskHead it)
return (const char*)it->name; return (const char*)it->name;
} }
/*------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------*/
const void *GetTaskData(pTaskHead it)
{
if(it->magic == TASKMAGIC){
return (const void*)it->pData;
} else {
return NULL;
}
}
/*------------------------------------------------------------------------------*/
long GetTaskGroupID(pTaskMan self) long GetTaskGroupID(pTaskMan self)
{ {
lIDMama++; lIDMama++;
@ -569,13 +589,15 @@ int isTaskGroupRunning(pTaskMan self, long groupID)
pTaskHead pCurrent, pNext; pTaskHead pCurrent, pNext;
if (self == NULL) return 0; if (self == NULL) return 0;
if (groupID == IDUNDEFINED) return 0;
assert(self->iID == TASKERID); assert(self->iID == TASKERID);
pNext = self->pHead->pNext; /* skip dummy task */ pNext = self->pHead->pNext; /* skip dummy task */
while (pNext != NULL) { while (pNext != NULL) {
pCurrent = pNext; pCurrent = pNext;
pNext = pCurrent->pNext; pNext = pCurrent->pNext;
if (pCurrent->groupID == groupID) { if (pCurrent->groupID != IDUNDEFINED && pCurrent->groupID == groupID) {
return 1; return 1;
} }
} }

5
task.h
View File

@ -197,7 +197,10 @@ const char *GetTaskName(pTaskHead it);
/* /*
get the name of the current task. Do not delete the returned pointer. get the name of the current task. Do not delete the returned pointer.
*/ */
const void *GetTaskData(pTaskHead it);
/*
Get the user data for the current task. Do not free the returned pointer!
*/
/*============================================================================= /*=============================================================================
Task Groups. The implementation has the limit that any given task can Task Groups. The implementation has the limit that any given task can
only be member of one task group only be member of one task group

View File

@ -89,8 +89,10 @@ static int TclTaskFunction(void *pData)
MacroPush(self->con); MacroPush(self->con);
status = Tcl_Eval(pTcl, self->scriptName); status = Tcl_Eval(pTcl, self->scriptName);
MacroPop(); MacroPop();
/*
traceSys("task","Executed %s with results %d and %s",self->scriptName, status, traceSys("task","Executed %s with results %d and %s",self->scriptName, status,
Tcl_GetStringResult(pTcl)); Tcl_GetStringResult(pTcl));
*/
if(status == 0){ if(status == 0){
retVal = atoi(Tcl_GetStringResult(pTcl)); retVal = atoi(Tcl_GetStringResult(pTcl));
} else { } else {

View File

@ -8,6 +8,13 @@
* copyright: see file COPYRIGHT * copyright: see file COPYRIGHT
* *
* Mark Koennecke, February 2013 * Mark Koennecke, February 2013
*
* TODO: this may need a refactoring towards a monochromator object with its
* own parameters and such. Eiger would have benefitted from this. This here
* just implements a drivable interface on top of the tasub parameters. As EIGER
* is now working; this has gone low priority.
*
* Mark Koennecke, September 2014
*/ */
#include <sics.h> #include <sics.h>
#include "tasmono.h" #include "tasmono.h"

View File

@ -771,7 +771,6 @@ static int TASUBScanCount(pScanData self, int iPoint)
} else { } else {
status = 1; status = 1;
} }
SetStatus(eOld);
return status; return status;
} }

View File

@ -5,7 +5,7 @@
Mark Koennecke, May 2005, using code from an earlier TASAMAD emulation Mark Koennecke, May 2005, using code from an earlier TASAMAD emulation
core. core.
------------------------------------------------------------------------*/ ------------------------------------------------------------------------*/
#ifndef SICUBSTAS #ifndef SICSUBTAS
#define SICSUBTAS #define SICSUBTAS
#include <sicsvar.h> #include <sicsvar.h>
#include "tasub.h" #include "tasub.h"

View File

@ -15,6 +15,7 @@
Mark Koennecke, September 2011 Mark Koennecke, September 2011
----------------------------------------------------------------------*/ ----------------------------------------------------------------------*/
#include <assert.h> #include <assert.h>
#include <math.h>
#include "sics.h" #include "sics.h"
#include "lld.h" #include "lld.h"
#include "SCinter.h" #include "SCinter.h"
@ -971,7 +972,7 @@ static void listDiagnostik(ptasUB self, SConnection * pCon)
static int addAuxReflection(ptasUB self, SConnection * pCon, static int addAuxReflection(ptasUB self, SConnection * pCon,
SicsInterp * pSics, int argc, char *argv[]) SicsInterp * pSics, int argc, char *argv[])
{ {
int status; int status, ss;
tasReflection r1, r2; tasReflection r1, r2;
float value = -999.99; float value = -999.99;
char pBueffel[256]; char pBueffel[256];
@ -1027,7 +1028,8 @@ static int addAuxReflection(ptasUB self, SConnection * pCon,
r2.qe.kf = self->current.kf; r2.qe.kf = self->current.kf;
r2.qe.ki = self->current.ki; r2.qe.ki = self->current.ki;
GetDrivablePosition(self->motors[A3], pCon, &value); GetDrivablePosition(self->motors[A3], pCon, &value);
r2.angles.a3 = value + 180.; ss = self->machine.ss_sample;
r2.angles.a3 = fmod(value + ss*180.,360.) - ss*180.;
r2.angles.sgu = .0; r2.angles.sgu = .0;
r2.angles.sgl = .0; r2.angles.sgl = .0;
calcTwoTheta(B, r2.qe, self->machine.ss_sample, calcTwoTheta(B, r2.qe, self->machine.ss_sample,

View File

@ -184,7 +184,7 @@ double tasAngleBetweenReflections(MATRIX B, tasReflection r1,
chi1 = mat_mul(B, h1); chi1 = mat_mul(B, h1);
chi2 = mat_mul(B, h2); chi2 = mat_mul(B, h2);
if (chi1 != NULL && chi2 != NULL) { if (chi1 != NULL && chi2 != NULL) {
angle = angleBetween(chi1, chi2); angle = tasAngleBetween(chi1, chi2);
killVector(chi1); killVector(chi1);
killVector(chi2); killVector(chi2);
} }
@ -271,8 +271,9 @@ int makeAuxReflection(MATRIX B, tasReflection r1, tasReflection * r2,
r2->qe.ki = r1.qe.ki; r2->qe.ki = r1.qe.ki;
r2->qe.kf = r1.qe.kf; r2->qe.kf = r1.qe.kf;
theta = calcTheta(r1.qe.ki, r1.qe.kf, r1.angles.sample_two_theta); theta = calcTheta(r1.qe.ki, r1.qe.kf,
om = r1.angles.a3 - theta; ss*r1.angles.sample_two_theta);
om = r1.angles.a3 - ss*theta;
om += tasAngleBetweenReflections(B, r1, *r2); om += tasAngleBetweenReflections(B, r1, *r2);
QC = tasReflectionToHC(r2->qe, B); QC = tasReflectionToHC(r2->qe, B);
@ -289,12 +290,17 @@ int makeAuxReflection(MATRIX B, tasReflection r1, tasReflection * r2,
return TRIANGLENOTCLOSED; return TRIANGLENOTCLOSED;
} }
r2->angles.sample_two_theta = ss * Acosd(cos2t); r2->angles.sample_two_theta = ss * Acosd(cos2t);
theta = calcTheta(r1.qe.ki, r1.qe.kf, r2->angles.sample_two_theta); theta = calcTheta(r1.qe.ki, r1.qe.kf, ss*r2->angles.sample_two_theta);
r2->angles.a3 = om + theta; r2->angles.a3 = om + ss*theta;
r2->angles.a3 = fmod(r2->angles.a3 + ss*180.,360.) - ss*180.;
/*
r2->angles.a3 -= 180.; r2->angles.a3 -= 180.;
if (r2->angles.a3 < -180.) { if (r2->angles.a3 < -180.) {
r2->angles.a3 += 360.; r2->angles.a3 += 360.;
} }
*/
mat_free(QC); mat_free(QC);
return 1; return 1;
@ -415,21 +421,15 @@ MATRIX calcPlaneNormalQ(MATRIX UB, tasReflection r1, tasReflection r2)
return planeNormal; return planeNormal;
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------
MATRIX calcTestUB(lattice cell, double om, double sgu, double sgl) This is shot. The resulting UB is invalid. This needs more throught.
{
MATRIX B, M, N, OM, UB;
int status;
/*
* create matrices
*/ */
B = mat_creat(3, 3, ZERO_MATRIX); MATRIX calcUBFromAngles(MATRIX B, double om, double sgu, double sgl)
{
status = calculateBMatrix(cell, B); MATRIX M, N, OM, UB;
if (status < 0) { int status;
return NULL;
}
M = mat_creat(3, 3, ZERO_MATRIX); M = mat_creat(3, 3, ZERO_MATRIX);
N = mat_creat(3, 3, ZERO_MATRIX); N = mat_creat(3, 3, ZERO_MATRIX);
@ -468,11 +468,30 @@ MATRIX calcTestUB(lattice cell, double om, double sgu, double sgl)
mat_free(OM); mat_free(OM);
mat_free(N); mat_free(N);
mat_free(M); mat_free(M);
mat_free(B);
return UB; return UB;
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
MATRIX calcTestUB(lattice cell, double om, double sgu, double sgl)
{
MATRIX B, UB;
int status;
/*
* create matrices
*/
B = mat_creat(3, 3, ZERO_MATRIX);
status = calculateBMatrix(cell, B);
if (status < 0) {
return NULL;
}
UB = calcUBFromAngles(B,om,sgu,sgl);
mat_free(B);
return UB;
}
/*--------------------------------------------------------------------*/
MATRIX calcTestNormal(double sgu, double sgl) MATRIX calcTestNormal(double sgu, double sgl)
{ {
MATRIX M, N, Z, NORM; MATRIX M, N, Z, NORM;

View File

@ -186,21 +186,33 @@ MATRIX calcTasUBFromTwoReflections(lattice cell, tasReflection r1,
*/ */
MATRIX calcTestNormal(double sgu, double sgl); MATRIX calcTestNormal(double sgu, double sgl);
/** /**
* calculate a test UB * calculate a test UB from angles
* @param cell The lattice constant of the crystal * @param cell The B lattice constants
* @param om A theoretical om for the crystal * @param om A theoretical om for the crystal
* @param sgu A theoretical plane tilt on upper * @param sgu A theoretical plane tilt on upper
* @param sgl A theoretical plane tilt on lower * @param sgl A theoretical plane tilt on lower
* @return a UB matix on sucess, or NULL on failure. This can only happen * @return a UB matrix on sucess, or NULL on failure. This can only happen
* when out of memory or with a bad cell * when out of memory or with a bad cell
*/ */
MATRIX calcTestUB(lattice cell, double om, double sgu, double sgl); MATRIX calcTestUB(lattice cell, double om, double sgu, double sgl);
/**
* calculate a test UB
* @param B The B matrix as calculated from the cell constants
* @param om A theoretical om for the crystal
* @param sgu A theoretical plane tilt on upper
* @param sgl A theoretical plane tilt on lower
* @return a UB matrix on sucess, or NULL on failure. This can only happen
* when out of memory or with a bad cell
*/
MATRIX calcUBFromAngles(MATRIX B, double om, double sgu, double sgl);
/** /**
* calcluate the normal to the plane describe by the two reflections r1, r2 * calcluate the normal to the plane describe by the two reflections r1, r2
* @param r1 first reflection * @param r1 first reflection
* @param r2 second reflection * @param r2 second reflection
* @return a plane normal on success, NULL else * @return a plane normal on success, NULL else
*/ */
MATRIX calcPlaneNormal(tasReflection r1, tasReflection r2); MATRIX calcPlaneNormal(tasReflection r1, tasReflection r2);
/** /**
* calcluate the normal to the plane describe by the two reflections r1, r2 * calcluate the normal to the plane describe by the two reflections r1, r2

52
trace.c
View File

@ -37,6 +37,7 @@ static int hdbInit = 0;
static int filterProv = 0; static int filterProv = 0;
static int debug = 0; static int debug = 0;
static int lastTen = -10; static int lastTen = -10;
static long traceStamperID = -1;
/*----------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------*/
int traceActive() int traceActive()
{ {
@ -468,12 +469,56 @@ static int TraceLog(pSICSOBJ ccmd, SConnection * con,
TraceObjects(); TraceObjects();
hdbInit = 1; hdbInit = 1;
} }
TaskRegisterN(pServ->pTasker,"tracestamper", if(traceStamperID < 0){
traceStamperID = TaskRegisterN(pServ->pTasker,"tracestamper",
TraceLogTask, NULL, NULL, NULL, 1); TraceLogTask, NULL, NULL, NULL, 1);
} }
} }
}
return 1; return 1;
} }
/*----------------------------------------------------------------*/
static int TraceAppend(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
char *filename = NULL;
if(nPar < 1) {
if(logFD != NULL){
SCPrintf(con,eValue,"Tracing to %s", logfile);
} else {
SCWrite(con,"Tracing is off", eValue);
}
return 1;
}
filename = par[0]->value.v.text;
/*
This is good even if appending to the same file:
it flushes all buffers
*/
if(logFD != NULL){
fclose(logFD);
free(logfile);
}
logFD = fopen(filename,"a+");
if(logFD == NULL){
SCPrintf(con,eError,"ERROR: failed to open %s for logging", filename);
return 0;
} else {
logfile = strdup(filename);
saveInitialParameters();
SCPrintf(con,eValue,"Logging to %s", filename);
if(hdbInit == 0){
TraceObjects();
hdbInit = 1;
}
TaskRegisterN(pServ->pTasker,"tracestamper",
TraceLogTask, NULL, NULL, NULL, 1);
}
return 1;
}
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
static int TraceDebug(pSICSOBJ ccmd, SConnection * con, static int TraceDebug(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar) Hdb * cmdNode, Hdb * par[], int nPar)
@ -520,6 +565,11 @@ void MakeTrace(void)
"log", usMugger, MakeSICSFunc(TraceLog)); "log", usMugger, MakeSICSFunc(TraceLog));
AddSICSHdbPar(cmd, "filename", usMugger, MakeHdbText("")); AddSICSHdbPar(cmd, "filename", usMugger, MakeHdbText(""));
cmd = AddSICSHdbPar(ccmd->objectNode,
"append", usMugger, MakeSICSFunc(TraceAppend));
AddSICSHdbPar(cmd, "filename", usMugger, MakeHdbText(""));
cmd = AddSICSHdbPar(ccmd->objectNode, cmd = AddSICSHdbPar(ccmd->objectNode,
"filter", usMugger, MakeSICSFunc(TraceFilter)); "filter", usMugger, MakeSICSFunc(TraceFilter));
AddSICSHdbPar(cmd, "selection", usMugger, MakeHdbInt(0)); AddSICSHdbPar(cmd, "selection", usMugger, MakeHdbInt(0));

View File

@ -189,6 +189,37 @@ double angleBetween(MATRIX v1, MATRIX v2)
} }
return angle; return angle;
} }
/*-----------------------------------------------------------------------
angleBetween gives only angles between 0 - 180. This is also the
only thing there is; the direction of the rotation depends on the
viewpoint and thus is ill defined. This version determines the
sign of the rotation from v3[2]. I made a special version in order not
to trouble other uses of angleBetween.
-----------------------------------------------------------------------*/
double tasAngleBetween(MATRIX v1, MATRIX v2)
{
double angle, angles, sum;
MATRIX v3 = NULL;
int i;
angle = vectorDotProduct(v1, v2) / (vectorLength(v1) * vectorLength(v2));
v3 = vectorCrossProduct(v1, v2);
if (v3 != NULL) {
angles = vectorLength(v3) / (vectorLength(v1) * vectorLength(v2));
angle = Atan2d(angles, angle);
for(i = 0, sum = .0; i < 3; i++){
sum += v3[i][0];
}
if(sum < 0){
angle *= -1.;
}
} else {
angle = Acosd(angle);
}
return angle;
}
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
void scaleVector(MATRIX v, double scale) void scaleVector(MATRIX v, double scale)

View File

@ -91,12 +91,20 @@ MATRIX vectorCrossProduct(MATRIX v1, MATRIX v2);
*/ */
MATRIX matFromTwoVectors(MATRIX v1, MATRIX v2); MATRIX matFromTwoVectors(MATRIX v1, MATRIX v2);
/** /**
* calculate the nagle between two vectors * calculate the angle between two vectors
* @param v1 first vector * @param v1 first vector
* @param v2 second vector * @param v2 second vector
* @return angle in degree * @return angle in degree
*/ */
double angleBetween(MATRIX v1, MATRIX v2); double angleBetween(MATRIX v1, MATRIX v2);
/**
* calculate the angle between two vectors. Try to determine the
* sign of the rotation
* @param v1 first vector
* @param v2 second vector
* @return angle in degree
*/
double tasAngleBetween(MATRIX v1, MATRIX v2);
/** /**
* scale the vector v with scale * scale the vector v with scale

5
velo.c
View File

@ -588,10 +588,7 @@ int VSGetLossCurrent(pVelSel self, SConnection * pCon, float *fLoss)
assert(self); assert(self);
assert(pCon); assert(pCon);
eOld = GetStatus();
SetStatus(eRunning);
iRet = self->pDriv->GetLossCurrent(self->pDriv, fLoss); iRet = self->pDriv->GetLossCurrent(self->pDriv, fLoss);
SetStatus(eOld);
if (!iRet) { if (!iRet) {
self->pDriv->GetError(self->pDriv, &iCode, pError, 131); self->pDriv->GetError(self->pDriv, &iCode, pError, 131);
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: %s while trying to measure loss current", snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: %s while trying to measure loss current",
@ -1161,9 +1158,7 @@ int VelSelAction(SConnection * pCon, SicsInterp * pSics, void *pData,
eError); eError);
return 0; return 0;
} }
SetStatus(eDriving);
iRet = VSSetTiltRot(self, pCon, fRot, fTilt); iRet = VSSetTiltRot(self, pCon, fRot, fTilt);
SetStatus(eEager);
if (iRet) { if (iRet) {
SCSendOK(pCon); SCSendOK(pCon);
return 1; return 1;