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
*/
Tcl_DeleteInterp(pTcl);
KillSicsUnknown();
}

View File

@ -155,7 +155,7 @@ void *FindCommandData(SicsInterp * pSics, char *name, char *comclass);
*/
pObjectDescriptor FindCommandDescriptor(SicsInterp * pSics, char *name);
/*------------------------------------------------------------------------
/*---------------------------------------------------------------------
FindDrivable tries to find Drivable object by the name given. Returns a
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

View File

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

View File

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

View File

@ -145,6 +145,14 @@ int ANETinfo(int handle, char *hostname, int hostNameLen);
* \return 1 on success, 0 on failure
*/
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
* the read buffer yet.

View File

@ -9,7 +9,7 @@
--------------------------------------------------------------------------*/
#ifndef 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 WriteToCommandLogCmd(int id, char *text);
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);
target.h = v.v.floatArray[0];
target.k = v.v.floatArray[1];
target.l = v.v.floatArray[2];
SICSHdbGetPar(obj, pCon, "qscale", &v);
/*
@ -198,7 +197,7 @@ static long ConeSetValue(void *pData, SConnection * pCon, float fVal)
mat_free(csToPsi);
if (status != 1) {
SCWrite(pCon, "ERROR: cannot get cone vector into scattering position",
eError);
eLogError);
SCSetInterrupt(pCon, eAbortOperation);
return 0;
}

View File

@ -1016,7 +1016,6 @@ int SCPureSockWrite(SConnection * self, char *buffer, int iOut)
return 1;
}
/*--------------------------------------------------------------------------
special for ClientLog. Do not use elsewhere without check
----------------------------------------------------------------------------*/
@ -1044,6 +1043,18 @@ int SCLogWrite(SConnection * self, char *buffer, int iOut)
if(pPtr != pBueffel){
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 {
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);
return 0;
}
pBuf = malloc(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;
/*
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 */
memset(outBuf, 0, 65536);
@ -1270,6 +1296,16 @@ int SCWriteBinary(SConnection * self, char *pName, void *pData,
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 */
memset(outBuf, 0, 65536);
@ -1521,8 +1557,6 @@ int SCPrompt(SConnection * pCon, char *pPrompt, char *pResult, int iLen)
SCWrite(pCon, pPrompt, eWarning);
master = SCfindMaster(pCon);
eOld = GetStatus();
SetStatus(eInput);
CostaUnlock(master->pStack);
while (1) {
/*
@ -1542,14 +1576,12 @@ int SCPrompt(SConnection * pCon, char *pPrompt, char *pResult, int iLen)
/* do we have data ? */
iRet = CostaPop(master->pStack, &pPtr);
if (iRet == 1) {
SetStatus(eOld);
CostaLock(master->pStack);
strlcpy(pResult, pPtr, iLen);
WriteToCommandLogId(" prompted>", pCon->sockHandle, pPtr);
return 1;
}
}
SetStatus(eOld);
CostaLock(master->pStack);
return 0;
}
@ -1570,8 +1602,6 @@ int SCPromptTMO(SConnection * pCon, char *pPrompt, char *pResult, int iLen, int
SCWrite(pCon, pPrompt, eWarning);
master = SCfindMaster(pCon);
eOld = GetStatus();
SetStatus(eInput);
CostaUnlock(master->pStack);
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 ? */
iRet = CostaPop(master->pStack, &pPtr);
if (iRet == 1) {
SetStatus(eOld);
CostaLock(master->pStack);
strlcpy(pResult, pPtr, iLen);
WriteToCommandLogId(" prompted>", pCon->sockHandle, pPtr);
return 1;
}
}
SetStatus(eOld);
CostaLock(master->pStack);
return 0;
}
@ -1724,10 +1752,8 @@ int SCInvoke(SConnection * self, SicsInterp * pInter, char *pCommand)
return 0;
}
strlcpy(pCopy->deviceID, pBueffel, SCDEVIDLEN);
/* SCAdvanceContext(self,pBueffel); */
traceCommand(ConID(self),"in:%s", pCommand);
iRet = InterpExecute(pInter, pCopy, pCommand);
/* SCPopContext(self); */
SCDeleteConnection(pCopy);
StatusFileTask(NULL); /* save changed parameters */

View File

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

View File

@ -9,6 +9,7 @@
*
* Mark Koennecke, February 2009
*/
#include <math.h>
#include <time.h>
#include <sics.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 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,"continue", usUser, MakeSICSFunc(ContinueCmd));
child = AddSICSHdbPar(node,"interest", usUser, MakeSICSFunc(InterestCmd));
child = AddSICSHdbPar(node,"countstatus", usUser, MakeSICSFunc(CountStatusCmd));
return pRes;
}

View File

@ -182,12 +182,13 @@ pExeList CreateExeList(pTaskMan pTask)
pRes->waitID = -1;
pRes->runID = -1;
pRes->iLock = 0;
pRes->drivePrint = 0;
pRes->drivePrint = 0;
pRes->paused = 0;
pRes->taskRunning = 0;
pRes->pCall = CreateCallBackInterface();
pRes->lastRun = time(NULL);
pRes->pDes->GetInterface = DevexecInterface;
pRes->instStatus = eEager;
return pRes;
}
@ -295,7 +296,6 @@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
taskID = StartDriveTask(pData, pCon, name, fNew);
if(taskID > 0 && self->instStatus != eCounting){
self->instStatus = eDriving;
SetStatus(eDriving);
}
if(taskID > 0 && self->drivePrint == 1){
oldVal = pDrivInt->GetValue(pData, pCon);
@ -307,7 +307,6 @@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
taskID = StartCountTask(pData,pCon,name);
if(taskID > 0){
self->instStatus = eCounting;
SetStatus(eCounting);
}
} else {
SCPrintf(pCon,eLogError, "ERROR: type unkonw, cannot start %s", name);
@ -530,7 +529,6 @@ int PauseExecution(pExeList self)
if(IsCounting(self)){
TaskSignalGroup(self->pTask, IPAUSE, &interrupt, self->waitID);
TaskSignalGroup(self->pTask, IPAUSE, &interrupt, self->runID);
SetStatus(ePaused);
}
return 1;
@ -559,7 +557,6 @@ int ContinueExecution(pExeList self)
if(GetStatus() == ePaused){
TaskSignalGroup(self->pTask, CONTINUE, &interrupt, self->waitID);
TaskSignalGroup(self->pTask, CONTINUE, &interrupt, self->runID);
SetStatus(eCounting);
}
return 1;
}
@ -716,7 +713,6 @@ int Success(SConnection * pCon, SicsInterp * pSics, void *pData,
pExeList self = (pExeList)pData;
eOld = GetStatus();
SetStatus(eRunning);
if(argc > 1){
if(strcmp(argv[1],"RUNDRIVE") == 0){
@ -758,7 +754,6 @@ int Success(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, "Level done", eValue);
iRet = 1;
}
SetStatus(eEager);
return iRet;
}
/*-------------------------------------------------------------------------*/
@ -894,7 +889,6 @@ int DevExecTask(void *pData)
self->lTask = -1;
self->iRun = 0;
self->instStatus = eEager;
SetStatus(eEager);
/*
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.
@ -965,3 +959,12 @@ void SetDevexecStatus(pExeList pExe, int 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 level, char *name);
#line 249 "devexec.w"
#line 251 "devexec.w"
/*------------------------------------------------------------------------*/
@ -77,8 +77,10 @@
int DevExecTask(void *pEL);
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 StopExeWait(pExeList self);
@ -122,7 +124,7 @@
int ContinueExecution(pExeList self);
#line 269 "devexec.w"
#line 271 "devexec.w"
/*-------------------------- Commands ------------------------------------*/
int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData,
@ -164,13 +166,13 @@
/*--------------------------- Locking ---------------------------------*/
#line 190 "devexec.w"
#line 192 "devexec.w"
void LockDeviceExecutor(pExeList self);
void UnlockDeviceExecutor(pExeList self);
#line 309 "devexec.w"
#line 311 "devexec.w"
/* -------------------------- Executor management -------------------------*/

View File

@ -101,6 +101,8 @@ From within the SICS main loops this special function is called:
int DevExecTask(void *pEL);
void DevExecSignal(void *pEL, int iSignal, void *pSigData);
int GetDevExecInstStatus(pExeList self);
@}
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

