- Modified collective drive operations to run motors in individual tasks

- Added a processnode methos to scriptcontext. processnode waits for the
  scriptchain of a node to finish.
- Fixed a bug in sicsget
- Made histmemsec dim and rank manager privilege. To allow chnage at runtime.
  Is required for SANS
- Fixed some issues with multicountersec, mostly relating to passing things through
  in a sensible way.
- Updated motorsec.c to work with a client based driver


SKIPPED:
	psi/polterwrite.c
	psi/tabledrive.c
	psi/tabledrive.h
This commit is contained in:
koennecke
2014-02-18 13:25:32 +00:00
parent 95d37fea12
commit 33e122ea9e
22 changed files with 240 additions and 241 deletions

View File

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

View File

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

View File

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

View File

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

18
macro.c
View File

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

View File

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

View File

@ -19,6 +19,7 @@ typedef struct {
pIDrivable pDriv;
void *data;
int running;
long taskID;
} MotControl, *pMotControl;
/*======================================================================*/

View File

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

View File

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

5
mumo.c
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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",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;
}

View File

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

View File

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

View File

@ -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 <assert.h>
#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);
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;
}

View File

@ -37,6 +37,7 @@
int silent;
int stopFixed; /* flag to stop multiple fixed messages in scans*/
char *updater;
long groupID;
}tasUB, *ptasUB;

2
velo.c
View File

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