From 47e38eba5a36f065d54175574702a19156823312 Mon Sep 17 00:00:00 2001 From: koennecke Date: Thu, 13 Jul 2006 07:24:44 +0000 Subject: [PATCH] - Added log instrumentation to devexe - Added a hill climbing option to optimise - Added hrpt files SKIPPED: psi/libpsi.a psi/sinqhmdriv.c psi/tabledrive.c --- devexec.c | 240 ++++++++++++++++++++++++++++++++- devexec.h | 9 +- devexec.tex | 3 +- devexec.w | 3 +- doc/manager/nxscript.htm | 5 +- doc/user/optimise.htm | 5 +- drive.c | 2 +- nserver.c | 5 + optimise.c | 278 ++++++++++++++++++++++++++++++++++++++- scan.tex | 1 + scan.w | 1 + sicshipadaba.c | 68 ++++++++++ sicshipadaba.h | 24 ++++ stdscan.c | 2 +- stdscan.h | 1 + 15 files changed, 633 insertions(+), 14 deletions(-) diff --git a/devexec.c b/devexec.c index 079ec589..d539c6e0 100644 --- a/devexec.c +++ b/devexec.c @@ -42,10 +42,12 @@ NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -----------------------------------------------------------------------------*/ +#include #include #include #include #include +#include #include "fortify.h" #include "sics.h" #include "nserver.h" @@ -56,11 +58,51 @@ #include "status.h" #include "lld.h" #include "commandlog.h" +#include "ifile.h" /* #define DEBUG 1 */ +/*======================== Logging stuff ==================================*/ +static FILE *devLog = NULL; +/*-------------------------------------------------------------------------*/ +int openDevexecLog(){ + char *fileName = NULL; + char fileBuffer[1024]; + + if(devLog == NULL){ + fileName = IFindOption(pSICSOptions,"devexeclog"); + if(fileName != NULL){ + strcpy(fileBuffer,fileName); + } else { + fileBuffer[0] = '\0'; + fileName = getenv("HOME"); + if(fileName != NULL){ + strcpy(fileBuffer,fileName); + } + strcat(fileBuffer,"/log/devexec.log"); + } + devLog = fopen(fileBuffer,"a+"); + } + if(devLog == NULL){ + return 0; + } else { + return 1; + } +} +/*-------------------------------------------------------------------------*/ +void DevexecLog(char *operation, char *device) { + struct timeval tv; + struct timezone tm; + if(devLog != NULL){ + gettimeofday(&tv,&tm); + fprintf(devLog, "DEVEXEC:%s:%s:%ld:%ld\n",operation,device, + tv.tv_sec, tv.tv_usec); + fflush(devLog); + } +} +/*======================== internal data structures =======================*/ typedef struct _DevEntry { void *pData; pObjectDescriptor pDescriptor; @@ -122,6 +164,7 @@ typedef struct { int iLock; pICallBack pCall; time_t lastRun; + int paused; } ExeList; static pExeList pExecutor = NULL; @@ -178,6 +221,10 @@ typedef struct { free(self); pServ->pExecutor = NULL; + if(devLog != NULL){ + fclose(devLog); + devLog = NULL; + } } /*--------------------------------------------------------------------------*/ void ExeInterest(pExeList self, pDevEntry pDev, char *text) { @@ -295,6 +342,7 @@ typedef struct { self->iEnd = 0; pCon->conStatus = HWBusy; } + DevexecLog("START",pNew->name); return 1; } else @@ -397,7 +445,7 @@ typedef struct { pCon,pCter->pDriv->fPreset); } /*--------------------------------------------------------------------------*/ - int CheckExeList(pExeList self) + int CheckExeListOld(pExeList self) { int iRet; pDevEntry pDev = NULL; @@ -568,6 +616,196 @@ typedef struct { return 0; } } +/*-------------------------------------------------------------------------*/ +static int checkInterrupt(pCheckContext pCheck, int targetStatus){ + if(SCGetInterrupt(pCheck->self->pOwner) != eContinue) { + pCheck->self->iStatus = DEVINT; + SCPopContext(pCheck->self->pOwner); + SetStatus(eEager); + return -1; + } else { + return targetStatus; + } +} +/*--------------------------------------------------------------------------*/ +static int initializeCheck(pCheckContext pCheck, pDevEntry pDev){ + int eCode; + + SCPushContext(pCheck->self->pOwner, + pDev->comCon.transID, pDev->comCon.deviceID); + pCheck->pDev = pDev; + pCheck->pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID); + pCheck->pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID); + if(pCheck->pDrivInt != NULL){ + eCode = pCheck->pDrivInt->CheckStatus(pDev->pData,pCheck->self->pOwner); + } else if(pCheck->pCountInt != NULL) { + eCode = pCheck->pCountInt->CheckCountStatus(pDev->pData,pCheck->self->pOwner); + } + return eCode; +} +/*--------------------------------------------------------------------------*/ +static int finishDevice(pCheckContext pCheck){ + int status; + + if(pCheck->pCountInt != NULL) { + pCheck->pCountInt->TransferData(pCheck->pDev->pData,pCheck->self->pOwner); + } else if(pCheck->pDrivInt != NULL) { + pCheck->pDrivInt->iErrorCount = 0; + } + ExeInterest(pCheck->self, pCheck->pDev, "finished"); + DevexecLog("STOP",pCheck->pDev->name); + DeleteDevEntry(pCheck->pDev); + LLDnodeDelete(pCheck->self->iList); + status = LLDnodePtr2Prev(pCheck->self->iList); + SCWrite(pCheck->self->pOwner, "", eFinish); + pCheck->self->iStatus = DEVDONE; + return checkInterrupt(pCheck,status); +} +/*-------------------------------------------------------------------------*/ +static int errorDevice(pCheckContext pCheck){ + int status; + + ExeInterest(pCheck->self, pCheck->pDev, "finished with problem"); + DevexecLog("STOP",pCheck->pDev->name); + DeleteDevEntry(pCheck->pDev); + LLDnodeDelete(pCheck->self->iList); + status = LLDnodePtr2Prev(pCheck->self->iList); + SCWrite(pCheck->self->pOwner, "", eFinish); + pCheck->self->iStatus = DEVERROR; + if(pCheck->pDrivInt != NULL) { + pCheck->pDrivInt->iErrorCount++; + } + return checkInterrupt(pCheck,status); +} +/*-------------------------------------------------------------------------*/ +static int testFinish(pExeList self){ + if((self->pOwner == NULL) || (LLDcheck(self->iList) == LIST_EMPTY)) { + self->pOwner = NULL; + self->iRun = 0; + self->iEnd = 1; + self->iStop = 0; + self->lTask = -1; + return 1; + } else { + return 0; + } +} +/*--------------------------------------------------------------------------*/ + int CheckExeList(pExeList self) + { + int iRet, status; + checkContext check; + pDevEntry pDev = NULL; + pICountable pCountInt = NULL; + pIDrivable pDrivInt = NULL; + int eCode; + int isCounting=0, isDriving=0; + char pBueffel[512]; + SConnection *pCon; + pCon = self->pOwner; + + assert(self); + + /* Sometimes this gets called, though nothing is running. There are + cases where this is feasible for maintainance, but in some cases it + is pure rubbish, because nothing runs. This will be checked here. + */ + if(testFinish(self) == 1){ + return 1; + } + + /* + check the status of all registered devices. Remove when finished + */ + check.self = self; + status = LLDnodePtr2First(self->iList); + while(status != 0) + { + LLDnodeDataTo(self->iList,&pDev); + if(pDev) + { + eCode = initializeCheck(&check,pDev); + if(eCode != HWNoBeam && eCode != HWPause && self->paused == 1){ + DevexecLog("CONTINUE","ALL"); + self->paused = 0; + } + switch(eCode) + { + case HWIdle: + case OKOK: + status = finishDevice(&check); + if(status < 0){ + return status; + } + break; + case HWFault: /* real HW error: burning, no net etc.. */ + status = errorDevice(&check); + if(status < 0){ + return status; + } + break; + case HWNoBeam: + SetStatus(eOutOfBeam); + if(self->paused == 0){ + self->paused = 1; + DevexecLog("NOBEAM","ALL"); + } + status = checkInterrupt(&check,1); + if(status < 0){ + return status; + } + break; + case HWPause: + SetStatus(ePaused); + if(self->paused == 0){ + self->paused = 1; + DevexecLog("PAUSE","ALL"); + } + status = checkInterrupt(&check,1); + if(status < 0){ + /* + * continue in order to wait for devices to come to a stop + */ + ContinueExecution(self); + return status; + } + break; + case HWBusy: + if(check.pDrivInt != NULL) + { + isDriving = 1; + } + else if(check.pCountInt != NULL) + { + isCounting = 1; + } + self->iStatus = DEVBUSY; + break; + case HWPosFault: /* cannot get somewhere... */ + status = errorDevice(&check); + if(status < 0){ + return status; + } + break; + } + SCPopContext(self->pOwner); + } + status = LLDnodePtr2Next(self->iList); + } + + if (isCounting) { + if (isDriving) { + SetStatus(eCountDrive); + } else { + SetStatus(eCounting); + } + } else if (isDriving) { + SetStatus(eDriving); + } + + iRet = LLDnodePtr2First(self->iList); + return testFinish(self); + } /*---------------------------------------------------------------------------*/ int Wait4Success(pExeList self) { diff --git a/devexec.h b/devexec.h index 9c43e207..9c0bd015 100644 --- a/devexec.h +++ b/devexec.h @@ -152,11 +152,7 @@ /* continues execution */ - int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData, - int argc, char *argv[]); - /* - * various commands - */ + /*--------------------------- Locking ---------------------------------*/ #line 183 "devexec.w" @@ -171,5 +167,6 @@ pExeList GetExecutor(void); void SetExecutor(pExeList pExe); - +/*----------------------- Logging -----------------------------------------*/ + void DevexecLog(char *op, char *device); #endif diff --git a/devexec.tex b/devexec.tex index e6515b8f..20dd2e56 100644 --- a/devexec.tex +++ b/devexec.tex @@ -353,7 +353,8 @@ to the global SICS device executor. \mbox{}\verb@ @\\ \mbox{}\verb@ pExeList GetExecutor(void);@\\ \mbox{}\verb@ void SetExecutor(pExeList pExe);@\\ -\mbox{}\verb@ @\\ +\mbox{}\verb@/*----------------------- Logging -----------------------------------------*/@\\ +\mbox{}\verb@ void DevexecLog(char *op, char *device); @\\ \mbox{}\verb@#endif @\\ \mbox{}\verb@@$\diamond$ \end{list} diff --git a/devexec.w b/devexec.w index 45ff782c..f97023f3 100644 --- a/devexec.w +++ b/devexec.w @@ -299,7 +299,8 @@ to the global SICS device executor. pExeList GetExecutor(void); void SetExecutor(pExeList pExe); - +/*----------------------- Logging -----------------------------------------*/ + void DevexecLog(char *op, char *device); #endif @} diff --git a/doc/manager/nxscript.htm b/doc/manager/nxscript.htm index 04db765e..39e359d8 100644 --- a/doc/manager/nxscript.htm +++ b/doc/manager/nxscript.htm @@ -125,7 +125,10 @@ automatically appended to the definition string for the alias.
Writes the Tcl array arrayName to file using the aliasName. The definiton string belonging to aliasName does not need to contain a -dim argument as this is set by this routine. The parameter length is -the length of the array. Only rank 1 arrays are supported. +the length of the array. Only rank 1 arrays are supported. The array is +considered a float array. +
nxscript putintarray aliasName arrayName length +
The same as above, but the data is considered integer.
nxsript putglobal attName bla bla bla
This writes an global attribute attName. Everything after attName is concatenated to a string which then respresents the value of the diff --git a/doc/user/optimise.htm b/doc/user/optimise.htm index 8d80b76c..c8a2e881 100644 --- a/doc/user/optimise.htm +++ b/doc/user/optimise.htm @@ -43,7 +43,10 @@ and number of steps parameters should cover the whole peak. However, the Optimiser will extend the scan is the specified range is not sufficient.
opti run
Starts the optimiser. It will then optimise the peak. This may take some -time. +time as it uses a time consuming scan based algorithm. +
opti climb +
Starts the optimiser in hill climbing mode. Hill climbing is faster but may + not be as accurate as a scan based optimization. The behaviour of the optimiser can be configured by modifying some parameters. The synatx is easy: opti parameter prints the value of the diff --git a/drive.c b/drive.c index 1ad01395..8e85a51c 100644 --- a/drive.c +++ b/drive.c @@ -387,7 +387,7 @@ } else if(iRet == DEVINT) { - sprintf(pBueffel,"Driving Interrupted!"); + sprintf(pBueffel,"ERROR: Driving Interrupted!"); SCWrite(pCon,pBueffel,eError); ClearExecutor(GetExecutor()); SetStatus(eOld); diff --git a/nserver.c b/nserver.c index b3fca7bf..47556084 100644 --- a/nserver.c +++ b/nserver.c @@ -43,6 +43,8 @@ */ extern void StopExit(void); /* in SICSmain.c */ + + extern int openDevexecLog(); /* in devexec.c */ /* ========================= Less dreadful file statics =================== */ #define DEFAULTINIFILE "servo.tcl" @@ -216,6 +218,8 @@ assert(pCom); assert(pCom->pData); self->pExecutor = (pExeList)pCom->pData; + openDevexecLog(); + DevexecLog("START","SICS"); /* initialize Interrupt Port */ @@ -305,6 +309,7 @@ /* clear all pending bullshit */ ClearExecutor(self->pExecutor); + DevexecLog("STOP","SICS"); /* shut telnet down */ KillTelnet(); diff --git a/optimise.c b/optimise.c index d74cae09..7b507cf7 100644 --- a/optimise.c +++ b/optimise.c @@ -22,6 +22,7 @@ #include "scan.i" #include "fitcenter.h" #include "optimise.h" +#include "stdscan.h" #ifdef CYGNUS #define MAXFLOAT 9999999.99 @@ -83,7 +84,6 @@ { return 1; } - /*------------------------------------------------------------------------*/ pOptimise CreateOptimiser(pCounter pCount) @@ -466,6 +466,197 @@ return iReturn; } +/*------------------------------------------------------------------------ + * We use the scan object here for counting. The reason is that this + * handles well in the common case of a single counter but also has + * provisions for other counting methods through the scan modules + * scripting mechanism + * ------------------------------------------------------------------------*/ +static long ClimbCount(pOptimise self, SConnection *pCon) +{ + int status; + long data[1]; + int (*CollectFunc)(pScanData self, int iPoint) = NULL; + + SilentPrepare(self->pScanner); + + status = self->pScanner->ScanCount(self->pScanner,0); + if(status != 1) + { + return status; + } + if(self->pScanner->CollectScanData == CollectScanData) + { + CollectFunc = self->pScanner->CollectScanData; + self->pScanner->CollectScanData = CollectSilent; + } + status = self->pScanner->CollectScanData(self->pScanner,0); + if(CollectFunc != NULL) + { + self->pScanner->CollectScanData = CollectFunc; + } + if(status != 1) + { + return status; + } + GetScanCounts(self->pScanner,data,1); + return data[0]; +} +/*------------------------------------------------------------------------*/ +static int ClimbDrive(SConnection *pCon,char *name, float value) +{ + int status; + + status = Start2Run(pCon,pServ->pSics,name,value); + if(status != 1) + { + return DRIVEERROR; + } + status = Wait4Success(GetExecutor()); + if(status != DEVDONE) + { + return DRIVEERROR; + } + return 1; +} +/*-------------------------------------------------------------------------*/ + static int ClimbVariable(pOptimise self, SConnection *pCon, int i) + { + pOVarEntry pOvar; + void *pData; + int status, direction = 1; + long oneCount, twoCount, lastCount, currentCount; + float varValue, startValue; + char buffer[256]; + int (*CollectFunc)(pScanData self, int iPoint) = NULL; + + assert(self); + assert( (i >= 0) && (i < self->iVar)); + assert(pCon); + + /* get variable data */ + DynarGet(self->pVariables,i,&pData); + pOvar = (pOVarEntry)pData; + startValue = pOvar->fCenter; + + /* + * prepare scan object + */ + self->pScanner->pCon = pCon; + self->pScanner->pSics = pServ->pSics; + self->pScanner->iNP = 1; + self->pScanner->iMode = self->eCount; + self->pScanner->fPreset = self->fPreset; + + /* + * test for upwards direction + */ + varValue = pOvar->fCenter + pOvar->fStep; + status = ClimbDrive(pCon,pOvar->pName,varValue); + if(!status) + { + return DRIVEERROR; + } + oneCount = ClimbCount(self,pCon); + if(oneCount < 0) + { + return SCANERROR; + } + if(SCGetInterrupt(pCon) != eContinue) + { + return SCANABORT; + } + varValue = pOvar->fCenter - pOvar->fStep; + status = ClimbDrive(pCon,pOvar->pName,varValue); + if(!status) + { + return DRIVEERROR; + } + twoCount = ClimbCount(self,pCon); + if(SCGetInterrupt(pCon) != eContinue) + { + return SCANABORT; + } + if(twoCount < 0) + { + return SCANERROR; + } + if(oneCount > twoCount) + { + direction = 1; + lastCount = oneCount; + } + else + { + direction = -1; + lastCount = twoCount; + } + + /* + * drive to the last best position + */ + varValue = pOvar->fCenter + direction*pOvar->fStep; + status = ClimbDrive(pCon,pOvar->pName,varValue); + if(!status) + { + return DRIVEERROR; + } + currentCount = lastCount; + + /* + * climb upwards as long as possible + */ + while(1) + { + pOvar->fCenter = varValue; + varValue = pOvar->fCenter + direction * pOvar->fStep; + status = ClimbDrive(pCon,pOvar->pName,varValue); + if(!status) + { + return DRIVEERROR; + } + if(SCGetInterrupt(pCon) != eContinue) + { + return SCANABORT; + } + currentCount = ClimbCount(self,pCon); + if(currentCount < 0) + { + return SCANERROR; + } + if(SCGetInterrupt(pCon) != eContinue) + { + return SCANABORT; + } + snprintf(buffer,255,"Climbing %s, value = %f, count = %ld", + pOvar->pName, varValue, currentCount); + SCWrite(pCon,buffer,eWarning); + + if(currentCount <= lastCount) + { + /* + * we are finished. Drive to previous position and + * break + */ + status = ClimbDrive(pCon,pOvar->pName,pOvar->fCenter); + if(!status) + { + return DRIVEERROR; + } + break; + } + else + { + /* + * go on, we are not over the top yet + */ + lastCount = currentCount; + } + } + pOvar->fShift = ABS(startValue - pOvar->fCenter); + + return 1; + } /*---------------------------------------------------------------------------*/ static int CheckSuccess(pOptimise self) { @@ -530,6 +721,45 @@ } return MAXCYCLE; } +/*---------------------------------------------------------------------------*/ + int OptimiserClimb(pOptimise self, SConnection *pCon) + { + int i, iRet, iCycle, iRedoVar = 0; + char pBueffel[256]; + + assert(self); + + if(self->iVar < 1) + { + SCWrite(pCon,"ERROR: Nothing to optimise",eError); + return 0; + } + + iRet = OptimiserInit(self,pCon); + if(!iRet) + { + return iRet; + } + for(iCycle = 0; iCycle < self->iMaxCycles; iCycle++) + { + sprintf(pBueffel,"Optimiser cycle %d of %d started",iCycle, self->iMaxCycles); + SCWrite(pCon,pBueffel,eStatus); + for(i = iRedoVar; i < self->iVar; i++) + { + iRet = ClimbVariable(self,pCon,i); + if(iRet <= 0) + { + return iRet; + } + } + iRet = CheckSuccess(self); + if(iRet) + { + return 1; + } + } + return MAXCYCLE; + } /*--------------------------------------------------------------------------*/ int MakeOptimiser(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) @@ -717,6 +947,52 @@ break; } } +/*-------- climb */ + else if(strcmp(argv[1],"climb") == 0) + { + /* check rights */ + if(!SCMatchRights(pCon,usUser)) + { + SCWrite(pCon,"ERROR: You are not aurhorised to do this!",eError); + return 0; + } + iRet = OptimiserClimb(self,pCon); + switch(iRet) + { + case PEAKLOST: + SCWrite(pCon,"ERROR: lost the peak, sorry!",eError); + return 0; + break; + case MAXCYCLE: + sprintf(pBueffel,"ERROR: could not optimise peak in %d cycles", + self->iMaxCycles); + SCWrite(pCon,pBueffel,eError); + return 0; + break; + case SCANERROR: + SCWrite(pCon,"ERROR: failed to scan the peak",eError); + return 0; + break; + case SCANABORT: + SCWrite(pCon,"ERROR: Scan was aborted, Optimiser follows",eError); + return 0; + break; + case DRIVEERROR: + SCWrite(pCon,"ERROR: Failure to drive variable to new position",eError); + return 0; + break; + case 1: + SCWrite(pCon,"At long last, I finished optimising the peak",eValue); + return 1; + break; + default: + SCWrite(pCon,"ERROR: Unidentified error krept into Optimiser",eError); + return 0; + break; + } + SCWrite(pCon,"Optimiser climbed successfully",eValue); + return 1; + } /* ------ count mode */ if(strcmp(argv[1],"countmode") == 0) { diff --git a/scan.tex b/scan.tex index 1ac0e692..ce5eecc1 100644 --- a/scan.tex +++ b/scan.tex @@ -531,6 +531,7 @@ $\langle$stdscan {\footnotesize ?}$\rangle\equiv$ \mbox{}\verb@ */@\\ \mbox{}\verb@ int CollectScanData(pScanData self, int iPoint);@\\ \mbox{}\verb@ int CollectScanDataJochen(pScanData self, int iPoint);@\\ +\mbox{}\verb@ int CollectSilent(pScanData self, int iPoint);@\\ \mbox{}\verb@/*===================================================================*/@\\ \mbox{}\verb@ /**@\\ \mbox{}\verb@ * Script invocation for writing the scan header.@\\ diff --git a/scan.w b/scan.w index cd1cfa84..9f1f9122 100644 --- a/scan.w +++ b/scan.w @@ -477,6 +477,7 @@ documentation. */ int CollectScanData(pScanData self, int iPoint); int CollectScanDataJochen(pScanData self, int iPoint); + int CollectSilent(pScanData self, int iPoint); /*===================================================================*/ /** * Script invocation for writing the scan header. diff --git a/sicshipadaba.c b/sicshipadaba.c index 909e80d6..564c037e 100644 --- a/sicshipadaba.c +++ b/sicshipadaba.c @@ -566,6 +566,74 @@ void RemoveSICSPar(pHdb node){ SICSDeleteNodeData(node); } +/*==================== access suport functions ==============================*/ +int SICSHdbGetFloat(pHdb parent, SConnection *pCon, + char *path, float *value){ + hdbValue v; + pHdb par = NULL; + int status; + char buffer[256]; + + par = GetHipadabaNode(parent,path); + if(par == NULL){ + if(pCon != NULL){ + snprintf(buffer,255,"ERROR: parameter %s not found", path); + SCWrite(pCon,buffer,eError); + } + return SICSNOPAR; + } + + status = GetHipadabaPar(par,&v,pCon); + if(status < 0){ + return status; + } + if(v.dataType == HIPFLOAT){ + *value = (float)v.v.doubleValue; + } else if(v.dataType == HIPINT){ + *value = (float)v.v.intValue; + } else { + /* + * it is an error to call this for array dada types + */ + assert(0); + } + return 1; +} +/*--------------------------------------------------------------------------*/ +int SICSHdbSetFloat(pHdb parent, SConnection *pCon, + char *path, float value){ + hdbValue v; + pHdb par = NULL; + int status; + char buffer[256]; + + par = GetHipadabaNode(parent,path); + if(par == NULL){ + if(pCon != NULL){ + snprintf(buffer,255,"ERROR: parameter %s not found", path); + SCWrite(pCon,buffer,eError); + } + return SICSNOPAR; + } + + v.dataType = par->value.dataType; + if(v.dataType == HIPFLOAT){ + v.v.doubleValue = (double)value; + } else if(v.dataType == HIPINT){ + v.v.intValue = (long)value; + } else { + /* + * it is an error to call this for array dada types + */ + assert(0); + } + + status = SetHipadabaPar(par,v,pCon); + if(status < 0){ + return status; + } + return 1; +} /*---------------------------------------------------------------------------*/ int InstallSICSNotify(pHdb node, SConnection *pCon, int id, int recurse){ diff --git a/sicshipadaba.h b/sicshipadaba.h index c14cb7ff..83f0bf5f 100644 --- a/sicshipadaba.h +++ b/sicshipadaba.h @@ -17,6 +17,7 @@ #define SICSCBPERM -608 #define SICSCBRANGE -609 #define SICSCBBADFIXED -610 +#define SICSNOPAR -611 /*======================== data structure for automatic parameter update =======*/ typedef struct { SConnection *pCon; @@ -136,6 +137,29 @@ pHdb MakeSICSScriptPar(char *name, char *setScript, char *readScript, hdbValue v * @param node The node to delete */ void RemoveSICSPar(pHdb node); +/*============== access support functions =================================*/ +/** + * SICSHdbGetFloat returns the float value of a parameter. Integers are + * automatically converted. + * @param parent The parent node where to start searching for the parameter + * @param pCon The optional connection object to use for reporting errors. + * @param path The path to the parameter. + * @param value The value of the parameter + * @return 1 on success, a negative error code else. + */ +int SICSHdbGetFloat(pHdb parent, SConnection *pCon, + char *path, float *value); +/** + * SICSHdbSetFloat sets the value of a parameter. Integers are + * automatically converted. + * @param parent The parent node where to start searching for the parameter + * @param pCon The optional connection object to use for reporting errors. + * @param path The path to the parameter. + * @param value The new value of the parameter + * @return 1 on success, a negative error code else. + */ +int SICSHdbSetFloat(pHdb parent, SConnection *pCon, + char *path, float value); /*============= common SICS Interactions ===================================*/ /** * Install a SICS automatic notification callback on the node. This is diff --git a/stdscan.c b/stdscan.c index 5194fb5e..c2deb893 100644 --- a/stdscan.c +++ b/stdscan.c @@ -847,7 +847,7 @@ int prepareDataFile(pScanData self){ return CollectScanDataIntern(self,iPoint,1); } /*------------------------------------------------------------------------*/ - static int CollectSilent(pScanData self, int iPoint) + int CollectSilent(pScanData self, int iPoint) { pVarEntry pVar = NULL; void *pDings; diff --git a/stdscan.h b/stdscan.h index d845488c..d0030c9e 100644 --- a/stdscan.h +++ b/stdscan.h @@ -68,6 +68,7 @@ */ int CollectScanData(pScanData self, int iPoint); int CollectScanDataJochen(pScanData self, int iPoint); + int CollectSilent(pScanData self, int iPoint); /*===================================================================*/ /** * Script invocation for writing the scan header.