View File

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

View File

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

View File

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

View File

@ -224,7 +224,16 @@ pDynString findBatchFile(SicsInterp * pSics, char *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,
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 exeHdbNode(pHdb exeNode, SConnection * pCon);
int isBatchRunning();
#endif

View File

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

View File

@ -22,6 +22,7 @@ static char update[] = { "update" };
static char treeChange[] = { "treeChange" };
static char dataSearch[] = { "dataSearch" };
static char killNode[] = { "killNode" };
static char propertyChange[] = { "propertyChange" };
/*------------------------------------------------------------------------*/
pHdbDataMessage GetHdbSetMessage(pHdbMessage toTest)
@ -77,6 +78,15 @@ pHdbMessage GetHdbKillNodeMessage(pHdbMessage toTest)
return NULL;
}
/*-------------------------------------------------------------------------*/
pHdbPropertyChange GetPropertyChangeMessage(pHdbMessage toTest)
{
if (toTest->type == propertyChange) {
return (pHdbPropertyChange)toTest;
}
return NULL;
}
/*================== internal functions ===================================*/
void DeleteCallbackChain(pHdb node)
{
@ -1140,6 +1150,8 @@ static int calcDataLength(pHdb node, int testLength)
/*============================= Property Functions ==========================*/
void SetHdbProperty(pHdb node, char *key, char *value)
{
hdbPropertyChange propMes;
if (node != NULL && key != NULL && node->properties != NULL) {
if (value == NULL) {
StringDictDelete(node->properties, key);
@ -1148,6 +1160,10 @@ void SetHdbProperty(pHdb node, char *key, char *value)
} else {
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
*
* Refactored callback handling, Markus Zolliker, Mark Koennecke, March 2008
*
* Added property chnage events. Mark Koennecke, February 2015
*/
#ifndef HIPADABA
#define HIPADABA
@ -71,11 +73,12 @@ typedef struct __hipadaba {
struct __hdbcallback *callBackChain;
char *name;
hdbValue value;
int protected;
int iprotected;
pStringDict properties;
} Hdb, *pHdb;
/*-------------- return values for callback functions -------------------------*/
typedef enum { hdbContinue,
typedef enum {
hdbContinue,
hdbAbort,
hdbKill
} hdbCallbackReturn;
@ -101,6 +104,12 @@ typedef struct {
void *result;
} hdbDataSearch, *pHdbDataSearch;
/*-------------------------------------------------------------------------------*/
typedef struct {
char *type;
char *key;
char *value;
} hdbPropertyChange, *pHdbPropertyChange;
/*-------------------------------------------------------------------------------*/
typedef hdbCallbackReturn(*hdbCallbackFunction) (pHdb currentNode,
void *userData,
pHdbMessage message);
@ -156,6 +165,14 @@ pHdbDataSearch GetHdbDataSearchMessage(pHdbMessage toTest);
* pointer if it is.
*/
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 ========================*/
/**
* 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);
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];
}
/* printf("initArray called with length %d\n", length);*/
@ -262,6 +262,22 @@ static int SumCmd(pSICSOBJ ccmd, SConnection * pCon,
}
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,
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, "yend", usSpy, MakeHdbInt(0));
child = AddSICSHdbPar(node,"total", usSpy, MakeSICSFunc(TotalCmd));
/*
* test TOF option
*/

View File

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

View File

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

View File

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

View File

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

View File

@ -11,5 +11,6 @@
MFLAGS=-f makefile_macosx
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 */
eOld = GetStatus();
SetStatus(eBatch);
SICSLogWrite("Evaluating in MacroFileEval", eValue);
SICSLogWrite(argv[1], eValue);
@ -500,7 +498,6 @@ int MacroFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
Tcl_DStringAppend(&command, pBueffel, -1);
pCom = Tcl_DStringValue(&command);
if (Tcl_CommandComplete(pCom)) {
SetStatus(eEager);
FirstWord(pCom, pBueffel);
if (FindCommand(pInter, pBueffel) != NULL) {
snprintf(pBueffel,sizeof(pBueffel)-1, "%s:%d>> %s", pFile, iLine, pCom);
@ -512,7 +509,6 @@ int MacroFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
iLine++;
}
iRet = Tcl_Eval(pTcl, pCom);
SetStatus(eBatch);
if (iRet != TCL_OK) {
/* write TCL error and check for total interrupt */
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);
Tcl_DStringFree(&command);
SCWrite(pCon, "ERROR: batch processing interrupted", eError);
SetStatus(eEager);
return 0;
} else {
SCSetInterrupt(pCon, eContinue);
@ -555,7 +550,6 @@ int MacroFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
/* clean up */
fclose(fp);
Tcl_DStringFree(&command);
SetStatus(eOld);
SCSendOK(pCon);
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 \
histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.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
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
.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
full: purge all
@ -81,12 +81,7 @@ $(SICSROOT)/sicspsi/hardsup/libhlib.a: libhlib
libhlib:
cd $(SICSROOT)/sicspsi/hardsup; make $(MFLAGS) libhlib.a
$(SICSROOT)/sicspsi/tecs/libtecsl.a: libtecsl
libtecsl:
cd $(SICSROOT)/sicspsi/tecs; make $(MFLAGS) libtecsl.a
$SICSROOT)/sicspsi/libpsi.a: libpsi
$(SICSROOT)/sicspsi/libpsi.a: libpsi
libpsi:
cd $(SICSROOT)/sicspsi; make $(MFLAGS) libpsi.a
@ -98,7 +93,6 @@ clean:
rm -f *.o *.d SICServer
cd $(SICSROOT)/sicspsi/hardsup; make $(MFLAGS) clean
cd matrix; make $(MFLAGS) clean
cd $(SICSROOT)/sicspsi/tecs; make $(MFLAGS) clean
cd $(SICSROOT)/sicspsi; make $(MFLAGS) clean
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
@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
include makefile_$(SICS_MAKE_VERSION)

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
BINTARGET = bin
EXTRA=
SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \
psi/tecs/libtecsl.a
SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a
LIBS = -L$(HDFROOT)/lib $(SUBLIBS) \
-ltcl -lfor $(HDFROOT)/lib/libhdf5.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
EXTRA=nintf.o
SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \
psi/tecs/libtecsl.a
SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a
LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\
-ltcl -lNeXus -lhdf5 -lmfhdf -ldf \
-lmxml -lghttp -ljpeg -ljson -ldl -lz -lm -lc

View File

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

View File

@ -12,11 +12,14 @@ NI= -DHAVENI
NIOBJ= nigpib.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
CC = gcc
CFLAGS = -I$(HDFROOT)/include -DNXXML -DHDF5 $(NI) \
-I$(SICSROOT)/sicspsi/hardsup -I$(SICSROOT) -I. -MMD \
-Werror -DCYGNUS -DNONINTF $(DBG) $(DFORTIFY) \
@ -25,7 +28,7 @@ CFLAGS = -I$(HDFROOT)/include -DNXXML -DHDF5 $(NI) \
BINTARGET = bin
EXTRA=nintf.o
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) \
-ltcl -lNeXus $(HDFROOT)/lib/libhdf5.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
@echo
#---------- for Redhat linux
#CC= gcc
#CFLAGS= -I/usr/local/include -I. -I../ -DLINUX -g -c
%.o: usage
@echo
#------------ for DigitalUnix
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:
@ 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
.c.o:
$(CC) $(CFLAGS) $*.c
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);
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 {
site = getSite();
if (site != NULL) {

View File

@ -47,6 +47,7 @@
#define ABS(x) (x < 0 ? -(x) : (x))
/*-------------------------------------------------------------------------*/
static void SecMotorSetError(pMotor self, char *text)
{
@ -268,9 +269,6 @@ static int checkPosition(pMotor self, SConnection * pCon)
node = GetHipadabaNode(self->pDescriptor->parNode, "hardposition");
assert(node != NULL);
SetHipadabaPar(node, MakeHdbFloat(target), pCon);
node = GetHipadabaNode(self->pDescriptor->parNode, "targetposition");
assert(node != NULL);
SetHipadabaPar(node, MakeHdbFloat(target), pCon);
return HWBusy;
}
return HWIdle;
@ -377,7 +375,7 @@ static float SecMotorGetValue(void *pData, SConnection * pCon)
assert(pData);
status = GetHdbProperty(self->pDescriptor->parNode,"geterror", error,sizeof(error));
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;
}
status = GetHipadabaPar(self->pDescriptor->parNode, &v, pCon);
@ -467,7 +465,7 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
pHdb child = NULL;
pMotor self = NULL;
float fHard, fVal, sign, zero;
char pBueffel[512], pError[132];
char pBueffel[512], pError[132], *pPtr = NULL;
int status;
self = (pMotor) userData;
@ -511,6 +509,7 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
self->name);
SCWrite(pCon, pBueffel, eWarning);
self->errorCount = 0;
self->pDrivInt->iErrorCount = 0;
}
/*
@ -527,6 +526,8 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
ServerWriteGlobal(pBueffel, eError);
SCSetInterrupt(pCon, eAbortBatch);
self->pDrivInt->iErrorCount = 0;
child = GetHipadabaNode(self->pDescriptor->parNode, "status");
UpdateHipadabaPar(child, MakeHdbText("run"), pCon);
return hdbAbort;
}
@ -548,6 +549,12 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
if (mm != NULL) {
pCon = (SConnection *) mm->callData;
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);
node->value.v.doubleValue = fVal;
mm->v->v.doubleValue = fVal;
@ -562,6 +569,7 @@ static hdbCallbackReturn HardUpdateCallback(pHdb node, void *userData,
pHdbMessage message)
{
pHdbDataMessage mm = NULL;
pHdbPropertyChange pm = NULL;
pMotor self = (pMotor) userData;
float fVal;
hdbValue v;
@ -576,6 +584,18 @@ static hdbCallbackReturn HardUpdateCallback(pHdb node, void *userData,
UpdateHipadabaPar(self->pDescriptor->parNode, v, mm->callData);
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;
}
@ -655,6 +675,80 @@ static hdbCallbackReturn SecMotorZeroCallback(pHdb node, void *userData,
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)
{
@ -793,6 +887,10 @@ pMotor SecMotorInit(char *name)
child = MakeHipadabaNode("error", HIPTEXT, 1);
AddHipadabaChild(node, child, NULL);
child = AddSICSHdbPar(node,"interest", usUser, MakeSICSFunc(InterestCmd));
AddSICSHdbPar(child, "name", usUser, MakeHdbText("UNKNOWN"));
pM->endScriptID = 0;
/* initialise Drivable interface */

View File

@ -15,7 +15,14 @@
#include <counter.h>
#include <stptok.h>
#include <macro.h>
#include <status.h>
#include "sicshipadaba.h"
/*---------------------------------------------------------------------------*/
typedef struct {
float fPreset;
float fCurrent;
char *pName;
} MonEvent, *pMonEvent;
/*-------------------------------------------------------------------------*/
static void SecCounterSetError(pCounter self, char *text)
{
@ -134,6 +141,7 @@ static void startMultiCounting(pHdb self, SConnection *pCon)
assert(sID != NULL);
assert(mID != NULL);
strtolower(mode->value.v.text);
if(strcmp(mode->value.v.text,"timer") == 0) {
eMode = eTimer;
} else {
@ -231,129 +239,177 @@ static hdbCallbackReturn MultiSecControllCallback(pHdb node,
return hdbContinue;
}
/*-------------------------------------------------------------------------------------*/
static int isMultiMasterRunning(pCounter self, SConnection *pCon, int *status)
/*-------------------------------------------------------------------------2-*/
static int MultiSecTransfer(void *pData, SConnection * pCon)
{
pHdb mID, master, myStatus, control, ccd, stopTime;
hdbValue v;
long mlID;
void *data;
pICountable pCount;
float controlVal;
int i, retVal = OKOK, tclStatus;
char pBueffel[132];
pCounter pCount = NULL;
pHdb transfer;
SConnection *myCon;
mID = GetHipadabaNode(self->objectNode,"masterID");
master = GetHipadabaNode(self->objectNode,"master");
myStatus = GetHipadabaNode(self->objectNode,"status");
control = GetHipadabaNode(self->objectNode,"control");
ccd = GetHipadabaNode(self->objectNode,"ccd");
stopTime = GetHipadabaNode(self->objectNode,"stopTime");
assert(mID != NULL);
assert(master != NULL);
assert(myStatus != NULL);
assert(control != NULL);
assert(ccd != NULL);
assert(stopTime != NULL);
pCount = (pCounter) pData;
mlID = mID->value.v.intValue;
if(mlID == 0) {
return 0;
}
data = FindCommandData(pServ->pSics,master->value.v.text,NULL);
assert(data != NULL);
pCount = GetCountableInterface(data);
assert(pCount != NULL);
if(isTaskIDRunning(pServ->pTasker,mlID)) {
*status = pCount->CheckCountStatus(data,pCon);
controlVal = GetControlValue((pCounter)data);
UpdateHipadabaPar(control,MakeHdbFloat(controlVal),pCon);
SecCounterSetError(self,"None");
switch(*status){
case HWFault:
UpdateHipadabaPar(myStatus,MakeHdbText("error"),pCon);
UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon);
SecCounterSetError(self,"Master counter errror");
*status = HWBusy;
break;
case HWPause:
UpdateHipadabaPar(myStatus,MakeHdbText("paused"),pCon);
break;
case HWNoBeam:
UpdateHipadabaPar(myStatus,MakeHdbText("nobeam"),pCon);
break;
default:
*status = HWBusy;
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
break;
}
} else {
/*
we recently stopped. Mark it so and stop slaves.
*/
mID->value.v.intValue = 0;
*status = HWBusy;
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon);
if(ccd->value.v.intValue != 1) {
doCountCommand(self->objectNode,pCon,1011);
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 1;
return retVal;
}
/*-------------------------------------------------------------------------------------*/
static int areSlavesRunning(pCounter self, SConnection *pCon, int *status)
{
pHdb slaveID, myStatus, stopTime, ccd;
int i;
static int isMultiMasterRunning(pCounter self, SConnection *pCon, int *status)
{
pHdb mID, master, myStatus, control, ccd, stopTime, timeNode;
hdbValue v;
long mlID;
void *data;
pICountable pCount;
float controlVal, tVal;
MonEvent sMon;
slaveID = GetHipadabaNode(self->objectNode,"slaveID");
myStatus = GetHipadabaNode(self->objectNode,"status");
stopTime = GetHipadabaNode(self->objectNode,"stopTime");
ccd = GetHipadabaNode(self->objectNode,"ccd");
assert(slaveID != NULL);
assert(myStatus != NULL);
assert(stopTime != NULL);
assert(ccd != NULL);
mID = GetHipadabaNode(self->objectNode,"masterID");
master = GetHipadabaNode(self->objectNode,"master");
myStatus = GetHipadabaNode(self->objectNode,"status");
control = GetHipadabaNode(self->objectNode,"control");
ccd = GetHipadabaNode(self->objectNode,"ccd");
stopTime = GetHipadabaNode(self->objectNode,"stopTime");
timeNode = GetHipadabaNode(self->objectNode,"time");
assert(mID != NULL);
assert(master != NULL);
assert(myStatus != NULL);
assert(control != NULL);
assert(ccd != NULL);
assert(stopTime != NULL);
assert(timeNode != NULL);
if(isTaskGroupRunning(pServ->pTasker,slaveID->value.v.intValue)){
if(ccd->value.v.intValue == 1 && time(NULL) > stopTime->value.v.intValue + 100) {
SCWrite(pCon,"WARNING: CCD overrun, restarting counting...", eLogError);
self->pCountInt->Halt(self);
ReleaseCountLock(self->pCountInt);
for(i = 0; i < 100; i++){
SicsWait(1);
if(!isTaskGroupRunning(pServ->pTasker,slaveID->value.v.intValue)){
self->pCountInt->StartCount(self,pCon);
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon);
*status = HWBusy;
return 1;
}
mlID = mID->value.v.intValue;
if(mlID == 0) {
return 0;
}
SCWrite(pCon,"ERROR: failed to stop overrun CCD",eLogError);
*status = HWFault;
return 0;
} else {
data = FindCommandData(pServ->pSics,master->value.v.text,NULL);
assert(data != NULL);
pCount = GetCountableInterface(data);
assert(pCount != NULL);
if(isTaskIDRunning(pServ->pTasker,mlID)) {
*status = pCount->CheckCountStatus(data,pCon);
controlVal = GetControlValue((pCounter)data);
UpdateHipadabaPar(control,MakeHdbFloat(controlVal),pCon);
tVal = GetCountTime((pCounter)data,pCon);
UpdateHipadabaPar(timeNode,MakeHdbFloat(tVal),pCon);
SecCounterSetError(self,"None");
switch(*status){
case HWFault:
UpdateHipadabaPar(myStatus,MakeHdbText("error"),pCon);
UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon);
SecCounterSetError(self,"Master counter errror");
*status = HWBusy;
break;
case HWPause:
UpdateHipadabaPar(myStatus,MakeHdbText("paused"),pCon);
*status = HWPause;
break;
case HWNoBeam:
UpdateHipadabaPar(myStatus,MakeHdbText("nobeam"),pCon);
*status = HWNoBeam;
break;
default:
*status = HWBusy;
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;
}
} else {
/*
we recently stopped. Mark it so and stop slaves.
*/
mID->value.v.intValue = 0;
*status = HWBusy;
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon);
tVal = GetCountTime((pCounter)data,pCon);
UpdateHipadabaPar(timeNode,MakeHdbFloat(tVal),pCon);
if(ccd->value.v.intValue != 1) {
doCountCommand(self->objectNode,pCon,1011);
}
}
return 1;
}
/*-------------------------------------------------------------------------------------*/
static int areSlavesRunning(pCounter self, SConnection *pCon, int *status)
{
pHdb slaveID, myStatus, stopTime, ccd;
int i;
slaveID = GetHipadabaNode(self->objectNode,"slaveID");
myStatus = GetHipadabaNode(self->objectNode,"status");
stopTime = GetHipadabaNode(self->objectNode,"stopTime");
ccd = GetHipadabaNode(self->objectNode,"ccd");
assert(slaveID != NULL);
assert(myStatus != NULL);
assert(stopTime != NULL);
assert(ccd != NULL);
if(isTaskGroupRunning(pServ->pTasker,slaveID->value.v.intValue)){
if(ccd->value.v.intValue == 1 && time(NULL) > stopTime->value.v.intValue + 100) {
SCWrite(pCon,"WARNING: CCD overrun, restarting counting...", eLogError);
self->pCountInt->Halt(self);
ReleaseCountLock(self->pCountInt);
for(i = 0; i < 100; i++){
SicsWait(1);
if(!isTaskGroupRunning(pServ->pTasker,slaveID->value.v.intValue)){
self->pCountInt->StartCount(self,pCon);
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon);
*status = HWBusy;
return 1;
}
}
SCWrite(pCon,"ERROR: failed to stop overrun CCD",eLogError);
*status = HWFault;
} else {
*status = HWBusy;
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
return 1;
}
} else {
}
} else {
*status = HWIdle;
UpdateHipadabaPar(myStatus,MakeHdbText("idle"),pCon);
return 0;
}
return 1;
}
UpdateHipadabaPar(myStatus,MakeHdbText("idle"),pCon);
return 0;
}
return 1;
}
/*------------------------------------------------------------------------------------*/
static void multiEndCounting(pCounter self, SConnection *pCon)
{
InvokeCallBack(self->pCall, COUNTEND, NULL);
ReleaseCountLock(self->pCountInt);
MultiSecTransfer(self,pCon);
}
/*-------------------------------------------------------------------------------------*/
@ -378,32 +434,6 @@ static int MultiSecStatus(void *pData, SConnection * pCon)
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
-----------------------------------------------------------------------------*/

