diff --git a/confvirtualmot.c b/confvirtualmot.c index 0ac738d4..677a6021 100644 --- a/confvirtualmot.c +++ b/confvirtualmot.c @@ -47,6 +47,7 @@ typedef struct { pIDrivable pDriv; float value; int running; + long taskID; } RealMotor, *pRealMotor; /* Data passed by event generating object */ @@ -179,9 +180,9 @@ static int startMotorList(pConfigurableVirtualMotor self, iRet = LLDnodePtr2First(self->motorList); while (iRet != 0) { LLDnodeDataTo(self->motorList, &tuktuk); - status = tuktuk.pDriv->SetValue(tuktuk.data, pCon, tuktuk.value); - if (status != 1) { - return status; + tuktuk.taskID = StartDriveTask(tuktuk.data,pCon,tuktuk.name,tuktuk.value); + if (tuktuk.taskID < 0) { + return HWFault; } tuktuk.running = 1; LLDnodeDataFrom(self->motorList, &tuktuk); @@ -342,28 +343,12 @@ static int ConfCheckStatus(void *pData, SConnection * pCon) while (iRet != 0) { LLDnodeDataTo(self->motorList, &tuktuk); if (tuktuk.running == 1) { - status = tuktuk.pDriv->CheckStatus(tuktuk.data, pCon); - switch (status) { - case HWIdle: - tuktuk.running = 0; + status = isTaskIDRunning(pServ->pTasker,tuktuk.taskID); + if(status == 1){ + return HWBusy; + } else { + tuktuk.running = 0; LLDnodeDataFrom(self->motorList, &tuktuk); - break; - case HWBusy: - result = HWBusy; - break; - case HWFault: - case HWPosFault: - if(self->state != NULL){ - free(self->state); - self->state = strdup("idle"); - } - return status; - break; - default: - /* - this is a programming error and has to be fixed - */ - assert(0); } } iRet = LLDnodePtr2Next(self->motorList); diff --git a/conman.c b/conman.c index 6976c32b..ee8ff769 100644 --- a/conman.c +++ b/conman.c @@ -1846,7 +1846,7 @@ int ConfigCon(SConnection * pCon, SicsInterp * pSics, void *pData, } else if (strcmp(argv[1], "rights") == 0) { if (argc < 4) { snprintf(pBueffel,511, "Insufficient number of args to %s", argv[0]); - SCWrite(pCon, pBueffel, eInError); + SCWrite(pCon, pBueffel, eError); return 0; } i = IsValidUser(argv[2], argv[3]); diff --git a/countersec.c b/countersec.c index caff70d1..9cad865a 100644 --- a/countersec.c +++ b/countersec.c @@ -425,6 +425,31 @@ static int CountCmd(pSICSOBJ ccmd, SConnection * con, return DoCount((pCounter)ccmd, preset, con, 1); } /*--------------------------------------------------------------------------*/ +static int GetMonitorCmd(pSICSOBJ ccmd, SConnection * con, + Hdb * cmdNode, Hdb * par[], int nPar) +{ + long counts; + pCounter self = (pCounter)ccmd; + if(nPar < 1) { + SCWrite(con,"ERROR: missing monitor no in getmonitor",eError); + return 0; + } + counts = self->getMonitor(self,par[0]->value.v.intValue,con); + SCPrintf(con,eValue,"%s.monitor.%d = %ld", self->name, + par[0]->value.v.intValue,counts); + return 1; +} +/*--------------------------------------------------------------------------*/ +static int GetCountsCmd(pSICSOBJ ccmd, SConnection * con, + Hdb * cmdNode, Hdb * par[], int nPar) +{ + long counts; + pCounter self = (pCounter)ccmd; + counts = self->getCounts(self,con); + SCPrintf(con,eValue,"%s.counts = %ld", self->name,counts); + return 1; +} +/*--------------------------------------------------------------------------*/ static int CountNBCmd(pSICSOBJ ccmd, SConnection * con, Hdb * cmdNode, Hdb * par[], int nPar) { @@ -587,12 +612,24 @@ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length) } AddHipadabaChild(node, child, NULL); + child = MakeSICSHdbPar("exponent", usUser, + MakeHdbInt(0)); + if (child == NULL) { + return NULL; + } + SetHdbProperty(child, "__save", "true"); + AddHipadabaChild(node, child, NULL); + child = AddSICSHdbPar(node,"count", usUser, MakeSICSFunc(CountCmd)); AddSICSHdbPar(child, "preset", usUser, MakeHdbFloat(2)); child = AddSICSHdbPar(node,"countnb", usUser, MakeSICSFunc(CountNBCmd)); AddSICSHdbPar(child, "preset", usUser, MakeHdbFloat(2)); + child = AddSICSHdbPar(node,"getmonitor", usSpy, MakeSICSFunc(GetMonitorCmd)); + AddSICSHdbPar(child, "no", usSpy, MakeHdbInt(1)); + child = AddSICSHdbPar(node,"getcounts", usUser, MakeSICSFunc(GetCountsCmd)); + child = AddSICSHdbPar(node,"stop", usUser, MakeSICSFunc(StopCmd)); child = AddSICSHdbPar(node,"pause", usUser, MakeSICSFunc(PauseCmd)); child = AddSICSHdbPar(node,"continue", usUser, MakeSICSFunc(ContinueCmd)); diff --git a/histmemsec.c b/histmemsec.c index 871231e1..259466ef 100644 --- a/histmemsec.c +++ b/histmemsec.c @@ -254,8 +254,9 @@ static int SumCmd(pSICSOBJ ccmd, SConnection * pCon, lSum = sumWindow(dataNode->value.v.intArray, xstart,xend,dimNode->value.v.intArray[0], ystart, yend, dimNode->value.v.intArray[1]); SCPrintf(pCon,eValue,"%s.sum = %ld", ccmd->objectNode->name, lSum); + break; default: - SCPrintf(pCon,eError, "ERROR: summing not supported for %s dimensional data", + SCPrintf(pCon, eError, "ERROR: summing not supported for %d dimensional data", dimNode->value.arrayLength); return 0; } @@ -344,13 +345,13 @@ int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData, DeleteHipadabaNode(child,pCon); } - child = MakeSICSHdbPar("rank", usInternal, MakeHdbInt(rank)); + child = MakeSICSHdbPar("rank", usMugger, MakeHdbInt(rank)); if (child == NULL) { return 0; } AddHipadabaChild(node, child, NULL); - child = MakeSICSHdbPar("dim", usMugger, makeHdbValue(HIPINTAR,rank)); + child = MakeSICSHdbPar("dim", usMugger, makeHdbValue(HIPINTVARAR,rank)); if (child == NULL) { return 0; } diff --git a/macro.c b/macro.c index 6ef29fd3..76f3d914 100644 --- a/macro.c +++ b/macro.c @@ -171,24 +171,6 @@ static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter, return TCL_ERROR; } - /* check for endless loop */ - /* Arg2Text(margc, myarg, comBuffer, 131); */ - /* if (lastCommand != NULL) { */ - /* if (strcmp(lastCommand, comBuffer) == 0) { */ - /* Tcl_AppendResult(pInter, "ERROR: Never ending loop in unknown\n", */ - /* "Offending command: ", comBuffer, */ - /* " Probably Tcl command not found", NULL); */ - /* /\* SCSetInterrupt(pCon, eAbortBatch); */ - /* The interrupt cause me a problem in a race condition at BOA. */ - /* Try to understand why this check is necessary in the first place. */ - /* *\/ */ - /* return TCL_ERROR; */ - /* } */ - /* } */ - /* if (pSics->lastUnknown[pSics->iStack]) */ - /* free(pSics->lastUnknown[pSics->iStack]); */ - /* pSics->lastUnknown[pSics->iStack] = strdup(comBuffer); */ - /* invoke */ pCon->sicsError = 0; iMacro = SCinMacro(pCon); diff --git a/motorlist.c b/motorlist.c index cd6ba250..acd7cc14 100644 --- a/motorlist.c +++ b/motorlist.c @@ -6,6 +6,10 @@ copyright: see file COPYRIGHT Mark Koennecke, September 2005 + + modified to use the task system + + Mark Koennecke, January 2014 -----------------------------------------------------------------------*/ #include "motorlist.h" #include "lld.h" @@ -73,17 +77,18 @@ static int MOLICheckLimits(void *data, float val, char *error, int errlen) ------------------------------------------------------------------*/ static long MOLISetValue(void *data, SConnection * pCon, float val) { - int self = 0, iRet, test; + int self = 0, iRet; MotControl tuktuk; + self = *(int *) data; iRet = LLDnodePtr2First(self); while (iRet != 0) { LLDnodeDataTo(self, &tuktuk); - test = tuktuk.pDriv->SetValue(tuktuk.data, pCon, tuktuk.target); - if (test != 1) { - return test; + tuktuk.taskID = StartDriveTask(tuktuk.data,pCon,tuktuk.name,tuktuk.target); + if (tuktuk.taskID < 0) { + return HWFault; } else { tuktuk.running = 1; LLDnodeDataFrom(self, &tuktuk); @@ -105,7 +110,7 @@ static long MOLISetValue(void *data, SConnection * pCon, float val) ------------------------------------------------------------------*/ static int MOLICheckStatus(void *data, SConnection * pCon) { - int self = 0, iRet, status, result = HWIdle; + int self = 0, iRet, status; MotControl tuktuk; self = *(int *) data; @@ -114,35 +119,17 @@ static int MOLICheckStatus(void *data, SConnection * pCon) while (iRet != 0) { LLDnodeDataTo(self, &tuktuk); if (tuktuk.running == 1) { - status = tuktuk.pDriv->CheckStatus(tuktuk.data, pCon); - switch (status) { - case HWIdle: - tuktuk.running = 0; + status = isTaskIDRunning(pServ->pTasker,tuktuk.taskID); + if(status == 1){ + return HWBusy; + } else { + tuktuk.running = 0; LLDnodeDataFrom(self, &tuktuk); - break; - case HWBusy: - result = HWBusy; - break; - case HWFault: - case HWPosFault: - /** - * It is questionable if one should not set a flag here - * and keep polling: it is not clear if this error is a - * communication problem or that the motor really - * has stopped. - */ - return status; - break; - default: - /* - this is a programming error and has to be fixed - */ - assert(0); } } iRet = LLDnodePtr2Next(self); } - return result; + return HWIdle; } /*--------------------------------------------------------- A special version for EIGER. I am cautious: I have problems @@ -151,39 +138,7 @@ static int MOLICheckStatus(void *data, SConnection * pCon) -----------------------------------------------------------*/ int MOLIEigerStatus(void *data, SConnection * pCon) { - int self = 0, iRet, status, result = HWIdle; - MotControl tuktuk; - - self = *(int *) data; - - iRet = LLDnodePtr2First(self); - while (iRet != 0) { - LLDnodeDataTo(self, &tuktuk); - if (tuktuk.running == 1) { - status = tuktuk.pDriv->CheckStatus(tuktuk.data, pCon); - switch (status) { - case HWIdle: - tuktuk.running = 0; - LLDnodeDataFrom(self, &tuktuk); - break; - case HWBusy: - result = HWBusy; - break; - case HWFault: - case HWPosFault: - tuktuk.running = 0; - LLDnodeDataFrom(self, &tuktuk); - break; - default: - /* - this is a programming error and has to be fixed - */ - assert(0); - } - } - iRet = LLDnodePtr2Next(self); - } - return result; + return MOLICheckStatus(data,pCon); } /*---------------------------------------------------------------- diff --git a/motorlist.h b/motorlist.h index 4821dbd2..1b168757 100644 --- a/motorlist.h +++ b/motorlist.h @@ -19,6 +19,7 @@ typedef struct { pIDrivable pDriv; void *data; int running; + long taskID; } MotControl, *pMotControl; /*======================================================================*/ diff --git a/motorsec.c b/motorsec.c index 71443aa7..3f6710b5 100644 --- a/motorsec.c +++ b/motorsec.c @@ -268,6 +268,9 @@ 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; diff --git a/multicountersec.c b/multicountersec.c index 73fbb025..659b6486 100644 --- a/multicountersec.c +++ b/multicountersec.c @@ -98,6 +98,18 @@ static void doCountCommand(pHdb self, SConnection *pCon, int command) } } /*---------------------------------------------------------------------------------*/ +static void copyExponent(pHdb self, void *data) +{ + pHdb source = NULL, target = NULL; + + pCounter count = (pCounter)data; + source = GetHipadabaNode(self,"exponent"); + target = GetHipadabaNode(count->pDes->parNode,"exponent"); + if(source != NULL && target != NULL){ + UpdateHipadabaPar(target,MakeHdbInt(source->value.v.intValue), NULL); + } +} +/*---------------------------------------------------------------------------------*/ static void startMultiCounting(pHdb self, SConnection *pCon) { pHdb mode = NULL, preset = NULL, master = NULL, slaves = NULL; @@ -138,6 +150,7 @@ static void startMultiCounting(pHdb self, SConnection *pCon) if(data != NULL){ pCount = GetCountableInterface(data); if(pCount != NULL){ + copyExponent(self,data); pCount->SetCountParameters(data,preset->value.v.doubleValue, eMode); masterID = StartCountTask(data,pCon,name); @@ -163,6 +176,7 @@ static void startMultiCounting(pHdb self, SConnection *pCon) if(data != NULL){ pCount = GetCountableInterface(data); if(pCount != NULL){ + copyExponent(self,data); pCount->SetCountParameters(data,preset->value.v.doubleValue, eMode); masterID = StartCountTask(data,pCon,master->value.v.text); diff --git a/mumo.c b/mumo.c index 94ae6139..96b2d9cc 100644 --- a/mumo.c +++ b/mumo.c @@ -683,6 +683,9 @@ static void RecoverNamPos(pMulMot self, int argc, char *argv[]) decrement, increment and simple values. DingsBums pos name - makes the current position a named position with name name. + DingsBums defpos name [alias value..] - makes a named + position with name name. The par is a list of alias value + pairs with the appropriate positions for name. DingsBums getpos - gets the current named position DingsBums drop name - deletes the current named position name. @@ -841,7 +844,7 @@ int MultiWrapper(SConnection * pCon, SicsInterp * pSics, void *pData, case RECOVERNAMPOS: /* This is not meant to be user command but a facility to read - back data from sattus file. This is why the error checking + back data from status file. This is why the error checking is not happening */ RecoverNamPos(self, argc - 2, &argv[2]); diff --git a/nxscript.c b/nxscript.c index 604d5a3c..fb93a260 100644 --- a/nxscript.c +++ b/nxscript.c @@ -1460,6 +1460,9 @@ static int GetDefString(void *message, void *userData) self->argv[2]); return MPSTOP; } + NXDtextreplace(self->nx->dictHandle,self->defString, + self->defString,sizeof(self->defString)); + return MPCONTINUE; } @@ -1556,7 +1559,7 @@ static int SPutWrite(void *message, void *userData) case HIPINTAR: case HIPINTVARAR: status = NXDputdef(self->nx->fileHandle, self->nx->dictHandle, - self->defString, &self->v.v.intArray); + self->defString, self->v.v.intArray); break; case HIPFLOATAR: case HIPFLOATVARAR: diff --git a/oscillate.c b/oscillate.c index 2f5bf772..8a5228d0 100644 --- a/oscillate.c +++ b/oscillate.c @@ -80,7 +80,7 @@ static int OscillationTask(void *data) case HWFault: case HWPosFault: WriteToCommandLog("oscillator>> ", - "ERROR occurred in oscialltion, try running motor manually to find out more"); + "ERROR occurred in oscillation, try running motor manually to find out more"); WriteToCommandLog("oscillator>> ", "Trying to run other direction"); pos = getNextPos(self); diff --git a/outcode.c b/outcode.c index a55ee959..eb38384f 100644 --- a/outcode.c +++ b/outcode.c @@ -1,6 +1,6 @@ /* ------------------------------------------------------------------------ The OutCode's for SICS have to be translated from text at several - places in SICS. Wherever necessary sich code should include this file. + places in SICS. Wherever necessary such code should include this file. This restricts changes to Scommon.h and this file Mark Koennecke, November 1996 diff --git a/scriptcontext.c b/scriptcontext.c index 929fb294..21aeb6d9 100644 --- a/scriptcontext.c +++ b/scriptcontext.c @@ -48,6 +48,7 @@ typedef struct SctData { int inMacro; Hdb *node; long syncid; + int busy; } SctData; /* data for updatescript */ @@ -422,7 +423,10 @@ static char *SctActionHandler(void *actionData, char *lastReply, } else { con = controller->conn; } + data->busy = 1; + /* + * Check if this is a followup call. * If this is a followup call, the I/O system will have set the * property result to the data from the device. Read this now and * print it if diagnostics is required. @@ -445,6 +449,8 @@ static char *SctActionHandler(void *actionData, char *lastReply, } /* + * Make sure that the state property is set to the name of the property + * which holds the name of the script to run at this stage. * When this is a followup, we use the content of the * state field as the property storing the next script to * run. If this is the start of a chain this is set to the @@ -491,6 +497,9 @@ static char *SctActionHandler(void *actionData, char *lastReply, } SyncedEnd(data->syncid); sct->sendNode = NULL; + /* + * Process the results of the script run + */ if (ret == 0) { /* * an error occurred in the script: store error message in @@ -588,7 +597,8 @@ static char *SctActionHandler(void *actionData, char *lastReply, free(script); script = NULL; /* - * If there is data to send, check it and do so + * If there is data to send, check it and do so. This also exits the + * quick script loop by returning the data to send to Devser. */ if (sct->sendCalled) { send = GetProp(node, controller->node, "send"); @@ -610,6 +620,10 @@ static char *SctActionHandler(void *actionData, char *lastReply, } SCPrintf(con, eLogError, "ERROR: too many quick scripts chained"); finish: + /* + * This section is always called when the script chain ends: either due to + * error or by successfull termination. + */ if (strcmp(data->name, "write") == 0) { if (GetHdbProp(node, "writestatus") != NULL) { SetHdbProperty(node, "writestatus", "commandsent"); @@ -624,6 +638,7 @@ finish: SCDeleteConnection(data->conCtx); data->conCtx = NULL; } + data->busy = 0; return send; } @@ -835,6 +850,7 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData, data->inMacro = SCinMacro(con); tracePar(node->name,"Queued %s to %s",node->name, GetCharArray(text)); data->syncid = SyncedIncr(0); + data->busy = 1; DevQueue(data->controller->devser, data, prio, SctWriteHandler, SctMatch, SctEndData, SctDataInfo); /* kill function SctEndData does not kill, data is owned by the node (callback list) */ @@ -1149,7 +1165,7 @@ void SctQueueNode(SctController * controller, Hdb * node, data->answered = 1; data->syncid = SyncedIncr(0); - + data->busy = 1; if (DevQueue(data->controller->devser, data, prio, SctWriteHandler, SctMatch, SctKillData, SctDataInfo)) { if (con != NULL) { @@ -1531,6 +1547,50 @@ static int SctSendCmd(pSICSOBJ ccmd, SConnection * con, return 1; } +static int SctProcessCmd(pSICSOBJ ccmd, SConnection * con, + Hdb * cmdNode, Hdb * par[], int nPar) +{ + SctData *data = NULL; + SctController *c; + + c = (SctController *) ccmd->pPrivate; + + if(nPar < 1 || par[0] == NULL){ + SCWrite(con,"ERROR: no node to process found", eError); + return 0; + } + + data = calloc(sizeof(SctData), 1); + if (data == NULL) { + SCWrite(con, "ERROR: out of memory in SctProcessCommand", eError); + return 0; + } + + data->node = FindHdbNode(NULL,par[0]->value.v.text, con); + if(data->node == NULL){ + SCPrintf(con,eError,"ERROR: node %s to process not found", par[0]->value.v.text); + return 0; + } + if(nPar > 1) { + data->name = strdup(par[1]->value.v.text); + } else { + data->name = strdup("read"); + } + data->controller = c; + data->conCtx = SCCopyConnection(con); + data->busy = 1; + data->inMacro = SCinMacro(con); + + DevQueue(c->devser, data, WritePRIO, + SctWriteHandler, SctMatch, NULL, SctDataInfo); + while (data->busy == 1) { + TaskYield(pServ->pTasker); + } + SctKillData(data); + + return 1; +} + static int SctDisconnect(pSICSOBJ ccmd, SConnection * con, Hdb * cmdNode, Hdb * par[], int nPar) { @@ -1857,6 +1917,11 @@ static int SctMakeController(SConnection * con, SicsInterp * sics, AddSICSHdbPar(cmd, "data", usMugger, MakeHdbText("")); AddSICSHdbPar(cmd, "prio", usMugger, MakeHdbText("")); + cmd = AddSICSHdbPar(controller->node, + "processnode", usUser, MakeSICSFunc(SctProcessCmd)); + AddSICSHdbPar(cmd, "node", usUser, MakeHdbText("")); + AddSICSHdbPar(cmd, "command", usUser, MakeHdbText("read")); + cmd = AddSICSHdbPar(controller->node, "disconnect", usMugger, MakeSICSFunc(SctDisconnect)); diff --git a/sctcomtask.c b/sctcomtask.c index 322b6d68..56796261 100644 --- a/sctcomtask.c +++ b/sctcomtask.c @@ -7,14 +7,14 @@ * - Retrieve reply data * - wait for a ComTask to finish. * - * The the purpose sctcomtask will keep a cache of pending and finished communications. + * The purpose sctcomtask will keep a cache of pending and finished communications. * Old runs will be deleted periodically. Nevertheless the cache can be listed in order * to figure out what happened. * * The intended use is for C-code or scripts to interact in a serial manner with * the asynchronous communication system implemented in devser and ascon. As a - * standalone implementation would share tons of code with scriptcontext, this has - * been implemented as an add on module to scriptcontext. + * standalone implementation this would share tons of code with scriptcontext, thus + * this has been implemented as an add on module to scriptcontext. * * copyright: see file COPYRIGHT * diff --git a/selector.c b/selector.c index 76f887df..16a8c76b 100644 --- a/selector.c +++ b/selector.c @@ -113,10 +113,10 @@ pSicsSelector CreateSelector(char *name, pMotor pTheta, pMotor pTwoTheta, /* create all the parameters */ ObParInit(pRes->pParams, SS, "ss", 1., usUser); - ObParInit(pRes->pParams, B1C1, "vk1", 1., usInternal); - ObParInit(pRes->pParams, B1C2, "vk2", 1., usInternal); - ObParInit(pRes->pParams, B2C1, "hk1", 1., usInternal); - ObParInit(pRes->pParams, B2C2, "hk2", 1., usInternal); + ObParInit(pRes->pParams, B1C1, "vk1", 1., usMugger); + ObParInit(pRes->pParams, B1C2, "vk2", 1., usMugger); + ObParInit(pRes->pParams, B2C1, "hk1", 1., usMugger); + ObParInit(pRes->pParams, B2C2, "hk2", 1., usMugger); ObParInit(pRes->pParams, LATD, "dd", 2.087, usMugger); ObParInit(pRes->pParams, RIGHTS, "access", usUser, usMugger); diff --git a/sicsget.c b/sicsget.c index 4c1fbdb5..c4ecc55c 100644 --- a/sicsget.c +++ b/sicsget.c @@ -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",GetCharArray(data)); + SCPrintf(pCon,eValue,"%s",trim(GetCharArray(data))); DeleteDynString(data); } else { SCPrintf(pCon,eError,"ERROR: formatting value for %s failed", argv[1]); @@ -176,7 +176,7 @@ static int SplitOffEqual(void *ms, void *userData) /*---------------------------------------------------------------------------*/ static int isNumber(char *txt) { - if(*txt == '\0'){ + if(*txt == '\0' || *txt == ' '){ return 1; } if(isalpha(*txt)){ @@ -189,12 +189,14 @@ static int isNumber(char *txt) static int countWords(char *txt) { char number[80]; + int count = 0; + char *pPtr = txt; - if(txt == NULL || strlen(txt) < 1){ - return 0; - } else { - return 1 + countWords(stptok(txt,number,sizeof(number)," ")); + while(pPtr != NULL){ + count++; + pPtr = stptok(pPtr,number,sizeof(number)," "); } + return count; } /*---------------------------------------------------------------------------*/ static hdbValue makeArray(char *txt, int type, int count) @@ -216,6 +218,7 @@ static hdbValue makeArray(char *txt, int type, int count) } else { ar.v.floatArray[i] = atof(number); } + i++; } return ar; } diff --git a/sicshipadaba.c b/sicshipadaba.c index b92494e7..82da1b6f 100644 --- a/sicshipadaba.c +++ b/sicshipadaba.c @@ -596,6 +596,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData, pHdbPtrMessage cmm = NULL; pHdbDataMessage mm = NULL; SConnection *tstCon; + char updatePath[1024]; cbInfo = (HdbCBInfo *) userData; @@ -657,7 +658,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData, return hdbContinue; } - pPath = GetHipadabaPath(node); + GetHdbPath(node,updatePath,sizeof(updatePath)); result = CreateDynString(128, 128); if ((protocol = isJSON(cbInfo->pCon)) == 1) outCode = eHdbEvent; @@ -671,14 +672,13 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData, if (GetHdbProperty(node, "transfer", value, 80) == 1) { if (strstr(value, "zip") != NULL || strstr(value,"bin") != NULL) { status = sendZippedNodeData(node, *(mm->v), cbInfo->pCon); - free(pPath); DeleteDynString(result); return hdbContinue; } } if (mm->v->arrayLength < 100) { printedData = formatValue(*(mm->v), node); - if (pPath == NULL || printedData == NULL || result == NULL) { + if (printedData == NULL || result == NULL) { SCWrite(cbInfo->pCon, "ERROR: out of memory formatting data", eEvent); /* @@ -687,7 +687,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData, */ return hdbContinue; } - formatNameValue(protocol, pPath, GetCharArray(printedData), result, + formatNameValue(protocol, updatePath, GetCharArray(printedData), result, mm->v->dataType); /* SCWrite(cbInfo->pCon, GetCharArray(result), outCode); */ SCPureSockWrite(cbInfo->pCon, GetCharArray(result), outCode); @@ -696,7 +696,6 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData, formatNameValue(protocol, pPath, "!!datachange!!", result, HIPTEXT); SCWrite(cbInfo->pCon, GetCharArray(result), outCode); } - free(pPath); DeleteDynString(result); return hdbContinue; diff --git a/stdscan.c b/stdscan.c index 06da3638..c0df18ff 100644 --- a/stdscan.c +++ b/stdscan.c @@ -950,7 +950,11 @@ static int StandardScriptInvoke(pScanData self, char *function) if (command == NULL) { return 0; } - status = InterpExecute(self->pSics, self->pCon, GetCharArray(command)); + if(self->pCon != NULL){ + status = InterpExecute(pServ->pSics, self->pCon, GetCharArray(command)); + } else { + status = InterpExecute(pServ->pSics, pServ->dummyCon, GetCharArray(command)); + } DeleteDynString(command); if (status != 1) { return 0; diff --git a/tasdrive.c b/tasdrive.c index 5fe1ea3d..852dc1e0 100644 --- a/tasdrive.c +++ b/tasdrive.c @@ -5,12 +5,14 @@ Mark Koennecke, May 2005 - In the long run it might be useful to switch all this to the more - general motor list driving code. Modified to rather use drivables then motors Mark Koennecke, September 2011 + + Modified to use drive tasks + + Mark Koennecke, January 2014 --------------------------------------------------------------------*/ #include #include "sics.h" @@ -72,7 +74,12 @@ int readTASMotAngles(ptasUB self, SConnection * pCon, if (status == 0) { return status; } - theta = val; + theta = val;/* $Id: tasdrive.c,v 1.39 2014/02/18 13:25:32 koennecke Exp $ */ + +#ifndef lint +static char vcid[] = "$Id: tasdrive.c,v 1.39 2014/02/18 13:25:32 koennecke Exp $"; +#endif /* lint */ + status = GetDrivablePosition(self->motors[A2], pCon, &val); if (status == 0) { return status; @@ -274,7 +281,7 @@ static float getMotorValue(pMotor mot, SConnection * pCon) void InvokeNewTarget(pExeList self, char *name, float target); /*--------------------------------------------------------------------------*/ static int startTASMotor(pMotor mot, SConnection * pCon, char *name, - double target, int silent, int stopFixed) + double target, int silent, int stopFixed, long groupID) { float val, fixed, precision = MOTPREC; int status = OKOK; @@ -282,6 +289,7 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name, pIDrivable pDriv = NULL; pDummy dum = NULL; pDynString mes = NULL; + long taskID; dum = (pDummy)mot; val = getMotorValue(mot, pCon); @@ -298,10 +306,11 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name, } mot->stopped = 0; if (ABS(val - target) > precision) { - pDriv = GetDrivableInterface(mot); - status = pDriv->SetValue(mot, pCon, (float) target); - if(status != OKOK){ + taskID = StartDriveTask(mot,pCon,name,target); + if(taskID < 0){ SCPrintf(pCon,eLog,"ERROR: failed to drive %s to %f", name, target); + } else { + AddTaskToGroup(pServ->pTasker,taskID, groupID); } /* to force updates on targets @@ -313,7 +322,8 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name, } /*-------------------------------------------------------------------------*/ static int StartTASA3(pMotor mot, SConnection *pCon, char *name, - double target, int silent, int stopFixed) + double target, int silent, int stopFixed, + long groupID) { float val; int status; @@ -326,14 +336,14 @@ static int StartTASA3(pMotor mot, SConnection *pCon, char *name, status = SCPromptTMO(pCon,NULL,buffer,sizeof(buffer),120); if(status == 1){ if(buffer[0] == 'y'){ - return startTASMotor(mot,pCon,name,target,silent,stopFixed); + return startTASMotor(mot,pCon,name,target,silent,stopFixed,groupID); } } SCWrite(pCon,"ERROR: no or wrong reply, aborting scan",eLogError); SCSetInterrupt(pCon,eAbortScan); return HWFault; } else { - return startTASMotor(mot,pCon,name,target,silent,stopFixed); + return startTASMotor(mot,pCon,name,target,silent,stopFixed,groupID); } } /*---------------------------------------------------------------------------*/ @@ -346,6 +356,9 @@ static int startMotors(ptasMot self, tasAngles angles, silent = self->math->silent; stopFixed = self->math->stopFixed; self->math->mustRecalculate = 1; + + self->math->groupID = GetTaskGroupID(pServ->pTasker); + /* monochromator */ @@ -353,6 +366,8 @@ static int startMotors(ptasMot self, tasAngles angles, pCon,angles.monochromator_two_theta); if(status != OKOK){ return status; + } else { + AddTaskToGroup(pServ->pTasker, self->math->monoTaskID, self->math->groupID); } /* @@ -360,12 +375,12 @@ static int startMotors(ptasMot self, tasAngles angles, */ if (self->math->tasMode != ELASTIC) { status = startTASMotor(self->math->motors[A5], pCon, "a5", - angles.analyzer_two_theta / 2.0, silent,stopFixed); + angles.analyzer_two_theta / 2.0, silent,stopFixed,self->math->groupID); if (status != OKOK) { return status; } status = startTASMotor(self->math->motors[A6], pCon, "a6", - angles.analyzer_two_theta, silent,stopFixed); + angles.analyzer_two_theta, silent,stopFixed,self->math->groupID); if (status != OKOK) { return status; } @@ -374,7 +389,7 @@ static int startMotors(ptasMot self, tasAngles angles, curve = maCalcVerticalCurvature(self->math->machine.analyzer, angles.analyzer_two_theta); status = startTASMotor(self->math->motors[ACV], pCon, "acv", - curve, silent,stopFixed); + curve, silent,stopFixed,self->math->groupID); if (status != OKOK) { SCWrite(pCon,"WARNING: analyzer vertical curvature motor failed to start", eLog); SCSetInterrupt(pCon,eContinue); @@ -384,7 +399,7 @@ static int startMotors(ptasMot self, tasAngles angles, curve = maCalcHorizontalCurvature(self->math->machine.analyzer, angles.analyzer_two_theta); status = startTASMotor(self->math->motors[ACH], pCon, "ach", - curve, silent,stopFixed); + curve, silent,stopFixed,self->math->groupID); if (status != OKOK) { SCWrite(pCon,"WARNING: analyzer horizontal curvature motor failed to start", eLog); SCSetInterrupt(pCon,eContinue); @@ -400,24 +415,24 @@ static int startMotors(ptasMot self, tasAngles angles, crystal */ status = StartTASA3(self->math->motors[A3], pCon, "a3", - angles.a3, silent,stopFixed); + angles.a3, silent,stopFixed,self->math->groupID); if (status != OKOK) { return status; } status = startTASMotor(self->math->motors[A4], pCon, "a4", - angles.sample_two_theta, silent,stopFixed); + angles.sample_two_theta, silent,stopFixed,self->math->groupID); if (status != OKOK) { return status; } if (driveTilt == 1) { status = startTASMotor(self->math->motors[SGL], pCon, "sgl", - angles.sgl, silent,stopFixed); + angles.sgl, silent,stopFixed, self->math->groupID); if (status != OKOK) { return status; } status = startTASMotor(self->math->motors[SGU], pCon, "sgu", - angles.sgu, silent,stopFixed); + angles.sgu, silent,stopFixed,self->math->groupID); if (status != OKOK) { return status; } @@ -566,60 +581,12 @@ static int calculateAndDrive(ptasMot self, SConnection * pCon) /*-----------------------------------------------------------------------------*/ static int checkMotors(ptasMot self, SConnection * pCon) { - int i, status, length = 12, count; - int mask[12], busy[12]; - pIDrivable pDrivInt = NULL; - self->math->mustRecalculate = 1; - if (self->math->tasMode == ELASTIC) { - length = 8; - } - memset(mask, 0, 12 * sizeof(int)); - memset(busy, 0, 12 * sizeof(int)); - for (i = 0; i < length; i++) { - mask[i] = 1; - busy[i] = 1; - } - if (self->math->outOfPlaneAllowed == 0) { - mask[SGU] = 0; - mask[SGL] = 0; - } - /* - check monochromator - */ - status = self->math->mono->CheckStatus(self->math->monoData,pCon); - if(status == HWIdle){ - for(i = 0; i < 4; i++){ - busy[i] = 0; - } - } - - /* - check the rest - */ - for (i = 4; i < 12; i++) { - if(self->math->motors[i] == NULL){ - busy[i] = 0; - } else { - if(mask[i] != 0) { - pDrivInt = GetDrivableInterface(self->math->motors[i]); - status = pDrivInt->CheckStatus(self->math->motors[i], pCon); - if(status == HWIdle || status == OKOK || status == HWFault || status == HWPosFault){ - busy[i] = 0; - } - } else { - busy[i] = 0; - } - } - } - for(i = 0, count = 0; i < 12; i++){ - count += busy[i]; - } - if(count == 0) { - return HWIdle; - } else { + if(isTaskGroupRunning(pServ->pTasker,self->math->groupID)){ return HWBusy; + } else { + return HWIdle; } } @@ -653,42 +620,18 @@ static int startQMMotors(ptasMot self, tasAngles angles, silent = self->math->silent; stopFixed = self->math->stopFixed; + + self->math->groupID = GetTaskGroupID(pServ->pTasker); + /* - monochromator - */ - /* status = startTASMotor(self->math->motors[A1], pCon, "a1", */ - /* angles.monochromator_two_theta / 2., silent,stopFixed); */ - /* if (status != OKOK) { */ - /* return status; */ - /* } */ - /* status = startTASMotor(self->math->motors[A2], pCon, "a2", */ - /* angles.monochromator_two_theta, silent,stopFixed); */ - /* if (status != OKOK) { */ - /* return status; */ - /* } */ - - /* if (self->math->motors[MCV] != NULL) { */ - /* curve = maCalcVerticalCurvature(self->math->machine.monochromator, */ - /* angles.monochromator_two_theta); */ - /* status = startTASMotor(self->math->motors[MCV], pCon, "mcv", */ - /* curve, silent,stopFixed); */ - /* if (status != OKOK) { */ - /* return status; */ - /* } */ - /* } */ - - /* if (self->math->motors[MCH] != NULL) { */ - /* curve = maCalcHorizontalCurvature(self->math->machine.monochromator, */ - /* angles.monochromator_two_theta); */ - /* status = startTASMotor(self->math->motors[MCH], pCon, "mch", */ - /* curve, silent,stopFixed); */ - /* if (status != OKOK) { */ - /* return status; */ - /* } */ - /* } */ - status = self->math->mono->SetValue(self->math->monoData,pCon,angles.analyzer_two_theta); + monochromator + */ + status = self->math->mono->SetValue(self->math->monoData, + pCon,angles.monochromator_two_theta); if(status != OKOK){ return status; + } else { + AddTaskToGroup(pServ->pTasker, self->math->monoTaskID, self->math->groupID); } @@ -696,12 +639,12 @@ static int startQMMotors(ptasMot self, tasAngles angles, analyzer */ status = startTASMotor(self->math->motors[A5], pCon, "a5", - angles.analyzer_two_theta / 2.0, silent,stopFixed); + angles.analyzer_two_theta / 2.0, silent,stopFixed,self->math->groupID); if (status != OKOK) { return status; } status = startTASMotor(self->math->motors[A6], pCon, "a6", - angles.analyzer_two_theta, silent,stopFixed); + angles.analyzer_two_theta, silent,stopFixed,self->math->groupID); if (status != OKOK) { return status; } @@ -710,7 +653,7 @@ static int startQMMotors(ptasMot self, tasAngles angles, curve = maCalcVerticalCurvature(self->math->machine.analyzer, angles.analyzer_two_theta); status = startTASMotor(self->math->motors[ACV], pCon, "acv", - curve, silent,stopFixed); + curve, silent,stopFixed,self->math->groupID); if (status != OKOK) { return status; } @@ -719,7 +662,7 @@ static int startQMMotors(ptasMot self, tasAngles angles, curve = maCalcHorizontalCurvature(self->math->machine.analyzer, angles.analyzer_two_theta); status = startTASMotor(self->math->motors[ACH], pCon, "ach", - curve, silent,stopFixed); + curve, silent,stopFixed,self->math->groupID); if (status != OKOK) { return status; } @@ -729,7 +672,7 @@ static int startQMMotors(ptasMot self, tasAngles angles, crystal */ status = startTASMotor(self->math->motors[A4], pCon, "a4", - angles.sample_two_theta, silent,stopFixed); + angles.sample_two_theta, silent,stopFixed,self->math->groupID); if (status != OKOK) { return status; } diff --git a/tasub.h b/tasub.h index 3c5eab5b..5ea047ef 100644 --- a/tasub.h +++ b/tasub.h @@ -37,6 +37,7 @@ int silent; int stopFixed; /* flag to stop multiple fixed messages in scans*/ char *updater; + long groupID; }tasUB, *ptasUB; diff --git a/velo.c b/velo.c index 35db8584..797bcc23 100644 --- a/velo.c +++ b/velo.c @@ -479,7 +479,7 @@ int VSGetTilt(pVelSel self, float *fTilt) { assert(self); - return self->pTilt->pDriver->GetPosition(self->pTilt->pDriver, fTilt); + return MotorGetSoftPosition(self->pTilt, pServ->dummyCon,fTilt); }