diff --git a/site_ansto/Makefile b/site_ansto/Makefile index 37a01457..23607837 100644 --- a/site_ansto/Makefile +++ b/site_ansto/Makefile @@ -153,6 +153,7 @@ GHTTP_LIBS = $(LIB_HTTP) OBJ= site_ansto.o anstoutil.o\ ansto_sctdriveadapter.o\ + ansto_tclmotdriv.o\ sctemonadapter.o\ motor_asim.o motor_dmc2280.o\ lh45.o lh45driv.o \ diff --git a/site_ansto/ansto_tclmotdriv.c b/site_ansto/ansto_tclmotdriv.c index 35dbd328..57b447df 100644 --- a/site_ansto/ansto_tclmotdriv.c +++ b/site_ansto/ansto_tclmotdriv.c @@ -19,9 +19,18 @@ facilitate error handling, a motor parameter errorcode is available to store errors between invocations. - Author: Jing Chen, Nov 2012 - copyright: see file COPYRIGHT + + Author: Mark Koennecke, December 2005 + + ANSTO MODIFICATIONS: + Jing Chen, Nov 2012: + Support extra parameters as calls to Tcl code. + + Ferdi Franceschini April 2013: + Use prefixes imot_, hdb_, and get_ to tell driver how to handle different + types of functions. Added debug info support. + --------------------------------------------------------------------------*/ #include @@ -32,7 +41,7 @@ #include "modriv.h" #include "lld.h" #include "stringdict.h" -#include "tclmotdriv.h" +#include "ansto_tclmotdriv.h" #define FUNCNOTFOUND -11000 #define TCLERROR -11001 @@ -44,275 +53,310 @@ #define LONG_NAME "long_name" #define ERRORCODE "errorcode" +void logTclCall(TCLDriv *pDriv, char *fn, char *script) { + char msg[512]; + snprintf(msg, 511, "tclmot %s.%s -> %s\n", pDriv->motName, fn, script); + SICSLogWrite(msg, eLog); +} /*----------------------------------------------------------------------------*/ -static int buildStandardCommandPart(TCLDriv *pDriv, char *command, - char *tclCommand, int commandLen){ - char tclFunc[132]; - int status; - - status = StringDictGet(pDriv->mappings,command,tclFunc,131); - if(status != 1) { - return 0; - } - //snprintf(tclCommand,commandLen,"%s %s ", tclFunc, pDriv->motName); - snprintf(tclCommand,commandLen,"%s", tclFunc); - return 1; +static int buildStandardCommandPart(TCLDriv * pDriv, char *command, + char *tclCommand, int commandLen) +{ + char tclFunc[132]; + int status; + + status = StringDictGet(pDriv->mappings, command, tclFunc, 131); + if (status != 1) { + return 0; + } + snprintf(tclCommand,commandLen,"%s %s ", tclFunc, pDriv->motName); +//snprintf(tclCommand, commandLen, "%s", tclFunc); + return 1; } /*----------------------------------------------------------------------------*/ - static int GetTclPos(void *self, float *fPos){ - TCLDriv *pDriv; - int status; - const char *result = NULL; - - assert(self); - pDriv = (TCLDriv *)self; +static int GetTclPos(void *self, float *fPos) +{ + TCLDriv *pDriv; + int status; + const char *result = NULL; - char *tclCommand = (char *)calloc(1024, sizeof(char)); + assert(self); + pDriv = (TCLDriv *) self; - pDriv->errorCode = 0; - if(!buildStandardCommandPart(pDriv,"getpos",tclCommand,1023)){ - pDriv->errorCode = FUNCNOTFOUND; - free(tclCommand); - return HWFault; - } + char *tclCommand = (char *) calloc(1024, sizeof(char)); - status = Tcl_Eval(pServ->pSics->pTcl,tclCommand); - result = Tcl_GetStringResult(pServ->pSics->pTcl); + pDriv->errorCode = 0; + if (!buildStandardCommandPart(pDriv, "getpos", tclCommand, 1023)) { + pDriv->errorCode = FUNCNOTFOUND; free(tclCommand); - if(result == NULL){ - pDriv->errorCode = NOTCLRESULT; - return HWFault; - } - if(status != TCL_OK){ - pDriv->errorCode = TCLERROR; - strncpy(pDriv->tclError,result,1023); - return HWFault; - } - sscanf(result,"%f",fPos); - return OKOK; - } -/*----------------------------------------------------------------------------*/ - static int TclRun(void *self, float fVal) { - TCLDriv *pDriv; - char num[80]; - int status; - const char *result = NULL; - - assert(self); - pDriv = (TCLDriv *)self; - - char *tclCommand = (char *)calloc(1024, sizeof(char)); - - pDriv->errorCode = 0; - if(!buildStandardCommandPart(pDriv,"run",tclCommand,1023)){ - pDriv->errorCode = FUNCNOTFOUND; - free(tclCommand); - return HWFault; - } - snprintf(num,79,"%f",fVal); - strncat(tclCommand,num,1023-strlen(tclCommand)); - - status = Tcl_Eval(pServ->pSics->pTcl,tclCommand); - result = Tcl_GetStringResult(pServ->pSics->pTcl); - free(tclCommand); - if(result == NULL) { - pDriv->errorCode = NOTCLRESULT; - return HWFault; - } - if(status != TCL_OK){ - pDriv->errorCode = TCLERROR; - strncpy(pDriv->tclError,result,1023); - return HWFault; - } - sscanf(result,"%d",&status); - return status; - } -/*-------------------------------------------------------------------------*/ -static int evaluateInternalErrors(TCLDriv *pDriv, int *iCode, - char *error, int iErrLen){ - switch(pDriv->errorCode){ - case FUNCNOTFOUND: - strncpy(error,"Config Error: Tcl function for driver not found",iErrLen); - *iCode = pDriv->errorCode; - return 1; - break; - case TCLERROR: - strncpy(error,pDriv->tclError,iErrLen); - *iCode = pDriv->errorCode; - return 1; - break; - case NOTCLRESULT: - strncpy(error,"Tcl function did not return result",iErrLen); - *iCode = pDriv->errorCode; - return 1; - break; - default: - return 0; - break; - } - return 0; -} -/*--------------------------------------------------------------------------*/ - static void TclGetError(void *self, int *iCode, char *error, int iErrLen){ - TCLDriv *pDriv; - int status = 1; - const char *result = NULL; - - assert(self); - pDriv = (TCLDriv *)self; - - if(evaluateInternalErrors(pDriv,iCode,error,iErrLen) == 1) { - return; - } - - char *tclCommand = (char *)calloc(1024, sizeof(char)); - - if(!buildStandardCommandPart(pDriv,"geterror",tclCommand,1023)){ - pDriv->errorCode = FUNCNOTFOUND; - status = 0; - } - - if(status != 0){ - status = Tcl_Eval(pServ->pSics->pTcl,tclCommand); - result = Tcl_GetStringResult(pServ->pSics->pTcl); - if(result == NULL) { - pDriv->errorCode = NOTCLRESULT; - } - if(status != TCL_OK && result != NULL){ - pDriv->errorCode = TCLERROR; - strncpy(pDriv->tclError,result,1023); - } - } - - if(evaluateInternalErrors(pDriv,iCode,error,iErrLen) == 1) { - free(tclCommand); - return; - } - free(tclCommand); - strncpy(error,result,iErrLen); + return HWFault; } + if (pDriv->debug) + logTclCall(pDriv, "getpos", tclCommand); + + status = Tcl_Eval(pServ->pSics->pTcl, tclCommand); + result = Tcl_GetStringResult(pServ->pSics->pTcl); + free(tclCommand); + if (result == NULL) { + pDriv->errorCode = NOTCLRESULT; + return HWFault; + } + if (status != TCL_OK) { + pDriv->errorCode = TCLERROR; + strncpy(pDriv->tclError, result, 1023); + return HWFault; + } + sscanf(result, "%f", fPos); + return OKOK; +} + +/*----------------------------------------------------------------------------*/ +static int TclRun(void *self, float fVal) +{ + TCLDriv *pDriv; + char num[80]; + int status; + const char *result = NULL; + + assert(self); + pDriv = (TCLDriv *) self; + + char *tclCommand = (char *) calloc(1024, sizeof(char)); + + pDriv->errorCode = 0; + if (!buildStandardCommandPart(pDriv, "run", tclCommand, 1023)) { + pDriv->errorCode = FUNCNOTFOUND; + free(tclCommand); + return HWFault; + } + snprintf(num, 79, "%f", fVal); + strncat(tclCommand, num, 1023 - strlen(tclCommand)); + + if (pDriv->debug) + logTclCall(pDriv, "run", tclCommand); + + status = Tcl_Eval(pServ->pSics->pTcl, tclCommand); + result = Tcl_GetStringResult(pServ->pSics->pTcl); + free(tclCommand); + if (result == NULL) { + pDriv->errorCode = NOTCLRESULT; + return HWFault; + } + if (status != TCL_OK) { + pDriv->errorCode = TCLERROR; + strncpy(pDriv->tclError, result, 1023); + return HWFault; + } + sscanf(result, "%d", &status); + return status; +} + +/*-------------------------------------------------------------------------*/ +static int evaluateInternalErrors(TCLDriv * pDriv, int *iCode, + char *error, int iErrLen) +{ + switch (pDriv->errorCode) { + case FUNCNOTFOUND: + strncpy(error, "Config Error: Tcl function for driver not found", + iErrLen); + *iCode = pDriv->errorCode; + return 1; + break; + case TCLERROR: + strncpy(error, pDriv->tclError, iErrLen); + *iCode = pDriv->errorCode; + return 1; + break; + case NOTCLRESULT: + strncpy(error, "Tcl function did not return result", iErrLen); + *iCode = pDriv->errorCode; + return 1; + break; + default: + return 0; + break; + } + return 0; +} + +/*--------------------------------------------------------------------------*/ +static void TclGetError(void *self, int *iCode, char *error, int iErrLen) +{ + TCLDriv *pDriv; + int status = 1; + const char *result = NULL; + + assert(self); + pDriv = (TCLDriv *) self; + + if (evaluateInternalErrors(pDriv, iCode, error, iErrLen) == 1) { + return; + } + + char *tclCommand = (char *) calloc(1024, sizeof(char)); + + if (!buildStandardCommandPart(pDriv, "geterror", tclCommand, 1023)) { + pDriv->errorCode = FUNCNOTFOUND; + status = 0; + } + + if (status != 0) { + if (pDriv->debug) + logTclCall(pDriv, "geterror", tclCommand); + + status = Tcl_Eval(pServ->pSics->pTcl, tclCommand); + result = Tcl_GetStringResult(pServ->pSics->pTcl); + if (result == NULL) { + pDriv->errorCode = NOTCLRESULT; + } + if (status != TCL_OK && result != NULL) { + pDriv->errorCode = TCLERROR; + strncpy(pDriv->tclError, result, 1023); + } + } + + if (evaluateInternalErrors(pDriv, iCode, error, iErrLen) == 1) { + free(tclCommand); + return; + } + free(tclCommand); + strncpy(error, result, iErrLen); +} + /*---------------------------------------------------------------------------*/ - static int TclTryAndFixIt(void *self, int iError, float fNew){ - TCLDriv *pDriv; - char num[80]; - int status; - const char *result = NULL; - - assert(self); - pDriv = (TCLDriv *)self; +static int TclTryAndFixIt(void *self, int iError, float fNew) +{ + TCLDriv *pDriv; + char num[80]; + int status; + const char *result = NULL; - char *tclCommand = (char *)calloc(1024, sizeof(char)); + assert(self); + pDriv = (TCLDriv *) self; - if(!buildStandardCommandPart(pDriv,"fixit",tclCommand,1023)){ - pDriv->errorCode = FUNCNOTFOUND; - free(tclCommand); - return HWFault; - } - snprintf(num,79,"%d %f",pDriv->errorCode, fNew); - strncat(tclCommand,num,1023-strlen(tclCommand)); + char *tclCommand = (char *) calloc(1024, sizeof(char)); - status = Tcl_Eval(pServ->pSics->pTcl,tclCommand); - result = Tcl_GetStringResult(pServ->pSics->pTcl); - if(result == NULL) { - pDriv->errorCode = NOTCLRESULT; - free(tclCommand); - return HWFault; - } - if(status != TCL_OK){ - pDriv->errorCode = TCLERROR; - strncpy(pDriv->tclError,result,1023); - free(tclCommand); - return HWFault; - } - sscanf(result,"%d",&status); + if (!buildStandardCommandPart(pDriv, "fixit", tclCommand, 1023)) { + pDriv->errorCode = FUNCNOTFOUND; free(tclCommand); - return status; + return HWFault; } + snprintf(num, 79, "%d %f", pDriv->errorCode, fNew); + strncat(tclCommand, num, 1023 - strlen(tclCommand)); + + if (pDriv->debug) + logTclCall(pDriv, "fixit", tclCommand); + + status = Tcl_Eval(pServ->pSics->pTcl, tclCommand); + result = Tcl_GetStringResult(pServ->pSics->pTcl); + if (result == NULL) { + pDriv->errorCode = NOTCLRESULT; + free(tclCommand); + return HWFault; + } + if (status != TCL_OK) { + pDriv->errorCode = TCLERROR; + strncpy(pDriv->tclError, result, 1023); + free(tclCommand); + return HWFault; + } + sscanf(result, "%d", &status); + free(tclCommand); + return status; +} /*--------------------------------------------------------------------------*/ - static int TclHalt(void *self) - { - TCLDriv *pDriv; - int status; - const char *result = NULL; - - assert(self); - pDriv = (TCLDriv *)self; +static int TclHalt(void *self) +{ + TCLDriv *pDriv; + int status; + const char *result = NULL; - pDriv->errorCode = 0; + assert(self); + pDriv = (TCLDriv *) self; - char *tclCommand = (char *)calloc(1024, sizeof(char)); + pDriv->errorCode = 0; - if(!buildStandardCommandPart(pDriv,"halt",tclCommand,1023)){ - pDriv->errorCode = FUNCNOTFOUND; - free(tclCommand); - return HWFault; - } + char *tclCommand = (char *) calloc(1024, sizeof(char)); - status = Tcl_Eval(pServ->pSics->pTcl,tclCommand); - result = Tcl_GetStringResult(pServ->pSics->pTcl); - if(result == NULL){ - pDriv->errorCode = NOTCLRESULT; - free(tclCommand); - return HWFault; - } - if(status != TCL_OK){ - pDriv->errorCode = TCLERROR; - strncpy(pDriv->tclError,result,1023); - free(tclCommand); - return HWFault; - } + if (!buildStandardCommandPart(pDriv, "halt", tclCommand, 1023)) { + pDriv->errorCode = FUNCNOTFOUND; free(tclCommand); - return OKOK; + return HWFault; } + if (pDriv->debug) + logTclCall(pDriv, "halt", tclCommand); + + status = Tcl_Eval(pServ->pSics->pTcl, tclCommand); + result = Tcl_GetStringResult(pServ->pSics->pTcl); + if (result == NULL) { + pDriv->errorCode = NOTCLRESULT; + free(tclCommand); + return HWFault; + } + if (status != TCL_OK) { + pDriv->errorCode = TCLERROR; + strncpy(pDriv->tclError, result, 1023); + free(tclCommand); + return HWFault; + } + free(tclCommand); + return OKOK; +} + /*--------------------------------------------------------------------------*/ - static int TclGetStatus(void *self) - { - TCLDriv *pDriv; - int status; - const char *result = NULL; - - assert(self); - pDriv = (TCLDriv *)self; +static int TclGetStatus(void *self) +{ + TCLDriv *pDriv; + int status; + const char *result = NULL; - pDriv->errorCode = 0; + assert(self); + pDriv = (TCLDriv *) self; - char *tclCommand = (char *)calloc(1024, sizeof(char)); + pDriv->errorCode = 0; - if(!buildStandardCommandPart(pDriv,"status",tclCommand,1023)){ - pDriv->errorCode = FUNCNOTFOUND; - free(tclCommand); - return HWFault; - } + char *tclCommand = (char *) calloc(1024, sizeof(char)); - status = Tcl_Eval(pServ->pSics->pTcl,tclCommand); - result = Tcl_GetStringResult(pServ->pSics->pTcl); - if(result == NULL){ - pDriv->errorCode = NOTCLRESULT; - free(tclCommand); - return HWFault; - } - if(status != TCL_OK){ - pDriv->errorCode = TCLERROR; - strncpy(pDriv->tclError,result,1023); - free(tclCommand); - return HWFault; - } - sscanf(result,"%d",&status); + if (!buildStandardCommandPart(pDriv, "status", tclCommand, 1023)) { + pDriv->errorCode = FUNCNOTFOUND; free(tclCommand); - return status; + return HWFault; } + if (pDriv->debug) + logTclCall(pDriv, "status", tclCommand); + + status = Tcl_Eval(pServ->pSics->pTcl, tclCommand); + result = Tcl_GetStringResult(pServ->pSics->pTcl); + if (result == NULL) { + pDriv->errorCode = NOTCLRESULT; + free(tclCommand); + return HWFault; + } + if (status != TCL_OK) { + pDriv->errorCode = TCLERROR; + strncpy(pDriv->tclError, result, 1023); + free(tclCommand); + return HWFault; + } + sscanf(result, "%d", &status); + free(tclCommand); + return status; +} + /*-----------------------------------------------------------------------*/ -static int TclSetPar(void *self, SConnection *pCon, char *name, float newValue){ - - int status; - const char *result = NULL; +static int TclSetPar(void *self, SConnection * pCon, char *name, + float newValue) +{ +/*TODO Skip functions in driveable interface ie "run" etc. */ + int status; + char *result = NULL, pBuffer[512]; TCLDriv *pDriv = (TCLDriv *) self; @@ -323,38 +367,48 @@ static int TclSetPar(void *self, SConnection *pCon, char *name, float newValue){ pDriv->fUpper = newValue; return 1; } else if (strcmp(name, HARDLOWERLIM) == 0) { - pDriv->fLower = newValue; - return 1; + pDriv->fLower = newValue; + return 1; } else if (strcmp(name, ERRORCODE) == 0) { - pDriv->errorCode = (int)newValue; - return 1; - } else if (strcmp(name, LONG_NAME) == 0) { + pDriv->errorCode = (int) newValue; + return 1; + } else if (strcmp(name, "debug") == 0) { + pDriv->debug = (int) newValue; + return 1; +/* } else if (strcmp(name, LONG_NAME) == 0) { strncpy(pDriv->long_name, &newValue, 255); - return 1; + return 1;*/ } else { - char *tclCommand = (char *)calloc(1024, sizeof(char)); + char *tclCommand = (char *) calloc(1024, sizeof(char)); if (StringDictExists(pDriv->mappings, name)) { - if (!buildStandardCommandPart(pDriv, name, tclCommand, 1023)){ - pDriv->errorCode = FUNCNOTFOUND; + if (!buildStandardCommandPart(pDriv, name, tclCommand, 1023)) { + pDriv->errorCode = FUNCNOTFOUND; free(tclCommand); return HWFault; } - char *tclCommandPara = (char *)calloc(1024, sizeof(char)); + char *tclCommandPara = (char *) calloc(1024, sizeof(char)); sprintf(tclCommandPara, "%s %f", tclCommand, newValue); - status = Tcl_Eval(pServ->pSics->pTcl,tclCommandPara); + + if (pDriv->debug) + logTclCall(pDriv, name, tclCommand); + + status = Tcl_Eval(pServ->pSics->pTcl, tclCommandPara); result = Tcl_GetStringResult(pServ->pSics->pTcl); - if (result == NULL){ - pDriv->errorCode = NOTCLRESULT; + if (result == NULL) { + pDriv->errorCode = NOTCLRESULT; free(tclCommand); free(tclCommandPara);; return HWFault; } - if (status != TCL_OK){ - pDriv->errorCode = TCLERROR; - strncpy(pDriv->tclError,result,1023); + if (status != TCL_OK) { + pDriv->errorCode = TCLERROR; + strncpy(pDriv->tclError, result, 1023); free(tclCommand); free(tclCommandPara);; return HWFault; + } else { + snprintf(pBuffer, 511, "%s.%s = %s", pDriv->motName, name, result); + SCWrite(pCon, pBuffer, eValue); } free(tclCommand); free(tclCommandPara);; @@ -368,51 +422,11 @@ static int TclSetPar(void *self, SConnection *pCon, char *name, float newValue){ } } -static int TclListPar(void *self, char *motorname, SConnection *pCon) { - - SDE sVal; - int iRet; - char pBueffel[512]; - char *funcText[] = {"getpos", - "run", - "status", - "halt", - "geterror", - "fixit", - NULL}; - TCLDriv *pDriv = (TCLDriv *)self; - - iRet = LLDnodePtr2First(pDriv->mappings->iList); - while(iRet != 0){ - LLDnodeDataTo(pDriv->mappings->iList, &sVal); - int count=0, flag=0; - while(funcText[count]!=NULL && flag==0) { - if(strcmp(sVal.name,funcText[count]) == 0) - flag = 1; - count++; - } - if(flag==0) { - int ret; - float value; - ret = TclGetPar(self, sVal.name, &value); - if (ret != OKOK) { - return ret; - } else { - snprintf(pBueffel,511,"%s.%s = %f",motorname,sVal.name,value); - SCWrite(pCon,pBueffel,eValue); - } - } - iRet = LLDnodePtr2Next(pDriv->mappings->iList); - } - - return OKOK; -} - - /*-----------------------------------------------------------------------*/ -int TclGetPar(void *self, char *name, float *value) { +int TclGetPar(void *self, char *name, float *value) +{ - int status; + int status; const char *result = NULL; TCLDriv *pDriv = (TCLDriv *) self; @@ -420,36 +434,42 @@ int TclGetPar(void *self, char *name, float *value) { assert(self); if (strcmp(name, ERRORCODE) == 0) { - *value = (float)pDriv->errorCode; + *value = (float) pDriv->errorCode; return OKOK; } else if (strcmp(name, HARDUPPERLIM) == 0) { - *value = (float)pDriv->fUpper; + *value = (float) pDriv->fUpper; return OKOK; } else if (strcmp(name, HARDLOWERLIM) == 0) { - *value = (float)pDriv->fLower; + *value = (float) pDriv->fLower; + return OKOK; + } else if (strcmp(name, "debug") == 0) { + *value = (float) pDriv->debug; return OKOK; } else { - char *tclCommand = (char *)calloc(1024, sizeof(char)); + char *tclCommand = (char *) calloc(1024, sizeof(char)); if (StringDictExists(pDriv->mappings, name)) { - if(!buildStandardCommandPart(pDriv, name, tclCommand, 1023)){ - pDriv->errorCode = FUNCNOTFOUND; + if (!buildStandardCommandPart(pDriv, name, tclCommand, 1023)) { + pDriv->errorCode = FUNCNOTFOUND; free(tclCommand); return HWFault; } - status = Tcl_Eval(pServ->pSics->pTcl,tclCommand); - result = Tcl_GetStringResult(pServ->pSics->pTcl); - if(result == NULL){ - pDriv->errorCode = NOTCLRESULT; + if (pDriv->debug) + logTclCall(pDriv, name, tclCommand); + + status = Tcl_Eval(pServ->pSics->pTcl, tclCommand); + result = Tcl_GetStringResult(pServ->pSics->pTcl); + if (result == NULL) { + pDriv->errorCode = NOTCLRESULT; free(tclCommand); return HWFault; } - if(status != TCL_OK){ - pDriv->errorCode = TCLERROR; - strncpy(pDriv->tclError,result,1023); + if (status != TCL_OK) { + pDriv->errorCode = TCLERROR; + strncpy(pDriv->tclError, result, 1023); free(tclCommand); return HWFault; - } - sscanf(result,"%f", value); + } + sscanf(result, "%f", value); free(tclCommand); return OKOK; } else { @@ -461,114 +481,140 @@ int TclGetPar(void *self, char *name, float *value) { return OKOK; } } + +/* + * Functions which include hdb_, imot_, and get_ are treated specially. + * hdb_, Parameter will be added to hdb tree. + * imot_, Motor interface function, eg run, status. + * get_, Tcl code will be evaluated when "mot list" is called. + * WARNING: Parameters prefixed with hdb_ will be executed when any of the + * parameters in the hdb tree are updated, for instance if the + * softzero is changed. + */ +void TclListPar(void *self, char *motorname, SConnection * pCon) +{ + char pBueffel[512]; + char motParVal[256]; + float value; + const char *motPar=NULL; + TCLDriv *pDriv = (TCLDriv *) self; + int pos = 0, imot; + + + snprintf(pBueffel, 511, "%s.debug = %d", motorname, pDriv->debug); + SCWrite(pCon, pBueffel, eValue); + while ( (motPar = StringDictGetNext(pDriv->mappings,motParVal,256)) != NULL ) { + imot = 0; + pBueffel[0] = '\0'; + /* sicshipadaba sets motorname="test" when constructing hdb tree */ + if (strcmp(motorname, "test.") == 0 && strstr(motParVal, "hdb_") == NULL) + continue; + + if (strstr(motParVal, "imot_")) + imot = 1; + if (imot && !pDriv->debug) + continue; + + pos = snprintf(pBueffel, 511, "%s.%s", motorname, motPar); + if (pDriv->debug) + pos += snprintf(&pBueffel[pos], 511, "->[%s]", motParVal); + + if (strstr(motParVal, "get_")) { + TclGetPar(self, (char *)motPar, &value); + snprintf(&pBueffel[pos], 511, " = %f", value); + } else if (imot) + snprintf(&pBueffel[pos], 511, " (imot)"); + else + snprintf(&pBueffel[pos], 511, " (command)"); + + if (pBueffel[0] != '\0') + SCWrite(pCon, pBueffel, eValue); + } +} + /*---------------------------------------------------------------------------*/ - void KillTCL(void *pData) - { - TCLDriv *pDriv = (TCLDriv *) pData; +void KillTCL(void *pData) +{ + TCLDriv *pDriv = (TCLDriv *) pData; + + if (pDriv != NULL) { + DeleteStringDict(pDriv->mappings); + } + + return; +} - if(pDriv != NULL){ - DeleteStringDict(pDriv->mappings); - } - - return; - } /*-------------------------------------------------------------------------*/ -static int assignMappings(TCLDriv *pDriv, SConnection *pCon, char *arrayName){ +static int assignMappings(TCLDriv * pDriv, SConnection * pCon, + char *arrayName) +{ + const char *funcName = NULL; + char *funcText[] = { "getpos", + "run", + "status", + "halt", + "geterror", + "fixit", + NULL + }; + char error[256]; + int count = 0; - if (*arrayName==NULL) { - return OKOK; - } else { - unsigned char ps=0; - char *pch; - char *funcName = (char *)calloc(1024, sizeof(char)); + char **argv; + int i, code, argc; - pch = strtok(arrayName, "{}"); - while (pch != NULL) { - int c=0; - while(pch[c]==' ' && cmappings,funcName, newStr); - ps = 0; - } - free(newStr); - pch = strtok (NULL, "{}"); - } - free(funcName); + code = Tcl_SplitList(pServ->pSics->pTcl, arrayName, &argc, &argv); + for (i=0; i < argc; i += 2) { + StringDictAddPair(pDriv->mappings, argv[i], (char *) argv[i+1]); } + Tcl_Free((char *) argv); return 1; -} +} + /*--------------------------------------------------------------------------*/ - MotorDriver *CreateTclMotDriv(SConnection *pCon, int argc, char *argv[]) - { - TCLDriv *pDriv = NULL; - - assert(pCon); - - if(argc < 4) { - SCWrite(pCon,"ERROR: not enough arguments to initilaize Tcl-driver",eError); - return NULL; - } +MotorDriver *CreateTclMotDriv(SConnection * pCon, int argc, char *argv[]) +{ + TCLDriv *pDriv = NULL; - pDriv = (TCLDriv *)malloc(sizeof(TCLDriv)); - if(!pDriv){ - SCWrite(pCon,"Error allocating memory in TclMotor",eError); - return NULL; - } - memset(pDriv,0,sizeof(TCLDriv)); - pDriv->mappings = CreateStringDict(); - if(pDriv->mappings == NULL){ - SCWrite(pCon,"Error allocating memory in TclMotor",eError); - free(pDriv); - return NULL; - } - if(assignMappings(pDriv,pCon,argv[3]) != 1){ - DeleteStringDict(pDriv->mappings); - free(pDriv); - return NULL; - } + assert(pCon); - pDriv->name = strdup("Tcl-Driver"); - strncpy(pDriv->motName, argv[1], 131); - pDriv->GetPosition = GetTclPos; - pDriv->RunTo = TclRun; - pDriv->GetStatus = TclGetStatus; - pDriv->GetError = TclGetError; - pDriv->TryAndFixIt = TclTryAndFixIt; - pDriv->SetDriverPar = TclSetPar; - pDriv->GetDriverPar = TclGetPar; - pDriv->ListDriverPar = TclListPar; - pDriv->Halt = TclHalt; - pDriv->KillPrivate = KillTCL; - - return (MotorDriver *)pDriv; + if (argc < 4) { + SCWrite(pCon, "ERROR: not enough arguments to initilaize Tcl-driver", + eError); + return NULL; } + pDriv = (TCLDriv *) malloc(sizeof(TCLDriv)); + if (!pDriv) { + SCWrite(pCon, "Error allocating memory in TclMotor", eError); + return NULL; + } + memset(pDriv, 0, sizeof(TCLDriv)); + pDriv->debug = 0; + pDriv->mappings = CreateStringDict(); + if (pDriv->mappings == NULL) { + SCWrite(pCon, "Error allocating memory in TclMotor", eError); + free(pDriv); + return NULL; + } + if (assignMappings(pDriv, pCon, argv[3]) != 1) { + DeleteStringDict(pDriv->mappings); + free(pDriv); + return NULL; + } + pDriv->name = strdup("Tcl-Driver"); + strncpy(pDriv->motName, argv[1], 131); + pDriv->GetPosition = GetTclPos; + pDriv->RunTo = TclRun; + pDriv->GetStatus = TclGetStatus; + pDriv->GetError = TclGetError; + pDriv->TryAndFixIt = TclTryAndFixIt; + pDriv->SetDriverPar = TclSetPar; + pDriv->GetDriverPar = TclGetPar; + pDriv->ListDriverPar = TclListPar; + pDriv->Halt = TclHalt; + pDriv->KillPrivate = KillTCL; - - - - - - - + return (MotorDriver *) pDriv; +} diff --git a/site_ansto/ansto_tclmotdriv.h b/site_ansto/ansto_tclmotdriv.h new file mode 100644 index 00000000..ba83d41a --- /dev/null +++ b/site_ansto/ansto_tclmotdriv.h @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------- + This is a motor driver which is implemented in Tcl. This means + this code is only a wrapper which calls Tcl functions to do the + actual work. + + copyright: see file COPYRIGHT + + Mark Koennecke, December 2005 + --------------------------------------------------------------------------*/ +#ifndef TCLMOTDRIV +#define TCLMOTDRIV +#include "stringdict.h" + +typedef struct ___TclDriv { + /* general motor driver interface + fields. REQUIRED! + */ + float fUpper; /* upper limit */ + float fLower; /* lower limit */ + char *name; + int (*GetPosition) (void *self, float *fPos); + int (*RunTo) (void *self, float fNewVal); + int (*GetStatus) (void *self); + void (*GetError) (void *self, int *iCode, char *buffer, int iBufLen); + int (*TryAndFixIt) (void *self, int iError, float fNew); + int (*Halt) (void *self); + int (*GetDriverPar) (void *self, char *name, float *value); + int (*SetDriverPar) (void *self, SConnection * pCon, + char *name, float newValue); + void (*ListDriverPar) (void *self, char *motorName, SConnection * pCon); + void (*KillPrivate) (void *self); + + /* Tcl specific fields */ + pStringDict mappings; + int debug; + int errorCode; + char tclError[1024]; + char motName[132]; +} TCLDriv; + +MotorDriver *CreateTclMotDriv(SConnection * pCon, int argc, char *argv[]); + +#endif diff --git a/site_ansto/make_gen_variables b/site_ansto/make_gen_variables index 813905df..825be52b 100644 --- a/site_ansto/make_gen_variables +++ b/site_ansto/make_gen_variables @@ -22,7 +22,7 @@ SOBJ = alias.o anticollider.o arrayutil.o ascon.o asyncprotocol.o asyncqueue.o a sicvar.o sig_die.o simchop.o simev.o simidx.o simindex.o sinfox.o singlebi.o singlediff.o singlenb.o singlebinb.o singletas.o singlex.o splitter.o s_rnge.o statemon.o \ statistics.o statusfile.o status.o stdscan.o stptok.o stringdict.o strlutil.o strrepl.o \ syncedprot.o synchronize.o tasdrive.o task.o tasscanub.o tasublib.o tasub.o tcldrivable.o \ - tclev.o tclintimpl.o tclmotdriv.o telnet.o testprot.o token.o trace.o trigd.o trim.o ubcalc.o \ + tclev.o tclintimpl.o telnet.o testprot.o token.o trace.o trigd.o trim.o ubcalc.o \ ubfour.o udpquieck.o uselect.o userscan.o uubuffer.o varlog.o vector.o velosec.o wwildcard.o \ xytable.o