View File

@ -67,7 +67,7 @@ struct timeval lastclose = { -1, 0 };
/*-----------------------------------------------------------------------
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);
@ -287,8 +287,9 @@ mkChannel *NETConnectWithFlags(char *name, int port, int flags)
iRet = connect(pRes->sockid, (struct sockaddr *) &(pRes->adresse),
sizeof(struct sockaddr_in));
if (iRet < 0) {
if (iRet < 0 && errno ) {
if (errno != EINPROGRESS) {
close(pRes->sockid);
free(pRes);
return NULL;
}
@ -607,7 +608,7 @@ int NETReadTillTerm(mkChannel * self, long timeout,
gettimeofday(&start, NULL);
if (pTerm == NULL)
pTerm = "";
pTerm = strdup("");
length = strlen(pTerm);
memset(pBuffer, 0, iBufLen);
@ -842,8 +843,9 @@ mkChannel *UDPOpen(int iPort)
i = 1;
setsockopt(pRes->sockid, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(int));
/*
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.
*/

View File

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

View File

@ -235,6 +235,7 @@ static int handleFileOperations(SConnection * pCon, pNXScript self,
SCWrite(pCon, buffer, eError);
return -1;
}
traceIO("datafile", "Opening %s", argv[2]);
SCSendOK(pCon);
return 1;
}
@ -1491,6 +1492,38 @@ static int SPutAddType(void *message, void *userData)
}
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)
{
@ -1518,7 +1551,11 @@ static int SPutDim(void *message, void *userData)
self->dim[0] = self->v.arrayLength;
break;
case HIPTEXT:
self->dim[0] = strlen(self->v.v.text)+1;
if(self->v.v.text != NULL){
self->dim[0] = strlen(self->v.v.text)+1;
} else {
self->dim[0] = 1;
}
break;
default:
snprintf(self->error, sizeof(self->error),"invalid data type %d",
@ -1604,6 +1641,7 @@ static void configurePutPipe()
AppendMPFilter(putPipe,SGetData, NULL,NULL);
AppendMPFilter(putPipe,GetDefString, NULL,NULL);
AppendMPFilter(putPipe,SPutAddType, NULL,NULL);
AppendMPFilter(putPipe,SPutPadding, NULL,NULL);
AppendMPFilter(putPipe,SPutDim, NULL,NULL);
AppendMPFilter(putPipe,SPutWrite, NULL,NULL);
}
@ -2123,3 +2161,20 @@ int MakeNXScript(SConnection * pCon, SicsInterp * pSics, void *pData,
}
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);
void changeExtension(char *filename, char *newExtension);
int isNXScriptWriting(void);
/*============== a personal data structure ============================*/
typedef struct {
pObjectDescriptor pDes;

1
ofac.c
View File

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

View File

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

View File

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

View File

@ -25,6 +25,8 @@ static char undef[] = "Undefined";
#define IDXFMT " %8.4f"
#define ANGFMT " %8.2f"
#define ABS(x) (x < 0 ? -(x) : (x))
int CountTblCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar); /* from hdbtable.c */
@ -369,6 +371,32 @@ static int ShowCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
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,
pHdb par[], int nPar)
{
@ -394,6 +422,28 @@ static int NamesCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
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,
pHdb par[], int nPar)
{
@ -557,6 +607,11 @@ pSICSOBJ CreateReflectionList(SConnection * pCon, SicsInterp * pSics,
cmd = AddSICSHdbPar(pNew->objectNode, "count", usUser,
MakeSICSFunc(CountTblCmd));
cmd = AddSICSHdbPar(pNew->objectNode, "relabel", usUser,
MakeSICSFunc(RelabelCmd));
AddCommand(pSics, name, InterInvokeSICSOBJ, KillSICSOBJ, pNew);
return pNew;
}
@ -687,10 +742,10 @@ int GetRefIndexID(pSICSOBJ refl, char *id, double hkl[])
snprintf(path, 132, "data/%s", id);
node = GetHipadabaNode(refl->objectNode, path);
if (node != NULL) {
child = node->child;
for(i = 0; i < 3; i++, child = child->next){
hkl[i] = child->value.v.doubleValue;
}
child = node->child;
for(i = 0; i < 3; i++, child = child->next){
hkl[i] = child->value.v.doubleValue;
}
return 1;
} else {
return 0;

View File

@ -57,4 +57,6 @@ int GetRefFlag(pSICSOBJ refl, int idx);
char *GetRefName(pSICSOBJ refl, int idx);
const char *FindHKL(pSICSOBJ self, double h, double k, double l);
#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
*
* 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 <string.h>
@ -15,6 +20,7 @@ typedef struct __RWBuffer {
int length;
int startPtr;
int endPtr;
int maxSize;
} RWBuffer;
/*----------------------------------------------------------------------*/
prwBuffer MakeRWPuffer(int size)
@ -32,9 +38,18 @@ prwBuffer MakeRWPuffer(int size)
self->length = size;
self->startPtr = 0;
self->endPtr = 0;
self->maxSize = size;
return self;
}
/*------------------------------------------------------------------------*/
prwBuffer MakeBigRWPuffer(int size, int maxSize)
{
prwBuffer result = MakeRWPuffer(size);
if(result != NULL){
result->maxSize = maxSize;
}
return result;
}
/*------------------------------------------------------------------------*/
void KillRWBuffer(prwBuffer self)
{
@ -46,16 +61,51 @@ void KillRWBuffer(prwBuffer 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 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) {
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) {
memmove(self->data, self->data + self->startPtr, length);
@ -81,5 +131,6 @@ void RemoveRWBufferData(prwBuffer self, int count)
if (self->startPtr >= self->endPtr) {
self->startPtr = 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
*/
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.
* \param self The rwPuffer to delete.
@ -29,6 +36,14 @@ void KillRWBuffer(prwBuffer self);
* \return 1 on success, 0 on failure
*/
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
* \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;
}
}
/*---------------------------------------------------------------------*/
int isScanRunning(pScanData self)
{
return self->iActive;
}
/*---------------------------------------------------------------------*/
int GetScanVarStep(pScanData self, int iWhich, float *fStep)
{
@ -1720,6 +1724,12 @@ int ScanWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, pBueffel, eValue);
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 */
else if (strcmp(argv[1], "getvardata") == 0) {
/* 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 GetScanNP(pScanData self);
float GetScanPreset(pScanData self);
int isScanRunning(pScanData self);
int ScanIntegrate(pScanData self, float *fSum, float *fVariance);

View File

@ -143,11 +143,17 @@ int SetSICSInterrupt(SConnection * pCon, SicsInterp * pSics, void *pData,
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 argc, char *argv[])
{
int iInt;
int iInt = 0;
char pBueffel[132];
assert(pCon);
@ -166,6 +172,13 @@ int SetSICSStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
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 ? */
if (argc < 2) {
SCWrite(pCon, "ERROR: missing parameter for SetStatus", eError);
@ -174,7 +187,7 @@ int SetSICSStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
/* actually do a job */
strtolower(argv[1]);
iInt = SetStatusFromText(argv[1]);
/* iInt = SetStatusFromText(argv[1]); */
if (iInt) {
SCSendOK(pCon);
return 1;
@ -193,7 +206,7 @@ static int isNum(char *pText)
for (i = 0; i < strlen(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;
break;
}

View File

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

View File

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

View File

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

View File

@ -954,7 +954,7 @@ static int copyToNode(pSICSData self, int argc, char *argv[],
}
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;
case HIPFLOATAR:
case HIPFLOATVARAR:

View File

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

View File

@ -315,7 +315,7 @@ static pHdb CreateMotorAdapter(char *name, pMotor pMot)
DeleteHipadabaNode(result, NULL);
return NULL;
}
result->protected = 1;
result->iprotected = 1;
return result;
}
@ -499,7 +499,7 @@ static pHdb MakeSicsVarNode(pSicsVariable pVar, char *name)
snprintf(command, 1023, "%s ", pVar->name);
SetHdbProperty(node, "sicscommand", command);
node->protected = 1;
node->iprotected = 1;
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.arrayLength = strlen(argv[3]);
SetHdbProperty(node, "sicscommand", argv[3]);
SetHdbProperty(node, "scriptcommand", "yes");
kalle = MakeHipadabaCallback(CommandSetCallback, NULL, NULL);
if (kalle == NULL) {

View File

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

View File

@ -459,7 +459,7 @@ static int ListObj(pSICSOBJ self, SConnection * pCon, int argc,
/*---------------------------------------------------------------------------*/
int InvokeSICSOBJ(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
int argc, char *argv[])
{
pSICSOBJ self = NULL;
int status;
@ -476,50 +476,50 @@ int InvokeSICSOBJ(SConnection * pCon, SicsInterp * pSics, void *pData,
if (parNode != NULL && isNodePrintable(parNode)) {
status = GetHdbProperty(parNode,"geterror",buffer,sizeof(buffer));
if (status == 1 && strstr(buffer,"none") == NULL){
SCPrintf(pCon,eValue,"ERROR: %s on last read of %s", buffer, argv[0]);
SCPrintf(pCon,eValue,"%s = -99999", argv[0]);
return 0;
}
status = GetHipadabaPar(parNode, &data, pCon);
if (status != 1) {
return 0;
}
parData = formatValue(data, parNode);
if (parData == NULL) {
SCWrite(pCon, "ERROR: failed to format data", eError);
return 0;
}
SCPrintf(pCon, eValue, "%s = %s", argv[0], GetCharArray(parData));
DeleteDynString(parData);
return 1;
} else {
SCWrite(pCon, "ERROR: nothing to print", eError);
SCPrintf(pCon,eValue,"ERROR: %s on last read of %s", buffer, argv[0]);
SCPrintf(pCon,eValue,"%s = -99999", argv[0]);
return 0;
}
status = GetHipadabaPar(parNode, &data, pCon);
if (status != 1) {
return 0;
}
} else {
parNode = GetHipadabaNode(self->objectNode, argv[1]);
if(parNode == NULL){
strtolower(argv[1]);
parNode = GetHipadabaNode(self->objectNode,argv[1]);
parData = formatValue(data, parNode);
if (parData == NULL) {
SCWrite(pCon, "ERROR: failed to format data", eError);
return 0;
}
}
if (parNode != NULL && parNode->value.dataType == HIPFUNC) {
status = invokeOBJFunction(self, parNode, pCon, argc - 2, &argv[2]);
SCPrintf(pCon, eValue, "%s = %s", argv[0], GetCharArray(parData));
DeleteDynString(parData);
return 1;
} else {
snprintf(buffer, sizeof buffer, "%s ", argv[0]);
status = ProcessSICSHdbPar(self->objectNode, pCon, buffer,
argc - 1, &argv[1]);
SCWrite(pCon, "ERROR: nothing to print", eError);
return 0;
}
} else {
parNode = GetHipadabaNode(self->objectNode, argv[1]);
if(parNode == NULL){
strtolower(argv[1]);
parNode = GetHipadabaNode(self->objectNode,argv[1]);
}
}
if (parNode != NULL && parNode->value.dataType == HIPFUNC) {
status = invokeOBJFunction(self, parNode, pCon, argc - 2, &argv[2]);
} else {
snprintf(buffer, sizeof buffer, "%s ", argv[0]);
status = ProcessSICSHdbPar(self->objectNode, pCon, buffer,
argc - 1, &argv[1]);
}
if (status == -1) {
if (strcmp(argv[1], "makescriptfunc") == 0) {
return MakeScriptFunc(self, pCon, argc, argv);
} else if (strcmp(argv[1], "list") == 0) {
return ListObj(self, pCon, argc, argv);
}
if (status == -1) {
if (strcmp(argv[1], "makescriptfunc") == 0) {
return MakeScriptFunc(self, pCon, argc, argv);
} else if (strcmp(argv[1], "list") == 0) {
return ListObj(self, pCon, argc, argv);
}
/* error message written by the caller */
}
}
return status;
return status;
}
/*---------------------------------------------------------------------------*/

View File

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

View File

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

185
status.c
View File

@ -13,6 +13,10 @@
Reworked restore to keep parameters from uninitialized devices
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:
Labor fuer Neutronenstreuung
@ -52,6 +56,10 @@
#include "status.h"
#include "interrupt.h"
#include "sicshipadaba.h"
#include "messagepipe.h"
#include "scan.h"
#include "exeman.h"
#include "nxscript.h"
#undef VALUECHANGE
#define VALUECHANGE 2
@ -97,6 +105,8 @@ static char *iText[] = {
static pICallBack pCall = NULL;
static int fixed = 0;
static Status eCode = eEager;
static int userWait = 0;
static double lastStatus = .0;
/*-------------------------------------------------------------------------*/
void KillStatus(void *pData)
{
@ -108,24 +118,35 @@ void KillStatus(void *pData)
/*--------------------------------------------------------------------------*/
void SetStatus(Status eNew)
{
if (!fixed) {
/* if (!fixed) {
if (eCode == eNew) {
return;
}
eCode = eNew;
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)
{
if (eCode == eNew) {
return;
}
eCode = eNew;
InvokeCallBack(pCall, VALUECHANGE, NULL);
fixed = 1;
// if (eCode == eNew) {
// return;
// }
// eCode = eNew;
// InvokeCallBack(pCall, VALUECHANGE, NULL);
// fixed = 1;
}
/*----------------------------------------------------------------------*/
@ -279,7 +300,9 @@ int ResetStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, "Insufficient authorisation to reset server", eError);
return 0;
}
SetStatus(eEager);
// SetStatus(eEager);
eCode = eEager;
InvokeCallBack(pCall, VALUECHANGE, NULL);
SetInterrupt(eContinue);
ClearExecutor(GetExecutor());
SCsetMacro(pCon, 0);
@ -337,3 +360,149 @@ int RedirectControl(SConnection * pCon, SicsInterp * pSics, void *pData,
pOwner->sockHandle = pCon->sockHandle;
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;
/* for status display */
void SetStatus(Status eNew);
int SetStatusFromText(char *text);
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);
void GetStatusText(char *buf, int iBufLen);
@ -49,5 +37,6 @@ int UserStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]);
int ResetStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]);
void InitStatus(void);
#endif

View File

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

View File

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

View File

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

View File

@ -352,6 +352,7 @@ static int startMotors(ptasMot self, tasAngles angles,
{
double curve;
int status, silent, stopFixed;
long monoID;
silent = self->math->silent;
stopFixed = self->math->stopFixed;
@ -363,12 +364,25 @@ static int startMotors(ptasMot self, tasAngles angles,
monochromator
*/
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){
return status;
} else {
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
@ -583,7 +597,8 @@ static int checkMotors(ptasMot self, SConnection * pCon)
{
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;
} else {
return HWIdle;

34
task.c
View File

@ -24,8 +24,12 @@
#define READY 1
#define WAITING 2
#define YIELDING 3
#define IDUNDEFINED 0L
#define TASKMAGIC 777111999
/*--------------------------------------------------------------------------*/
typedef struct __TaskHead {
long magic;
long lID;
long groupID;
int iStatus;
@ -46,8 +50,12 @@ typedef struct __TaskMan {
pTaskHead pCurrent; /* Think trice before you interfere with this! */
pTaskHead pHead;
} 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
/*---------------------------------------------------------------------------*/
@ -62,6 +70,7 @@ static pTaskHead MakeTaskHead(char *name, TaskFunc pTask, SignalFunc pSignal,
}
memset(pNew, 0, sizeof(TaskHead));
pNew->magic = TASKMAGIC;
pNew->name = strdup(name);
pNew->start_time = time(NULL);
pNew->pRun = pTask;
@ -71,9 +80,10 @@ static pTaskHead MakeTaskHead(char *name, TaskFunc pTask, SignalFunc pSignal,
lIDMama++;
pNew->lID = lIDMama;
pNew->iStatus = READY;
pNew->groupID = IDUNDEFINED;
if(lIDMama < 0){
lIDMama = 0;
lIDMama = 7;
}
return pNew;
@ -99,6 +109,7 @@ static void DeleteTaskHead(pTaskHead self)
if (self->pNext != NULL) {
self->pNext->pPrevious = self->pPrevious;
}
memset(self,0,sizeof(TaskHead));
free(self);
}
@ -485,7 +496,7 @@ pTaskHead TaskIteratorStart(pTaskMan self)
/*-----------------------------------------------------------------------------*/
pTaskHead TaskIteratorNext(pTaskHead it)
{
if(it != NULL){
if(it != NULL && it->magic == TASKMAGIC){
return it->pNext;
}
return NULL;
@ -529,7 +540,7 @@ long GetTaskID(pTaskHead it)
/*------------------------------------------------------------------------------*/
long GetGroupID(pTaskHead it)
{
return it-> groupID;
return it->groupID;
}
/*------------------------------------------------------------------------------*/
const char * GetTaskName(pTaskHead it)
@ -537,6 +548,15 @@ const char * GetTaskName(pTaskHead it)
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)
{
lIDMama++;
@ -569,13 +589,15 @@ int isTaskGroupRunning(pTaskMan self, long groupID)
pTaskHead pCurrent, pNext;
if (self == NULL) return 0;
if (groupID == IDUNDEFINED) return 0;
assert(self->iID == TASKERID);
pNext = self->pHead->pNext; /* skip dummy task */
while (pNext != NULL) {
pCurrent = pNext;
pNext = pCurrent->pNext;
if (pCurrent->groupID == groupID) {
if (pCurrent->groupID != IDUNDEFINED && pCurrent->groupID == groupID) {
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.
*/
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
only be member of one task group

View File

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

View File

@ -8,6 +8,13 @@
* copyright: see file COPYRIGHT
*
* 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 "tasmono.h"

View File

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

View File

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

View File

@ -15,6 +15,7 @@
Mark Koennecke, September 2011
----------------------------------------------------------------------*/
#include <assert.h>
#include <math.h>
#include "sics.h"
#include "lld.h"
#include "SCinter.h"
@ -971,7 +972,7 @@ static void listDiagnostik(ptasUB self, SConnection * pCon)
static int addAuxReflection(ptasUB self, SConnection * pCon,
SicsInterp * pSics, int argc, char *argv[])
{
int status;
int status, ss;
tasReflection r1, r2;
float value = -999.99;
char pBueffel[256];
@ -1027,7 +1028,8 @@ static int addAuxReflection(ptasUB self, SConnection * pCon,
r2.qe.kf = self->current.kf;
r2.qe.ki = self->current.ki;
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.sgl = .0;
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);
chi2 = mat_mul(B, h2);
if (chi1 != NULL && chi2 != NULL) {
angle = angleBetween(chi1, chi2);
angle = tasAngleBetween(chi1, chi2);
killVector(chi1);
killVector(chi2);
}
@ -271,8 +271,9 @@ int makeAuxReflection(MATRIX B, tasReflection r1, tasReflection * r2,
r2->qe.ki = r1.qe.ki;
r2->qe.kf = r1.qe.kf;
theta = calcTheta(r1.qe.ki, r1.qe.kf, r1.angles.sample_two_theta);
om = r1.angles.a3 - theta;
theta = calcTheta(r1.qe.ki, r1.qe.kf,
ss*r1.angles.sample_two_theta);
om = r1.angles.a3 - ss*theta;
om += tasAngleBetweenReflections(B, r1, *r2);
QC = tasReflectionToHC(r2->qe, B);
@ -289,12 +290,17 @@ int makeAuxReflection(MATRIX B, tasReflection r1, tasReflection * r2,
return TRIANGLENOTCLOSED;
}
r2->angles.sample_two_theta = ss * Acosd(cos2t);
theta = calcTheta(r1.qe.ki, r1.qe.kf, r2->angles.sample_two_theta);
r2->angles.a3 = om + theta;
theta = calcTheta(r1.qe.ki, r1.qe.kf, ss*r2->angles.sample_two_theta);
r2->angles.a3 = om + ss*theta;
r2->angles.a3 = fmod(r2->angles.a3 + ss*180.,360.) - ss*180.;
/*
r2->angles.a3 -= 180.;
if (r2->angles.a3 < -180.) {
r2->angles.a3 += 360.;
}
*/
mat_free(QC);
return 1;
@ -415,22 +421,16 @@ MATRIX calcPlaneNormalQ(MATRIX UB, tasReflection r1, tasReflection r2)
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 calcUBFromAngles(MATRIX B, double om, double sgu, double sgl)
{
MATRIX B, M, N, OM, UB;
MATRIX M, N, OM, UB;
int status;
/*
* create matrices
*/
B = mat_creat(3, 3, ZERO_MATRIX);
status = calculateBMatrix(cell, B);
if (status < 0) {
return NULL;
}
M = mat_creat(3, 3, ZERO_MATRIX);
N = mat_creat(3, 3, ZERO_MATRIX);
OM = 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(N);
mat_free(M);
mat_free(B);
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 M, N, Z, NORM;

View File

@ -186,21 +186,33 @@ MATRIX calcTasUBFromTwoReflections(lattice cell, tasReflection r1,
*/
MATRIX calcTestNormal(double sgu, double sgl);
/**
* calculate a test UB
* @param cell The lattice constant of the crystal
* calculate a test UB from angles
* @param cell The B lattice 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 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
*/
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
* @param r1 first reflection
* @param r2 second reflection
* @return a plane normal on success, NULL else
*/
MATRIX calcPlaneNormal(tasReflection r1, tasReflection r2);
/**
* calcluate the normal to the plane describe by the two reflections r1, r2

54
trace.c
View File

@ -37,6 +37,7 @@ static int hdbInit = 0;
static int filterProv = 0;
static int debug = 0;
static int lastTen = -10;
static long traceStamperID = -1;
/*----------------------------------------------------------------------------------------*/
int traceActive()
{
@ -468,12 +469,56 @@ static int TraceLog(pSICSOBJ ccmd, SConnection * con,
TraceObjects();
hdbInit = 1;
}
TaskRegisterN(pServ->pTasker,"tracestamper",
TraceLogTask, NULL, NULL, NULL, 1);
if(traceStamperID < 0){
traceStamperID = TaskRegisterN(pServ->pTasker,"tracestamper",
TraceLogTask, NULL, NULL, NULL, 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,
Hdb * cmdNode, Hdb * par[], int nPar)
@ -520,6 +565,11 @@ void MakeTrace(void)
"log", usMugger, MakeSICSFunc(TraceLog));
AddSICSHdbPar(cmd, "filename", usMugger, MakeHdbText(""));
cmd = AddSICSHdbPar(ccmd->objectNode,
"append", usMugger, MakeSICSFunc(TraceAppend));
AddSICSHdbPar(cmd, "filename", usMugger, MakeHdbText(""));
cmd = AddSICSHdbPar(ccmd->objectNode,
"filter", usMugger, MakeSICSFunc(TraceFilter));
AddSICSHdbPar(cmd, "selection", usMugger, MakeHdbInt(0));

View File

@ -189,6 +189,37 @@ double angleBetween(MATRIX v1, MATRIX v2)
}
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)

View File

@ -91,12 +91,20 @@ MATRIX vectorCrossProduct(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 v2 second vector
* @return angle in degree
*/
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

5
velo.c
View File

@ -588,10 +588,7 @@ int VSGetLossCurrent(pVelSel self, SConnection * pCon, float *fLoss)
assert(self);
assert(pCon);
eOld = GetStatus();
SetStatus(eRunning);
iRet = self->pDriv->GetLossCurrent(self->pDriv, fLoss);
SetStatus(eOld);
if (!iRet) {
self->pDriv->GetError(self->pDriv, &iCode, pError, 131);
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);
return 0;
}
SetStatus(eDriving);
iRet = VSSetTiltRot(self, pCon, fRot, fTilt);
SetStatus(eEager);
if (iRet) {
SCSendOK(pCon);
return 1;