- Added Sycamore protocol and command context to SICS
- Added sinfo to SICS - Added driver for TCP/IP Astrium velocity selector - Added driver for TCP/IP Astrium chopper controller SKIPPED: psi/amor2t.c psi/amorstat.c psi/dornier2.c psi/ecb.c psi/el734hp.c psi/fowrite.c psi/libpsi.a psi/make_gen psi/nextrics.c psi/pardef.c psi/pimotor.c psi/pipiezo.c psi/polterwrite.c psi/psi.c psi/scontroller.c psi/serial.c psi/tasinit.c psi/tasscan.c psi/tcpdocho.c psi/tcpdornier.c psi/tricssupport.c psi/velodornier.c
This commit is contained in:
305
SCinter.c
305
SCinter.c
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
Implementation file for the SICS-interpreter.
|
Implementation file for the SICS-interpreter.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Mark Koennecke, November 1996
|
Mark Koennecke, November 1996
|
||||||
|
|
||||||
Made ListObjects more intelligent: list objects according to interface etc.
|
Made ListObjects more intelligent: list objects according to interface etc.
|
||||||
@ -42,6 +40,16 @@
|
|||||||
M. Zolliker, Sept 2000, introduced formal aliases, modifications marked M.Z
|
M. Zolliker, Sept 2000, introduced formal aliases, modifications marked M.Z
|
||||||
Mark Koennecke, August 2001, modified SicsWriteStatus to write motor
|
Mark Koennecke, August 2001, modified SicsWriteStatus to write motor
|
||||||
positions on demand.
|
positions on demand.
|
||||||
|
|
||||||
|
Made ListObjects moe intelligent: list objects according to interface etc.
|
||||||
|
Mark Koennecke, December 2003
|
||||||
|
|
||||||
|
Extended 'dir' command (function ListObjects) to list via typename from
|
||||||
|
object descriptor. For completeness, added function PrintAllTypes.
|
||||||
|
Paul Hathaway, May 2004
|
||||||
|
|
||||||
|
Modified printXXX functions to fix duplicate write of last buffer line.
|
||||||
|
Paul Hathaway, May 2004
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -61,6 +69,15 @@
|
|||||||
/* M.Z. */
|
/* M.Z. */
|
||||||
#include "definealias.h"
|
#include "definealias.h"
|
||||||
|
|
||||||
|
/* pvh */
|
||||||
|
#include "lld_str.h"
|
||||||
|
static void printList(SConnection *pCon, int listID);
|
||||||
|
static void freeList(int listID);
|
||||||
|
int compareStringNode(void *pStr1, void **ppStr2);
|
||||||
|
|
||||||
|
#define MAXLEN 256
|
||||||
|
#define MAXPAR 100
|
||||||
|
#define MAXBUF 128
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
SicsInterp *InitInterp(void)
|
SicsInterp *InitInterp(void)
|
||||||
@ -219,22 +236,11 @@
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAXLEN 256
|
||||||
/*------------------------------------------------------------------------*/
|
#define MAXCOM 50
|
||||||
void RemoveStartupCommands(void)
|
extern char *stptok(char *s, char *tok, unsigned int toklen, char *brk);
|
||||||
{
|
extern char *SkipSpace(char *pPtr);
|
||||||
CommandList *pCurrent, *pNext;
|
/*-----------------------------------------------------------------------*/
|
||||||
pCurrent = pServ->pSics->pCList;
|
|
||||||
while(pCurrent)
|
|
||||||
{
|
|
||||||
pNext = pCurrent->pNext;
|
|
||||||
if (pCurrent->startupOnly) {
|
|
||||||
RemoveCommand(pServ->pSics, pCurrent->pName);
|
|
||||||
}
|
|
||||||
pCurrent = pNext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
int InterpExecute(SicsInterp *self,SConnection *pCon, char *pText)
|
int InterpExecute(SicsInterp *self,SConnection *pCon, char *pText)
|
||||||
{
|
{
|
||||||
int iCount = 0;
|
int iCount = 0;
|
||||||
@ -275,6 +281,7 @@
|
|||||||
iRet = 1;
|
iRet = 1;
|
||||||
goto deleteArgv;
|
goto deleteArgv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(argv[0] == NULL)
|
if(argv[0] == NULL)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ERROR: failed to parse command",eError);
|
SCWrite(pCon,"ERROR: failed to parse command",eError);
|
||||||
@ -298,7 +305,13 @@
|
|||||||
self->eOut = eStatus;
|
self->eOut = eStatus;
|
||||||
Tcl_ResetResult((Tcl_Interp *)self->pTcl);
|
Tcl_ResetResult((Tcl_Interp *)self->pTcl);
|
||||||
MacroPush(pCon);
|
MacroPush(pCon);
|
||||||
|
SCWrite(pCon, "", eStart);
|
||||||
|
pCon->conStatus = 0;
|
||||||
iRet = pCommand->OFunc(pCon, self, pCommand->pData, argc, argv);
|
iRet = pCommand->OFunc(pCon, self, pCommand->pData, argc, argv);
|
||||||
|
/* If a task is registered with the dev exec then conStatus is HWBusy*/
|
||||||
|
if (pCon->conStatus != HWBusy) {
|
||||||
|
SCWrite(pCon,"",eFinish);
|
||||||
|
}
|
||||||
MacroPop();
|
MacroPop();
|
||||||
|
|
||||||
deleteArgv:
|
deleteArgv:
|
||||||
@ -519,6 +532,74 @@ static void printAll(SicsInterp *pSics, SConnection *pCon)
|
|||||||
SCWrite(pCon,pBueffel,eStatus);
|
SCWrite(pCon,pBueffel,eStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
printAllTypes prints the list of types of objects instantiated on the
|
||||||
|
CommandList.
|
||||||
|
iFiltered=0 gives all objects including interpreter command objects
|
||||||
|
iFiltered=1 gives types where object name is not the same as its type
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
static void printAllTypes(SicsInterp *pSics, SConnection *pCon, int iFiltered)
|
||||||
|
{
|
||||||
|
CommandList *pCurrent = NULL;
|
||||||
|
char pBueffel[256];
|
||||||
|
char pName_lc[256];
|
||||||
|
char pType_lc[256];
|
||||||
|
char *pType;
|
||||||
|
Dummy *pTest;
|
||||||
|
int typeListID;
|
||||||
|
|
||||||
|
assert(pSics);
|
||||||
|
assert(pCon);
|
||||||
|
|
||||||
|
pBueffel[0] = '\0';
|
||||||
|
|
||||||
|
typeListID = LLDstringCreate();
|
||||||
|
if(-1==typeListID)
|
||||||
|
{
|
||||||
|
strcpy(pBueffel,"ERROR: Cannot generate list of object types\r\n");
|
||||||
|
SCWrite(pCon,pBueffel,eStatus);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pCurrent = pSics->pCList;
|
||||||
|
while(pCurrent)
|
||||||
|
{
|
||||||
|
if(NULL != pCurrent->pData)
|
||||||
|
{
|
||||||
|
pTest = (pDummy)pCurrent->pData;
|
||||||
|
if(NULL != pTest->pDescriptor)
|
||||||
|
{
|
||||||
|
pType = pTest->pDescriptor->name;
|
||||||
|
strcpy(pType_lc,pType);
|
||||||
|
strtolower(pType_lc);
|
||||||
|
|
||||||
|
LLDnodePtr2First(typeListID);
|
||||||
|
|
||||||
|
/* int LLDnodeFind( int List, CompFunPtr Compare, void * DataPtr ); */
|
||||||
|
/* */
|
||||||
|
/* Find *DataPtr in the List using the *Compare function. */
|
||||||
|
/* Returns the return value of *Compare. */
|
||||||
|
/* 0 == equal == found. */
|
||||||
|
/* non-zero == not found. Current node is set to found node. */
|
||||||
|
/* Returns 2 for an empty list. */
|
||||||
|
/* NB: First checked node is current node, then search to end of list*/
|
||||||
|
|
||||||
|
if(0!=LLDnodeFind(typeListID,compareStringNode,(void *)pType))
|
||||||
|
{ /* empty list or 'typename' not found */
|
||||||
|
strcpy(pName_lc, pCurrent->pName);
|
||||||
|
strtolower(pName_lc);
|
||||||
|
if((0==iFiltered)||((1==iFiltered)&&(0!=strcmp(pType_lc,pName_lc))))
|
||||||
|
{ /*ie Add if unfiltered or pass filter(name!=typename) */
|
||||||
|
LLDstringAdd(typeListID,pType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pCurrent = pCurrent->pNext;
|
||||||
|
}
|
||||||
|
printList(pCon,typeListID);
|
||||||
|
freeList(typeListID);
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------------------
|
/*-----------------------------------------------------------------------
|
||||||
printInterface prints only those objects which implement an interface
|
printInterface prints only those objects which implement an interface
|
||||||
as specified bi the id given
|
as specified bi the id given
|
||||||
@ -625,9 +706,9 @@ static void printMatch(SicsInterp *pSics, SConnection *pCon, char *mask)
|
|||||||
SCWrite(pCon,pBueffel,eStatus);
|
SCWrite(pCon,pBueffel,eStatus);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------
|
/*-----------------------------------------------------------------------
|
||||||
printType prints only those objects which match the type given
|
printType prints only those objects whose descriptor match the type given
|
||||||
-------------------------------------------------------------------------*/
|
-------------------------------------------------------------------------*/
|
||||||
static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
|
static void printType(SicsInterp *pSics, SConnection *pCon, char *typeName)
|
||||||
{
|
{
|
||||||
CommandList *pCurrent;
|
CommandList *pCurrent;
|
||||||
Tcl_DString txt;
|
Tcl_DString txt;
|
||||||
@ -644,7 +725,7 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
|
|||||||
{
|
{
|
||||||
if(pCurrent->pData != NULL)
|
if(pCurrent->pData != NULL)
|
||||||
{
|
{
|
||||||
if(iHasType(pCurrent->pData,type))
|
if(iHasType(pCurrent->pData,typeName))
|
||||||
{
|
{
|
||||||
if(iNum == 0)
|
if(iNum == 0)
|
||||||
{
|
{
|
||||||
@ -680,6 +761,8 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
|
|||||||
int ListObjects(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int ListObjects(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
char pType[256];
|
||||||
|
int i;
|
||||||
|
|
||||||
if(argc < 2)
|
if(argc < 2)
|
||||||
{
|
{
|
||||||
@ -701,6 +784,13 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
|
|||||||
printType(pSics,pCon,"Motor");
|
printType(pSics,pCon,"Motor");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/* Start Mod by Paul Hathaway May 2004 */
|
||||||
|
if(0 == strcmp(argv[1],"types"))
|
||||||
|
{
|
||||||
|
printAllTypes(pSics,pCon,1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* End Mod by Paul Hathaway May 2004*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -745,6 +835,33 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
|
|||||||
printMatch(pSics,pCon,argv[2]);
|
printMatch(pSics,pCon,argv[2]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Start Mod by Paul Hathaway May 2004 */
|
||||||
|
/*
|
||||||
|
* type-based dir
|
||||||
|
*/
|
||||||
|
if(0 == strcmp(argv[1],"type"))
|
||||||
|
{
|
||||||
|
if(0==strcmp(argv[2],"*"))
|
||||||
|
{
|
||||||
|
printAllTypes(pSics,pCon,0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
strcpy(pType,argv[2]);
|
||||||
|
/* Cater for multi-word types eg 'Environment Monitor' */
|
||||||
|
if(argc > 3)
|
||||||
|
{
|
||||||
|
for(i=3;i<argc;i++)
|
||||||
|
{
|
||||||
|
strcat(pType," ");
|
||||||
|
strcat(pType,argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printType(pSics,pCon,pType);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* End Mod by Paul Hathaway May 2004*/
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
@ -848,3 +965,149 @@ void *FindDrivable(SicsInterp *pSics, char *name){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* printList: Print contents of an LLDstring list
|
||||||
|
* Envisaged to be used by other extensions/refactoring utilising dynamic
|
||||||
|
* linked list module. May extend toallow different output formats
|
||||||
|
* (eg multi/single column) via switches
|
||||||
|
*/
|
||||||
|
static void printList(SConnection *pCon, int listID)
|
||||||
|
{
|
||||||
|
char pBueffel[MAXBUF];
|
||||||
|
int retCode;
|
||||||
|
|
||||||
|
if(0!=LLDnodePtr2First(listID))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
retCode = LLDstringData(listID,NULL);
|
||||||
|
if ((MAXBUF-3) > retCode) {
|
||||||
|
retCode = LLDstringData(listID,pBueffel);
|
||||||
|
strcat(pBueffel,"\r\n");
|
||||||
|
SCWrite(pCon,pBueffel,eStatus);
|
||||||
|
}
|
||||||
|
} while(0!=LLDnodePtr2Next(listID));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static void freeList(int listID)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
LLDstringDelete(listID);
|
||||||
|
} while(0!=LLDnodePtr2First(listID));
|
||||||
|
LLDdelete(listID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* compareStringNode wraps strcmp for use in findNode(LLD module) calls */
|
||||||
|
int compareStringNode(void *pStr1, void **ppStr2)
|
||||||
|
{
|
||||||
|
return strcmp((char *)pStr1,(char *)(*ppStr2));
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
void RemoveStartupCommands(void)
|
||||||
|
{
|
||||||
|
CommandList *pCurrent, *pNext;
|
||||||
|
pCurrent = pServ->pSics->pCList;
|
||||||
|
while(pCurrent)
|
||||||
|
{
|
||||||
|
pNext = pCurrent->pNext;
|
||||||
|
if (pCurrent->startupOnly) {
|
||||||
|
RemoveCommand(pServ->pSics, pCurrent->pName);
|
||||||
|
}
|
||||||
|
pCurrent = pNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
static int handleGet(SConnection *pCon,SicsInterp *pSics, int argc,
|
||||||
|
char *argv[]){
|
||||||
|
CommandList *obj = NULL;
|
||||||
|
pDummy pDum = NULL;
|
||||||
|
char pBueffel[512];
|
||||||
|
char *pPtr = NULL;
|
||||||
|
|
||||||
|
if(argc < 4){
|
||||||
|
SCWrite(pCon,"ERROR: Insufficient number of arguments to SicsAtt get",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj = FindCommand(pSics,argv[2]);
|
||||||
|
if(obj == NULL){
|
||||||
|
snprintf(pBueffel,511,"ERROR: object %s not found",argv[2]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pDum = obj->pData;
|
||||||
|
if(pDum == NULL){
|
||||||
|
snprintf(pBueffel,511,"%s has no data, is command", argv[2]);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
strtolower(argv[3]);
|
||||||
|
if(strcmp(argv[3],"type") == 0){
|
||||||
|
snprintf(pBueffel,511, "%s.type = %s", argv[2], pDum->pDescriptor->name);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
pPtr = GetDescriptorKey(pDum->pDescriptor, argv[3]);
|
||||||
|
if(pPtr == NULL){
|
||||||
|
snprintf(pBueffel,511,"%s.%s = Undefined", argv[0], argv[3]);
|
||||||
|
} else {
|
||||||
|
snprintf(pBueffel,511,"%s.%s = %s", argv[0], argv[3], pPtr);
|
||||||
|
}
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
static int handleSet(SConnection *pCon,SicsInterp *pSics, int argc,
|
||||||
|
char *argv[]){
|
||||||
|
CommandList *obj = NULL;
|
||||||
|
pDummy pDum = NULL;
|
||||||
|
char pBueffel[512];
|
||||||
|
char *pPtr = NULL;
|
||||||
|
|
||||||
|
if(argc < 5){
|
||||||
|
SCWrite(pCon,"ERROR: Insufficient number of arguments to SicsAtt set",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj = FindCommand(pSics,argv[2]);
|
||||||
|
if(obj == NULL){
|
||||||
|
snprintf(pBueffel,511,"ERROR: object %s not found",argv[2]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pDum = obj->pData;
|
||||||
|
if(pDum == NULL){
|
||||||
|
snprintf(pBueffel,511,"%s has no data, is command", argv[2]);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
strtolower(argv[3]);
|
||||||
|
pDum->pDescriptor->pKeys = IFSetOption(pDum->pDescriptor->pKeys, argv[3], argv[4]);
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
int SicsAtt(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]){
|
||||||
|
CommandList *current = NULL;
|
||||||
|
pDummy pDum = NULL;
|
||||||
|
|
||||||
|
if(argc < 2){
|
||||||
|
SCWrite(pCon,"ERROR: insufficient number of argumens to SicsAtt",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
strtolower(argv[1]);
|
||||||
|
if(strcmp(argv[1],"get") == 0) {
|
||||||
|
return handleGet(pCon, pSics, argc, argv);
|
||||||
|
} else if(strcmp(argv[1],"set") == 0){
|
||||||
|
return handleSet(pCon,pSics,argc, argv);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -87,7 +87,6 @@ typedef struct __SINTER
|
|||||||
If the command is found, 1 is returned on success, 0 on failure in
|
If the command is found, 1 is returned on success, 0 on failure in
|
||||||
the command.
|
the command.
|
||||||
----------------------------------------------------------------------------*/
|
----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
CommandList *FindCommand(SicsInterp *pInterp, char *name);
|
CommandList *FindCommand(SicsInterp *pInterp, char *name);
|
||||||
/*
|
/*
|
||||||
Searches the Interpreters pInterp command list for a command
|
Searches the Interpreters pInterp command list for a command
|
||||||
|
@ -46,6 +46,9 @@ typedef enum {
|
|||||||
eInError,
|
eInError,
|
||||||
eStatus,
|
eStatus,
|
||||||
eValue,
|
eValue,
|
||||||
|
eStart,
|
||||||
|
eFinish,
|
||||||
|
eEvent,
|
||||||
eWarning,
|
eWarning,
|
||||||
eError
|
eError
|
||||||
} OutCode;
|
} OutCode;
|
||||||
|
12
callback.c
12
callback.c
@ -64,6 +64,7 @@
|
|||||||
void *pUserData;
|
void *pUserData;
|
||||||
KillFuncIT pKill;
|
KillFuncIT pKill;
|
||||||
int iEvent;
|
int iEvent;
|
||||||
|
commandContext comCon;
|
||||||
} CallBackItem, *pCallBackItem;
|
} CallBackItem, *pCallBackItem;
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
static int CheckPointer(pICallBack self)
|
static int CheckPointer(pICallBack self)
|
||||||
@ -140,7 +141,7 @@
|
|||||||
LLDnodeDataTo(self->iList,&sItem);
|
LLDnodeDataTo(self->iList,&sItem);
|
||||||
if(sItem.iEvent == iEvent)
|
if(sItem.iEvent == iEvent)
|
||||||
{
|
{
|
||||||
iRet = sItem.pFunc(iEvent, pEventData,sItem.pUserData);
|
iRet = sItem.pFunc(iEvent, pEventData,sItem.pUserData,sItem.comCon);
|
||||||
if(!iRet)
|
if(!iRet)
|
||||||
{
|
{
|
||||||
iResult = 0;
|
iResult = 0;
|
||||||
@ -153,7 +154,7 @@
|
|||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static long lCount = 1L;
|
static long lCount = 1L;
|
||||||
|
|
||||||
long RegisterCallback(pICallBack self, int iEvent,
|
long RegisterCallback(pICallBack self, commandContext comCon, int iEvent,
|
||||||
SICSCallBack pFunc,
|
SICSCallBack pFunc,
|
||||||
void *pUserData, KillFunc pKFunc)
|
void *pUserData, KillFunc pKFunc)
|
||||||
{
|
{
|
||||||
@ -170,6 +171,7 @@
|
|||||||
sItem.iEvent = iEvent;
|
sItem.iEvent = iEvent;
|
||||||
sItem.pUserData = pUserData;
|
sItem.pUserData = pUserData;
|
||||||
sItem.pKill = pKFunc;
|
sItem.pKill = pKFunc;
|
||||||
|
sItem.comCon = comCon;
|
||||||
|
|
||||||
LLDnodeAppendFrom(self->iList,&sItem);
|
LLDnodeAppendFrom(self->iList,&sItem);
|
||||||
return sItem.iID;
|
return sItem.iID;
|
||||||
@ -244,7 +246,8 @@ static int CallbackWrite(SConnection *pCon,char *message, int outCode)
|
|||||||
/*-----------------------------------------------------------------------
|
/*-----------------------------------------------------------------------
|
||||||
the actual callback function invoking the script
|
the actual callback function invoking the script
|
||||||
------------------------------------------------------------------------*/
|
------------------------------------------------------------------------*/
|
||||||
static int ScriptCallback(int iEvent, void *pEventData, void *pUserData)
|
static int ScriptCallback(int iEvent, void *pEventData, void *pUserData,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
SConnection *pCon = NULL;
|
SConnection *pCon = NULL;
|
||||||
Tcl_Interp *pTcl;
|
Tcl_Interp *pTcl;
|
||||||
@ -332,7 +335,8 @@ int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Arg2Text(argc-4,&argv[4],pBuffer,131);
|
Arg2Text(argc-4,&argv[4],pBuffer,131);
|
||||||
lID = RegisterCallback(pCall,iEvent,ScriptCallback,
|
lID = RegisterCallback(pCall,SCGetContext(pCon),
|
||||||
|
iEvent,ScriptCallback,
|
||||||
strdup(pBuffer),free);
|
strdup(pBuffer),free);
|
||||||
sprintf(pBuffer,"callback = %ld", lID);
|
sprintf(pBuffer,"callback = %ld", lID);
|
||||||
SCWrite(pCon,pBuffer,eValue);
|
SCWrite(pCon,pBuffer,eValue);
|
||||||
|
16
commandcontext.h
Normal file
16
commandcontext.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*-------------------------------------------------
|
||||||
|
This file holds the command context structure which
|
||||||
|
is needed to make the sycamore protocol work.
|
||||||
|
|
||||||
|
Mark Koennecke, December 2005
|
||||||
|
-------------------------------------------------*/
|
||||||
|
#ifndef SICSCOMCONTEXT
|
||||||
|
#define SICSCOMCONTEXT
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
int transID;
|
||||||
|
char deviceID[256];
|
||||||
|
}commandContext, *pCommandContext;
|
||||||
|
#define SCDEVIDLEN 256
|
||||||
|
|
||||||
|
#endif
|
@ -19,8 +19,12 @@
|
|||||||
|
|
||||||
int ListObjects(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int ListObjects(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
lists all avialable objects. Realised in Scinter.c
|
lists all avialable objects. Realised in Scinter.c
|
||||||
*/
|
*/
|
||||||
|
int SicsAtt(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
/*
|
||||||
|
handling of SICS object attributes. In SCinter.c
|
||||||
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
128
conman.c
128
conman.c
@ -88,7 +88,6 @@ extern pServer pServ;
|
|||||||
|
|
||||||
/*------------- a number for generating automatic names --------------------*/
|
/*------------- a number for generating automatic names --------------------*/
|
||||||
static int iName = 0;
|
static int iName = 0;
|
||||||
static int SCNormalWrite(SConnection *self, char *buffer, int iOut);
|
|
||||||
static SConnection *freeConnections = NULL;
|
static SConnection *freeConnections = NULL;
|
||||||
static long lastIdent = 0;
|
static long lastIdent = 0;
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
@ -183,6 +182,12 @@ extern pServer pServ;
|
|||||||
pRes->pFiles[i] = NULL;
|
pRes->pFiles[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* initialise context variables */
|
||||||
|
pRes->iCmdCtr = 0;
|
||||||
|
pRes->conEventType=-1;
|
||||||
|
pRes->conStatus=-1;
|
||||||
|
pRes->contextStack = LLDcreate(sizeof(commandContext));
|
||||||
|
|
||||||
/* install command */
|
/* install command */
|
||||||
AddCommand(pSics, ConName(pRes->ident), ConSicsAction, NULL,pRes);
|
AddCommand(pSics, ConName(pRes->ident), ConSicsAction, NULL,pRes);
|
||||||
return pRes;
|
return pRes;
|
||||||
@ -436,8 +441,11 @@ extern pServer pServ;
|
|||||||
{
|
{
|
||||||
DeleteCommandStack(pVictim->pStack);
|
DeleteCommandStack(pVictim->pStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pVictim->lMagic=0; /* make a write to a freed connection harmless */
|
pVictim->lMagic=0; /* make a write to a freed connection harmless */
|
||||||
/* finally free pVictim*/
|
/* finally free pVictim*/
|
||||||
|
LLDdelete(pVictim->contextStack);
|
||||||
FreeConnection(pVictim);
|
FreeConnection(pVictim);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
@ -531,6 +539,15 @@ extern pServer pServ;
|
|||||||
}
|
}
|
||||||
return self->write(self,pBuffer,iOut);
|
return self->write(self,pBuffer,iOut);
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
int SCWriteInContext(SConnection *pCon, char *pBuffer, int out, commandContext cc)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
SCPushContext2(pCon,cc);
|
||||||
|
status = SCWrite(pCon,pBuffer,out);
|
||||||
|
SCPopContext(pCon);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
int SCPrintf(SConnection *self, int iOut, char *fmt, ...)
|
int SCPrintf(SConnection *self, int iOut, char *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -632,7 +649,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static int SCNormalWrite(SConnection *self, char *buffer, int iOut)
|
int SCNormalWrite(SConnection *self, char *buffer, int iOut)
|
||||||
{
|
{
|
||||||
int i, iPtr, iRet;
|
int i, iPtr, iRet;
|
||||||
char pBueffel[80];
|
char pBueffel[80];
|
||||||
@ -686,7 +703,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static int SCWriteWithOutcode(SConnection *self, char *buffer, int iOut)
|
int SCWriteWithOutcode(SConnection *self, char *buffer, int iOut)
|
||||||
{
|
{
|
||||||
int i, iPtr, iRet, length;
|
int i, iPtr, iRet, length;
|
||||||
char pBueffel[80];
|
char pBueffel[80];
|
||||||
@ -1343,7 +1360,14 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
|||||||
self->inUse++;
|
self->inUse++;
|
||||||
self->eInterrupt = eContinue;
|
self->eInterrupt = eContinue;
|
||||||
self->parameterChange = 0;
|
self->parameterChange = 0;
|
||||||
|
/*
|
||||||
|
get first word of command
|
||||||
|
*/
|
||||||
|
memset(pBueffel,0,80);
|
||||||
|
stptok(trim(pCommand),pBueffel,79," ");
|
||||||
|
SCAdvanceContext(self,pBueffel);
|
||||||
iRet = InterpExecute(pInter,self,pCommand);
|
iRet = InterpExecute(pInter,self,pCommand);
|
||||||
|
SCPopContext(self);
|
||||||
if(self->parameterChange == 1)
|
if(self->parameterChange == 1)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -1658,7 +1682,8 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
|||||||
The callback function for connection callbacks. Invokes command
|
The callback function for connection callbacks. Invokes command
|
||||||
given at registration time.
|
given at registration time.
|
||||||
*/
|
*/
|
||||||
static int ConCallBack(int iEvent, void *pEventData, void *pUserData)
|
static int ConCallBack(int iEvent, void *pEventData, void *pUserData,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
pCBAction self = NULL;
|
pCBAction self = NULL;
|
||||||
|
|
||||||
@ -1667,7 +1692,9 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
|||||||
|
|
||||||
if(self->pAction)
|
if(self->pAction)
|
||||||
{
|
{
|
||||||
|
SCPushContext2(self->pCon,cc);
|
||||||
InterpExecute(pServ->pSics,self->pCon,self->pAction);
|
InterpExecute(pServ->pSics,self->pCon,self->pAction);
|
||||||
|
SCPopContext(self->pCon);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1755,7 +1782,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
|||||||
pCB->pSics = pSics;
|
pCB->pSics = pSics;
|
||||||
pCB->pAction = strdup(pBueffel);
|
pCB->pAction = strdup(pBueffel);
|
||||||
sItem.pInterface = pInterface;
|
sItem.pInterface = pInterface;
|
||||||
sItem.lID = RegisterCallback(pInterface, iEvent, ConCallBack,
|
sItem.lID = RegisterCallback(pInterface, SCGetContext(pCB->pCon), iEvent, ConCallBack,
|
||||||
pCB, CBKill);
|
pCB, CBKill);
|
||||||
LLDnodeAppendFrom(self->iList,&sItem);
|
LLDnodeAppendFrom(self->iList,&sItem);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
@ -1961,6 +1988,48 @@ SConnection *SCLoad(SCStore *con) {
|
|||||||
}
|
}
|
||||||
return pCon;
|
return pCon;
|
||||||
}
|
}
|
||||||
|
/* --------------------------------------------------------------------------*/
|
||||||
|
long SCTagContext(SConnection *self, char *tagName)
|
||||||
|
{
|
||||||
|
commandContext a;
|
||||||
|
if(NULL==self) return -1;
|
||||||
|
/*
|
||||||
|
return SCSetContext(self,self->iCmdID,tagName);
|
||||||
|
*/
|
||||||
|
a = SCGetContext(self);
|
||||||
|
strncpy(a.deviceID,tagName,SCDEVIDLEN);
|
||||||
|
/*
|
||||||
|
SCGetContext will already have advanced the stack pointer to the
|
||||||
|
last position
|
||||||
|
*/
|
||||||
|
LLDnodeDataTo(self->contextStack, &a);
|
||||||
|
}
|
||||||
|
/* --------------------------------------------------------------------------*/
|
||||||
|
long SCAdvanceContext(SConnection *self, char *tagName)
|
||||||
|
{
|
||||||
|
if(NULL==self) return -1;
|
||||||
|
self->iCmdCtr++;
|
||||||
|
if(999999<self->iCmdCtr)
|
||||||
|
{
|
||||||
|
self->iCmdCtr = 0;
|
||||||
|
}
|
||||||
|
return SCPushContext(self, self->iCmdCtr, tagName);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
int SCVerifyConnection(SConnection *self)
|
||||||
|
{
|
||||||
|
return VerifyConnection(self);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
void SCWriteToLogFiles(SConnection *self, char *buffer)
|
||||||
|
{
|
||||||
|
writeToLogFiles(self,buffer);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
int SCDoSockWrite(SConnection *self, char *buffer)
|
||||||
|
{
|
||||||
|
return doSockWrite(self,buffer);
|
||||||
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
void KillFreeConnections(void) {
|
void KillFreeConnections(void) {
|
||||||
SConnection *next;
|
SConnection *next;
|
||||||
@ -1970,3 +2039,52 @@ void KillFreeConnections(void) {
|
|||||||
freeConnections = next;
|
freeConnections = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
int SCPushContext(SConnection *self, int ID, char *deviceID)
|
||||||
|
{
|
||||||
|
commandContext neu;
|
||||||
|
|
||||||
|
if(!VerifyConnection(self))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
neu.transID = ID;
|
||||||
|
strncpy(neu.deviceID,deviceID,SCDEVIDLEN);
|
||||||
|
LLDnodeAppendFrom(self->contextStack,&neu);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------*/
|
||||||
|
int SCPushContext2(SConnection *self, commandContext cc)
|
||||||
|
{
|
||||||
|
return SCPushContext(self,cc.transID, cc.deviceID);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------*/
|
||||||
|
commandContext SCGetContext(SConnection *pCon)
|
||||||
|
{
|
||||||
|
commandContext neu;
|
||||||
|
neu.transID = 0;
|
||||||
|
strcpy(neu.deviceID,"Undefined");
|
||||||
|
|
||||||
|
if(!VerifyConnection(pCon))
|
||||||
|
{
|
||||||
|
return neu;
|
||||||
|
}
|
||||||
|
if(LLDnodePtr2Last(pCon->contextStack) == 1){
|
||||||
|
LLDnodeDataTo(pCon->contextStack, &neu);
|
||||||
|
}
|
||||||
|
return neu;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------*/
|
||||||
|
int SCPopContext(SConnection *pCon)
|
||||||
|
{
|
||||||
|
if(!VerifyConnection(pCon))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(LLDnodePtr2Last(pCon->contextStack) != 0)
|
||||||
|
{
|
||||||
|
LLDnodeDelete(pCon->contextStack);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
26
conman.h
26
conman.h
@ -23,6 +23,7 @@
|
|||||||
#include "SCinter.h"
|
#include "SCinter.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "obdes.h"
|
#include "obdes.h"
|
||||||
|
#include "commandcontext.h"
|
||||||
|
|
||||||
#define MAXLOGFILES 10
|
#define MAXLOGFILES 10
|
||||||
|
|
||||||
@ -59,6 +60,16 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
|
|||||||
int parameterChange;
|
int parameterChange;
|
||||||
int sicsError;
|
int sicsError;
|
||||||
|
|
||||||
|
/*
|
||||||
|
stuff supporting the sycamore protocol and a
|
||||||
|
command context
|
||||||
|
*/
|
||||||
|
long iCmdCtr;
|
||||||
|
int conEventType;
|
||||||
|
int conStatus; /* should use status enum ffr */
|
||||||
|
int iProtocolID;
|
||||||
|
int contextStack;
|
||||||
|
|
||||||
/* a FIFO */
|
/* a FIFO */
|
||||||
pCosta pStack;
|
pCosta pStack;
|
||||||
|
|
||||||
@ -103,6 +114,8 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
|
|||||||
int SCOnlySockWrite(SConnection *self, char *buffer, int iOut);
|
int SCOnlySockWrite(SConnection *self, char *buffer, int iOut);
|
||||||
int SCFileWrite(SConnection *self, char *buffer, int iOut);
|
int SCFileWrite(SConnection *self, char *buffer, int iOut);
|
||||||
int SCNotWrite(SConnection *self, char *buffer, int iOut);
|
int SCNotWrite(SConnection *self, char *buffer, int iOut);
|
||||||
|
int SCNormalWrite(SConnection *self, char *buffer, int iOut);
|
||||||
|
int SCWriteWithOutcode(SConnection *self, char *buffer, int iOut);
|
||||||
/************************* CallBack *********************************** */
|
/************************* CallBack *********************************** */
|
||||||
int SCRegister(SConnection *pCon, SicsInterp *pSics,
|
int SCRegister(SConnection *pCon, SicsInterp *pSics,
|
||||||
void *pInter, long lID);
|
void *pInter, long lID);
|
||||||
@ -158,4 +171,17 @@ SConnection *SCLoad(SCStore *con);
|
|||||||
|
|
||||||
void KillFreeConnections(void);
|
void KillFreeConnections(void);
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
int SCVerifyConnection(SConnection *self);
|
||||||
|
void SCWriteToLogFiles(SConnection *self, char *buffer);
|
||||||
|
int SCDoSockWrite(SConnection *self, char *buffer);
|
||||||
|
int SCWriteInContext(SConnection *pCon, char *buffer, int code, commandContext cc);
|
||||||
|
|
||||||
|
long SCTagContext(SConnection *self, char *tagName);
|
||||||
|
long SCAdvanceContext(SConnection *self, char *tagName);
|
||||||
|
int SCPushContext(SConnection *pCon, int ID, char *deviceID);
|
||||||
|
int SCPushContext2(SConnection *pCon, commandContext cc);
|
||||||
|
int SCPopContext(SConnection *pCon);
|
||||||
|
commandContext SCGetContext(SConnection *pCon);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -708,7 +708,8 @@
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
static int CounterInterest(int iEvent, void *pEvent, void *pUser)
|
static int CounterInterest(int iEvent, void *pEvent, void *pUser,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
SConnection *pCon = NULL;
|
SConnection *pCon = NULL;
|
||||||
pMonEvent pMon = NULL;
|
pMonEvent pMon = NULL;
|
||||||
@ -731,7 +732,7 @@
|
|||||||
*/
|
*/
|
||||||
rights = SCGetRights(pCon);
|
rights = SCGetRights(pCon);
|
||||||
SCSetRights(pCon,usSpy);
|
SCSetRights(pCon,usSpy);
|
||||||
SCWrite(pCon,pBueffel,eWarning);
|
SCWriteInContext(pCon,pBueffel,eWarning,cc);
|
||||||
SCSetRights(pCon,rights);
|
SCSetRights(pCon,rights);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -896,7 +897,7 @@
|
|||||||
SCWrite(pCon,pBueffel,eValue);
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
return 1;
|
return 1;
|
||||||
case 9: /* interest */
|
case 9: /* interest */
|
||||||
lID = RegisterCallback(self->pCall, MONITOR, CounterInterest,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon), MONITOR, CounterInterest,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
|
8
danu.c
8
danu.c
@ -95,7 +95,8 @@ static int writeDataNumber(pDataNumber self, int iNum)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*------------------- The CallBack function for interest ------------------*/
|
/*------------------- The CallBack function for interest ------------------*/
|
||||||
static int InterestCallback(int iEvent, void *pEvent, void *pUser)
|
static int InterestCallback(int iEvent, void *pEvent, void *pUser,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
pDataNumber self = NULL;
|
pDataNumber self = NULL;
|
||||||
SConnection *pCon = NULL;
|
SConnection *pCon = NULL;
|
||||||
@ -120,7 +121,7 @@ static int writeDataNumber(pDataNumber self, int iNum)
|
|||||||
if(iNum > 0)
|
if(iNum > 0)
|
||||||
{
|
{
|
||||||
snprintf(pBueffel,131,"sicsdatanumber = %d", iNum);
|
snprintf(pBueffel,131,"sicsdatanumber = %d", iNum);
|
||||||
SCWrite(pCon,pBueffel,eValue);
|
SCWriteInContext(pCon,pBueffel,eValue,cc);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -330,7 +331,8 @@ int NewThousand(pDataNumber self)
|
|||||||
}
|
}
|
||||||
if(strcmp(argv[1],"interest") == 0)
|
if(strcmp(argv[1],"interest") == 0)
|
||||||
{
|
{
|
||||||
lID = RegisterCallback(self->pCall, VALUECHANGE, InterestCallback,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||||
|
VALUECHANGE, InterestCallback,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
|
58
devexec.c
58
devexec.c
@ -62,6 +62,7 @@
|
|||||||
pObjectDescriptor pDescriptor;
|
pObjectDescriptor pDescriptor;
|
||||||
float fVal;
|
float fVal;
|
||||||
char *name;
|
char *name;
|
||||||
|
commandContext comCon;
|
||||||
} DevEntry, *pDevEntry;
|
} DevEntry, *pDevEntry;
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, void *pData,
|
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, void *pData,
|
||||||
@ -80,6 +81,7 @@
|
|||||||
pNew->pData = pData;
|
pNew->pData = pData;
|
||||||
pNew->name = strdup(name);
|
pNew->name = strdup(name);
|
||||||
pNew->fVal = fVal;
|
pNew->fVal = fVal;
|
||||||
|
memset(&pNew->comCon,0,sizeof(commandContext));
|
||||||
return pNew;
|
return pNew;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
@ -228,6 +230,8 @@
|
|||||||
SCWrite(pCon,"ERROR: memory exhausted in Device Executor ",eError);
|
SCWrite(pCon,"ERROR: memory exhausted in Device Executor ",eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
pNew->comCon = SCGetContext(pCon);
|
||||||
|
strncpy(pNew->comCon.deviceID,name,SCDEVIDLEN);
|
||||||
|
|
||||||
/* start it */
|
/* start it */
|
||||||
pDrivInt = pDes->GetInterface(pData,DRIVEID);
|
pDrivInt = pDes->GetInterface(pData,DRIVEID);
|
||||||
@ -250,7 +254,12 @@
|
|||||||
if(iRet == OKOK)
|
if(iRet == OKOK)
|
||||||
{
|
{
|
||||||
LLDnodeAppendFrom(self->iList,&pNew);
|
LLDnodeAppendFrom(self->iList,&pNew);
|
||||||
ExeInterest(self, pNew, "started");
|
sprintf(pBueffel,"started");
|
||||||
|
if(NULL!=pNew->comCon.deviceID)
|
||||||
|
{
|
||||||
|
snprintf(pBueffel,130,"started (%s)",pNew->comCon.deviceID);
|
||||||
|
}
|
||||||
|
ExeInterest(self, pNew, pBueffel);
|
||||||
self->iRun = 1;
|
self->iRun = 1;
|
||||||
self->iStatus = DEVDONE;
|
self->iStatus = DEVDONE;
|
||||||
/* if no task: start it */
|
/* if no task: start it */
|
||||||
@ -263,6 +272,7 @@
|
|||||||
self,
|
self,
|
||||||
1);
|
1);
|
||||||
self->iEnd = 0;
|
self->iEnd = 0;
|
||||||
|
pCon->conStatus = HWBusy;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -373,6 +383,9 @@
|
|||||||
pIDrivable pDrivInt = NULL;
|
pIDrivable pDrivInt = NULL;
|
||||||
int eCode;
|
int eCode;
|
||||||
int isCounting=0, isDriving=0;
|
int isCounting=0, isDriving=0;
|
||||||
|
char pBueffel[512];
|
||||||
|
SConnection *pCon;
|
||||||
|
pCon = self->pOwner;
|
||||||
|
|
||||||
assert(self);
|
assert(self);
|
||||||
|
|
||||||
@ -397,6 +410,11 @@
|
|||||||
LLDnodeDataTo(self->iList,&pDev);
|
LLDnodeDataTo(self->iList,&pDev);
|
||||||
if(pDev)
|
if(pDev)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
SCSetContext(self->pOwner,pDev->cmdID,pDev->name);
|
||||||
|
*/
|
||||||
|
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
|
||||||
|
|
||||||
pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
|
pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
|
||||||
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
|
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
|
||||||
|
|
||||||
@ -423,10 +441,12 @@
|
|||||||
ExeInterest(self, pDev, "finished");
|
ExeInterest(self, pDev, "finished");
|
||||||
DeleteDevEntry(pDev);
|
DeleteDevEntry(pDev);
|
||||||
LLDnodeDelete(self->iList);
|
LLDnodeDelete(self->iList);
|
||||||
|
SCWrite(pCon, "", eFinish);
|
||||||
iRet = LLDnodePtr2Prev(self->iList);
|
iRet = LLDnodePtr2Prev(self->iList);
|
||||||
if(SCGetInterrupt(self->pOwner) != eContinue)
|
if(SCGetInterrupt(self->pOwner) != eContinue)
|
||||||
{
|
{
|
||||||
self->iStatus = DEVINT;
|
self->iStatus = DEVINT;
|
||||||
|
SCPopContext(self->pOwner);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
self->iStatus = DEVDONE;
|
self->iStatus = DEVDONE;
|
||||||
@ -435,6 +455,7 @@
|
|||||||
ExeInterest(self, pDev, "finished with problem");
|
ExeInterest(self, pDev, "finished with problem");
|
||||||
DeleteDevEntry(pDev);
|
DeleteDevEntry(pDev);
|
||||||
pDev = NULL;
|
pDev = NULL;
|
||||||
|
SCWrite(pCon, "", eFinish);
|
||||||
LLDnodeDataTo(self->iList,&pDev);
|
LLDnodeDataTo(self->iList,&pDev);
|
||||||
LLDnodeDelete(self->iList);
|
LLDnodeDelete(self->iList);
|
||||||
iRet = LLDnodePtr2Prev(self->iList);
|
iRet = LLDnodePtr2Prev(self->iList);
|
||||||
@ -446,6 +467,7 @@
|
|||||||
if(SCGetInterrupt(self->pOwner) != eContinue)
|
if(SCGetInterrupt(self->pOwner) != eContinue)
|
||||||
{
|
{
|
||||||
self->iStatus = DEVINT;
|
self->iStatus = DEVINT;
|
||||||
|
SCPopContext(self->pOwner);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -455,6 +477,7 @@
|
|||||||
{
|
{
|
||||||
SetStatus(eEager);
|
SetStatus(eEager);
|
||||||
self->iStatus = DEVINT;
|
self->iStatus = DEVINT;
|
||||||
|
SCPopContext(self->pOwner);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -464,6 +487,7 @@
|
|||||||
{
|
{
|
||||||
ContinueExecution(self);
|
ContinueExecution(self);
|
||||||
self->iStatus = DEVINT;
|
self->iStatus = DEVINT;
|
||||||
|
SCPopContext(self->pOwner);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -482,6 +506,7 @@
|
|||||||
ExeInterest(self, pDev, "finished with problem");
|
ExeInterest(self, pDev, "finished with problem");
|
||||||
DeleteDevEntry(pDev);
|
DeleteDevEntry(pDev);
|
||||||
LLDnodeDelete(self->iList);
|
LLDnodeDelete(self->iList);
|
||||||
|
SCWrite(pCon, "", eFinish);
|
||||||
self->iStatus = DEVERROR;
|
self->iStatus = DEVERROR;
|
||||||
if(pDrivInt)
|
if(pDrivInt)
|
||||||
{
|
{
|
||||||
@ -490,10 +515,12 @@
|
|||||||
if(SCGetInterrupt(self->pOwner) != eContinue)
|
if(SCGetInterrupt(self->pOwner) != eContinue)
|
||||||
{
|
{
|
||||||
self->iStatus = DEVINT;
|
self->iStatus = DEVINT;
|
||||||
|
SCPopContext(self->pOwner);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
SCPopContext(self->pOwner);
|
||||||
}
|
}
|
||||||
iRet = LLDnodePtr2Next(self->iList);
|
iRet = LLDnodePtr2Next(self->iList);
|
||||||
}
|
}
|
||||||
@ -641,7 +668,9 @@
|
|||||||
}
|
}
|
||||||
iRet = LLDnodePtr2Next(self->iList);
|
iRet = LLDnodePtr2Next(self->iList);
|
||||||
}
|
}
|
||||||
|
SCPushContext(self->pOwner,0,"system");
|
||||||
SCWrite(self->pOwner,"ERROR: Full Stop called!!",eError);
|
SCWrite(self->pOwner,"ERROR: Full Stop called!!",eError);
|
||||||
|
SCPopContext(self->pOwner);
|
||||||
if(SCGetInterrupt(self->pOwner) > eContinue)
|
if(SCGetInterrupt(self->pOwner) > eContinue)
|
||||||
{
|
{
|
||||||
self->iStatus = DEVINT;
|
self->iStatus = DEVINT;
|
||||||
@ -666,7 +695,7 @@
|
|||||||
}
|
}
|
||||||
else if(pCountInt)
|
else if(pCountInt)
|
||||||
{
|
{
|
||||||
pDrivInt->Halt(pDev->pData);
|
pCountInt->Halt(pDev->pData);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -699,6 +728,8 @@
|
|||||||
pDev = (pDevEntry)LLDnodePtr(self->iList);
|
pDev = (pDevEntry)LLDnodePtr(self->iList);
|
||||||
if(pDev)
|
if(pDev)
|
||||||
{
|
{
|
||||||
|
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
|
||||||
|
|
||||||
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
|
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
|
||||||
if(pCountInt)
|
if(pCountInt)
|
||||||
{
|
{
|
||||||
@ -710,6 +741,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
SCPopContext(self->pOwner);
|
||||||
iRet = LLDnodePtr2Next(self->iList);
|
iRet = LLDnodePtr2Next(self->iList);
|
||||||
}
|
}
|
||||||
SetStatus(ePaused);
|
SetStatus(ePaused);
|
||||||
@ -735,7 +767,6 @@
|
|||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
iRet = LLDnodePtr2Next(self->iList);
|
iRet = LLDnodePtr2Next(self->iList);
|
||||||
}
|
}
|
||||||
@ -760,11 +791,13 @@
|
|||||||
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
|
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
|
||||||
if(pCountInt)
|
if(pCountInt)
|
||||||
{
|
{
|
||||||
|
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
|
||||||
iRet = pCountInt->Continue(pDev->pData,self->pOwner);
|
iRet = pCountInt->Continue(pDev->pData,self->pOwner);
|
||||||
if(!iRet)
|
if(!iRet)
|
||||||
{
|
{
|
||||||
iRes = 0;
|
iRes = 0;
|
||||||
}
|
}
|
||||||
|
SCPopContext(self->pOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -842,12 +875,15 @@
|
|||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
/*------------------- The CallBack function for interest ------------------*/
|
/*------------------- The CallBack function for interest ------------------*/
|
||||||
static int DrivStatCallback(int iEvent, void *text, void *pCon)
|
static int DrivStatCallback(int iEvent, void *text, void *pCon,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
assert(pCon);
|
assert(pCon);
|
||||||
assert(text);
|
assert(text);
|
||||||
|
|
||||||
|
SCPushContext2(pCon,cc);
|
||||||
SCWrite(pCon, text, eValue);
|
SCWrite(pCon, text, eValue);
|
||||||
|
SCPopContext(pCon);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
@ -866,7 +902,8 @@
|
|||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
if (strcmp(argv[1], "interest") == 0)
|
if (strcmp(argv[1], "interest") == 0)
|
||||||
{
|
{
|
||||||
list = RegisterCallback(self->pCall, DRIVSTAT, DrivStatCallback,
|
list = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||||
|
DRIVSTAT, DrivStatCallback,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon, pSics, self->pCall,list);
|
SCRegister(pCon, pSics, self->pCall,list);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
@ -1025,15 +1062,6 @@
|
|||||||
{
|
{
|
||||||
if(iInterrupt > 1)
|
if(iInterrupt > 1)
|
||||||
{
|
{
|
||||||
/* M.Z: it seems that this warning is redundant
|
|
||||||
a) because it was erroenous
|
|
||||||
b) it would be emitted for every driveable obj to be stopped
|
|
||||||
|
|
||||||
Interrupt2Text(iInterrupt,pInterrupt,79);
|
|
||||||
snprintf(pBueffel,131,"ERROR: interrupt %s triggered",
|
|
||||||
pInterrupt);
|
|
||||||
SCWrite(self->pOwner,pBueffel, eError);
|
|
||||||
*/
|
|
||||||
StopExe(self,"all");
|
StopExe(self,"all");
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -1077,10 +1105,12 @@
|
|||||||
{
|
{
|
||||||
if(self->pOwner)
|
if(self->pOwner)
|
||||||
{
|
{
|
||||||
|
SCPushContext(self->pOwner,0,"system");
|
||||||
SCWrite(self->pOwner,
|
SCWrite(self->pOwner,
|
||||||
"ERROR: Interrupting Current Hardware Operation",
|
"ERROR: Interrupting Current Hardware Operation",
|
||||||
eError);
|
eError);
|
||||||
SCSetInterrupt(self->pOwner,*iInt);
|
SCSetInterrupt(self->pOwner,*iInt);
|
||||||
|
SCPopContext(self->pOwner);
|
||||||
}
|
}
|
||||||
StopExe(self,"all");
|
StopExe(self,"all");
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,8 @@ is set, without the current value is printed.
|
|||||||
<DT> nvs loss
|
<DT> nvs loss
|
||||||
<DD> Starts a loss current measurement on the velocity selector and prints the
|
<DD> Starts a loss current measurement on the velocity selector and prints the
|
||||||
result.
|
result.
|
||||||
|
<DT>nvs forbidden
|
||||||
|
<DD>Prints a list of forbidden speed regions for this selector.
|
||||||
<DT>nvs status
|
<DT>nvs status
|
||||||
<DD>Prints a status summary of the velocity selector.
|
<DD>Prints a status summary of the velocity selector.
|
||||||
</DL>
|
</DL>
|
||||||
|
@ -173,6 +173,16 @@
|
|||||||
eError);
|
eError);
|
||||||
return -999.;
|
return -999.;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void notifyStatus(pEVControl self, SConnection *pCon, int status) {
|
||||||
|
if (self->pDrivInt->drivableStatus!=status) {
|
||||||
|
((SConnection *)pCon)->conEventType=STATUS;
|
||||||
|
((SConnection *)pCon)->conStatus=status;
|
||||||
|
SCWrite(pCon, "", eEvent);
|
||||||
|
self->pDrivInt->drivableStatus=status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int EVIStatus(void *pData, SConnection *pCon)
|
static int EVIStatus(void *pData, SConnection *pCon)
|
||||||
{
|
{
|
||||||
@ -191,6 +201,7 @@
|
|||||||
/* go to idle when stopped */
|
/* go to idle when stopped */
|
||||||
if(self->iStop)
|
if(self->iStop)
|
||||||
{
|
{
|
||||||
|
notifyStatus(self, pCon, HWIdle);
|
||||||
return HWIdle;
|
return HWIdle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,16 +220,19 @@
|
|||||||
case DEVFAULT:
|
case DEVFAULT:
|
||||||
sprintf(pBueffel,"ERROR: %s",pError);
|
sprintf(pBueffel,"ERROR: %s",pError);
|
||||||
SCWrite(pCon,pBueffel,eError);
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
notifyStatus(self, pCon, HWFault);
|
||||||
return HWFault;
|
return HWFault;
|
||||||
case DEVREDO:
|
case DEVREDO:
|
||||||
sprintf(pBueffel,"WARNING: Fixing problem %s",pError);
|
sprintf(pBueffel,"WARNING: Fixing problem %s",pError);
|
||||||
SCWrite(pCon,pBueffel,eWarning);
|
SCWrite(pCon,pBueffel,eWarning);
|
||||||
|
notifyStatus(self, pCon, HWBusy);
|
||||||
return HWBusy;
|
return HWBusy;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(iRet == -1 ) /* pending */
|
else if(iRet == -1 ) /* pending */
|
||||||
{
|
{
|
||||||
|
notifyStatus(self, pCon, HWBusy);
|
||||||
return HWBusy;
|
return HWBusy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,6 +242,7 @@
|
|||||||
self->pName);
|
self->pName);
|
||||||
SCWrite(pCon,pBueffel,eError);
|
SCWrite(pCon,pBueffel,eError);
|
||||||
self->eMode = EVIdle;
|
self->eMode = EVIdle;
|
||||||
|
notifyStatus(self, pCon, HWFault);
|
||||||
return HWFault;
|
return HWFault;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,6 +269,7 @@
|
|||||||
self->pName);
|
self->pName);
|
||||||
SCWrite(pCon,pBueffel,eError);
|
SCWrite(pCon,pBueffel,eError);
|
||||||
self->eMode = EVMonitor;
|
self->eMode = EVMonitor;
|
||||||
|
notifyStatus(self, pCon, HWIdle);
|
||||||
return HWIdle;
|
return HWIdle;
|
||||||
}
|
}
|
||||||
tol = ObVal(self->pParam, TOLERANCE);
|
tol = ObVal(self->pParam, TOLERANCE);
|
||||||
@ -272,13 +288,16 @@
|
|||||||
self->pName, (self->lastt + tmo - now)*1.0);
|
self->pName, (self->lastt + tmo - now)*1.0);
|
||||||
SCWrite(pCon,pBueffel,eStatus);
|
SCWrite(pCon,pBueffel,eStatus);
|
||||||
}
|
}
|
||||||
|
notifyStatus(self, pCon, HWBusy);
|
||||||
return HWBusy;
|
return HWBusy;
|
||||||
}
|
}
|
||||||
if (now > self->lastt + tmo)
|
if (now > self->lastt + tmo)
|
||||||
{
|
{
|
||||||
self->eMode = EVMonitor;
|
self->eMode = EVMonitor;
|
||||||
|
notifyStatus(self, pCon, HWIdle);
|
||||||
return HWIdle;
|
return HWIdle;
|
||||||
}
|
}
|
||||||
|
notifyStatus(self, pCon, HWBusy);
|
||||||
return HWBusy;
|
return HWBusy;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -289,6 +308,7 @@
|
|||||||
SCWrite(pCon,pBueffel,eStatus);
|
SCWrite(pCon,pBueffel,eStatus);
|
||||||
self->lastt -= now;
|
self->lastt -= now;
|
||||||
}
|
}
|
||||||
|
notifyStatus(self, pCon, HWBusy);
|
||||||
return HWBusy;
|
return HWBusy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1009,7 +1029,8 @@ static void ErrReport(pEVControl self)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static int EVCallBack(int iEvent, void *pEventData, void *pUserData)
|
static int EVCallBack(int iEvent, void *pEventData, void *pUserData,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
char *pBuf = (char *)pEventData;
|
char *pBuf = (char *)pEventData;
|
||||||
SConnection *pCon = (SConnection *)pUserData;
|
SConnection *pCon = (SConnection *)pUserData;
|
||||||
@ -1017,7 +1038,8 @@ static void ErrReport(pEVControl self)
|
|||||||
|
|
||||||
if(iEvent == VALUECHANGE)
|
if(iEvent == VALUECHANGE)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,pBuf,eValue);
|
pCon->conEventType=POSITION;
|
||||||
|
SCWriteInContext(pCon,pBuf,eEvent,cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -1075,7 +1097,8 @@ static void ErrReport(pEVControl self)
|
|||||||
/* install automatic notification */
|
/* install automatic notification */
|
||||||
else if(strcmp(argv[1],"interest") == 0)
|
else if(strcmp(argv[1],"interest") == 0)
|
||||||
{
|
{
|
||||||
lID = RegisterCallback(self->pCall, VALUECHANGE, EVCallBack,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||||
|
VALUECHANGE, EVCallBack,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
@ -1414,13 +1437,14 @@ int RemoveEVController(SConnection *pCon, char *name) {
|
|||||||
SCWrite(pCon,"ERROR: cannot delete while running",eError);
|
SCWrite(pCon,"ERROR: cannot delete while running",eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!FindCommandData(pServ->pSics, name, "Environment Controller")) {
|
EVUnregister(FindEMON(pServ->pSics),name);
|
||||||
SCPrintf(pCon,eError,"ERROR: no environment controller %s found",name);
|
iRet = RemoveCommand(pServ->pSics,name);
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: %s not found, NOT deleted",name);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EVUnregister(FindEMON(pServ->pSics),name);
|
|
||||||
RemoveCommand(pServ->pSics,name);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
|
3
event.h
3
event.h
@ -42,7 +42,8 @@
|
|||||||
#define BATCHAREA 15
|
#define BATCHAREA 15
|
||||||
#define BATCHEND 16
|
#define BATCHEND 16
|
||||||
#define DRIVSTAT 17
|
#define DRIVSTAT 17
|
||||||
|
#define STATUS 18
|
||||||
|
#define POSITION 19 /* Position event for motors - ffr */
|
||||||
#line 104 "event.w"
|
#line 104 "event.w"
|
||||||
|
|
||||||
|
|
||||||
|
18
exeman.c
18
exeman.c
@ -284,25 +284,27 @@ static pExeInfo makeExeInfo(SConnection *pCon, pExeMan self){
|
|||||||
return pNew;
|
return pNew;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
static int BufferCallback(int iEvent, void *pEvent, void *pUser){
|
static int BufferCallback(int iEvent, void *pEvent, void *pUser,
|
||||||
|
commandContext cc){
|
||||||
pExeInfo self = (pExeInfo)pUser;
|
pExeInfo self = (pExeInfo)pUser;
|
||||||
char *name = (char *)pEvent;
|
char *name = (char *)pEvent;
|
||||||
char pBueffel[132];
|
char pBueffel[132];
|
||||||
|
|
||||||
if(iEvent == BATCHSTART){
|
if(iEvent == BATCHSTART){
|
||||||
snprintf(pBueffel,131,"BATCHSTART=%s",name);
|
snprintf(pBueffel,131,"BATCHSTART=%s",name);
|
||||||
SCWrite(self->pCon,pBueffel,eWarning);
|
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(iEvent == BATCHEND){
|
if(iEvent == BATCHEND){
|
||||||
snprintf(pBueffel,131,"BATCHEND=%s",name);
|
snprintf(pBueffel,131,"BATCHEND=%s",name);
|
||||||
SCWrite(self->pCon,pBueffel,eWarning);
|
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------*/
|
||||||
static int LineCallBack(int iEvent, void *pEvent, void *pUser){
|
static int LineCallBack(int iEvent, void *pEvent, void *pUser,
|
||||||
|
commandContext cc){
|
||||||
pExeInfo self = (pExeInfo)pUser;
|
pExeInfo self = (pExeInfo)pUser;
|
||||||
char pBueffel[256];
|
char pBueffel[256];
|
||||||
int start, end, lineno;
|
int start, end, lineno;
|
||||||
@ -317,7 +319,7 @@ static int LineCallBack(int iEvent, void *pEvent, void *pUser){
|
|||||||
exeBufRange(buf,&start,&end,&lineno);
|
exeBufRange(buf,&start,&end,&lineno);
|
||||||
snprintf(pBueffel,255,"%s.range = %d = %d",exeBufName(buf),
|
snprintf(pBueffel,255,"%s.range = %d = %d",exeBufName(buf),
|
||||||
start,end);
|
start,end);
|
||||||
SCWrite(self->pCon,pBueffel,eWarning);
|
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -332,13 +334,13 @@ static void registerCallbacks(SConnection *pCon, SicsInterp *pSics,
|
|||||||
if(info == NULL){
|
if(info == NULL){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lID = RegisterCallback(self->pCall, BATCHSTART, BufferCallback,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHSTART, BufferCallback,
|
||||||
info, killExeInfo);
|
info, killExeInfo);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
lID = RegisterCallback(self->pCall, BATCHEND, BufferCallback,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHEND, BufferCallback,
|
||||||
info, NULL);
|
info, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
lID = RegisterCallback(self->pCall, BATCHAREA, LineCallBack,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHAREA, LineCallBack,
|
||||||
info, NULL);
|
info, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
}
|
}
|
||||||
|
53
fourlib.c
53
fourlib.c
@ -450,6 +450,59 @@ double sign(double a, double b){
|
|||||||
return -ABS(a);
|
return -ABS(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
static void makeNull(double *gamma, double *om, double *nu){
|
||||||
|
*gamma = .0;
|
||||||
|
*om = .0;
|
||||||
|
*nu = .0;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
int z1mToNormalBeam(double lambda, MATRIX z1m, double *gamma, double *om, double *nu){
|
||||||
|
MATRIX dum, znew;
|
||||||
|
double d, a, b, sint, theta, omdeg;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = calcTheta(lambda,z1m,&d,&theta);
|
||||||
|
if(!status){
|
||||||
|
makeNull(gamma,om,nu);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Everything on omega axis is blind: test for this */
|
||||||
|
a = sqrt(z1m[0][0] * z1m[0][0] + z1m[1][0] * z1m[1][0]);
|
||||||
|
if(ABS(a) < .0001) {
|
||||||
|
makeNull(gamma,om,nu);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sint = sin(theta/RD);
|
||||||
|
b = 2.*sint*sint/(lambda*a);
|
||||||
|
if(b >= 1.) {
|
||||||
|
makeNull(gamma,om,nu);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
a = -atan2(z1m[1][0], -z1m[0][0]);
|
||||||
|
b = -asin(b);
|
||||||
|
*om = a + b;
|
||||||
|
omdeg = *om*RD;
|
||||||
|
dum = mat_creat(3,3,ZERO_MATRIX);
|
||||||
|
phimat(dum,omdeg);
|
||||||
|
znew = mat_mul(dum,z1m);
|
||||||
|
if(znew[0][0] < 0) {
|
||||||
|
*om = *om -2.*atan2(-znew[0][0], -znew[2][0]);
|
||||||
|
omdeg = *om * RD;
|
||||||
|
}
|
||||||
|
b = (sign(180.,omdeg)+ omdeg)/360.;
|
||||||
|
/* omdeg = omdeg - 360. * floor(b); */
|
||||||
|
*nu = asin(lambda*z1m[2][0]);
|
||||||
|
*gamma = acos(cos(2.*(theta/RD)))/cos(*nu);
|
||||||
|
*om = omdeg;
|
||||||
|
*nu = *nu * RD;
|
||||||
|
*gamma = *gamma * RD;
|
||||||
|
mat_free(dum);
|
||||||
|
mat_free(znew);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
int bisToNormalBeam(double twotheta, double omega, double chi, double phi,
|
int bisToNormalBeam(double twotheta, double omega, double chi, double phi,
|
||||||
double *omeganb, double *gamma, double *nu){
|
double *omeganb, double *gamma, double *nu){
|
||||||
|
@ -122,6 +122,10 @@ void z1FromAngles(double lambda, double stt, double om,
|
|||||||
*/
|
*/
|
||||||
int bisToNormalBeam(double twotheta, double omega, double chi, double phi,
|
int bisToNormalBeam(double twotheta, double omega, double chi, double phi,
|
||||||
double *omeganb, double *gamma, double *nu);
|
double *omeganb, double *gamma, double *nu);
|
||||||
|
/**
|
||||||
|
* calculate normal beam angles from z1
|
||||||
|
*/
|
||||||
|
int z1mToNormalBeam(double lambda, MATRIX z1, double *gamma, double *om, double *nu);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calculate the vector z1 from the normal beam angles omega, gamma and nu.
|
* calculate the vector z1 from the normal beam angles omega, gamma and nu.
|
||||||
|
104
histmem.c
104
histmem.c
@ -439,6 +439,7 @@
|
|||||||
free(pNew);
|
free(pNew);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
StringDictAddPair(pNew->pOption,"driver",driver);
|
||||||
StringDictAddPair(pNew->pOption,"update","0");
|
StringDictAddPair(pNew->pOption,"update","0");
|
||||||
|
|
||||||
/* initialise driver */
|
/* initialise driver */
|
||||||
@ -532,6 +533,8 @@
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringDictAddPair(pNew->pOption,"name",argv[1]);
|
||||||
|
|
||||||
/* install HM as command */
|
/* install HM as command */
|
||||||
iRet = AddCommand(pSics,argv[1],HistAction,DeleteHistMemory,(void *)pNew);
|
iRet = AddCommand(pSics,argv[1],HistAction,DeleteHistMemory,(void *)pNew);
|
||||||
if(!iRet)
|
if(!iRet)
|
||||||
@ -918,7 +921,8 @@ void HistDirty(pHistMem self)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
static int HMCountInterest(int iEvent, void *pEvent, void *pUser)
|
static int HMCountInterest(int iEvent, void *pEvent, void *pUser,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
SConnection *pCon = NULL;
|
SConnection *pCon = NULL;
|
||||||
char pBueffel[512];
|
char pBueffel[512];
|
||||||
@ -927,14 +931,14 @@ void HistDirty(pHistMem self)
|
|||||||
{
|
{
|
||||||
pCon = (SConnection *)pUser;
|
pCon = (SConnection *)pUser;
|
||||||
assert(pCon);
|
assert(pCon);
|
||||||
SCWrite(pCon,"HMCOUNTSTART",eWarning);
|
SCWriteInContext(pCon,"HMCOUNTSTART",eWarning,cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if(iEvent == COUNTEND)
|
else if(iEvent == COUNTEND)
|
||||||
{
|
{
|
||||||
pCon = (SConnection *)pUser;
|
pCon = (SConnection *)pUser;
|
||||||
assert(pCon);
|
assert(pCon);
|
||||||
SCWrite(pCon,"HMCOUNTEND",eWarning);
|
SCWriteInContext(pCon,"HMCOUNTEND",eWarning,cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -955,6 +959,89 @@ static int checkHMEnd(pHistMem self, char *text){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
void HMListOption(pHistMem self, SConnection *pCon)
|
||||||
|
{
|
||||||
|
char pBuffer[512];
|
||||||
|
char name[20];
|
||||||
|
char pValue[128];
|
||||||
|
const char *pKey;
|
||||||
|
int i,iRet,iLen,iRank,iDiscard,tofMode;
|
||||||
|
float fVal;
|
||||||
|
char *pMode[] = {"timer","monitor",NULL};
|
||||||
|
|
||||||
|
memset(pBuffer, 0, sizeof(pBuffer));
|
||||||
|
memset(pValue, 0, sizeof(pValue));
|
||||||
|
memset(name, 0, sizeof(name));
|
||||||
|
|
||||||
|
iRet = StringDictGet(self->pOption,"name",name,19);
|
||||||
|
if(0==iRet) {
|
||||||
|
strcpy(name,"*");
|
||||||
|
}
|
||||||
|
iRet = StringDictGet(self->pOption,"driver",pValue,sizeof(pValue)-1);
|
||||||
|
if(0<iRet) {
|
||||||
|
sprintf(pBuffer,"%s.driver = %s",name,pValue);
|
||||||
|
SCWrite(pCon,pBuffer,eStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
iRet = StringDictGetAsNumber(self->pOption,"update",&fVal);
|
||||||
|
if(0<iRet) {
|
||||||
|
sprintf(pBuffer,"%s.update = %d",name,(int)rint(fVal));
|
||||||
|
} else {
|
||||||
|
sprintf(pBuffer,"%s.update = 0 (no buffering)",name);
|
||||||
|
}
|
||||||
|
SCWrite(pCon,pBuffer,eStatus);
|
||||||
|
|
||||||
|
iRet = StringDictGetAsNumber(self->pOption,"rank",&fVal);
|
||||||
|
if(0<iRet) {
|
||||||
|
iRank = (int)rint(fVal);
|
||||||
|
sprintf(pBuffer,"%s.rank = %d",name,iRank);
|
||||||
|
SCWrite(pCon,pBuffer,eStatus);
|
||||||
|
} else {
|
||||||
|
iRank = 0;
|
||||||
|
}
|
||||||
|
for(i=0; i<iRank; i++){
|
||||||
|
sprintf(pValue,"dim%1.1d",i);
|
||||||
|
iRet = StringDictGetAsNumber(self->pOption,pValue,&fVal);
|
||||||
|
if(0<iRet){
|
||||||
|
sprintf(pBuffer,"%s.dim%1.1d = %d",name,i,(int)rint(fVal));
|
||||||
|
SCWrite(pCon,pBuffer,eStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pKey = StringDictGetNext(self->pOption,pValue,sizeof(pValue)-1);
|
||||||
|
while(pKey != NULL) {
|
||||||
|
iDiscard=0;
|
||||||
|
if(0==strcmp("name",pKey)) iDiscard=1;
|
||||||
|
if(0==strcmp("driver",pKey)) iDiscard=1;
|
||||||
|
if(0==strcmp("update",pKey)) iDiscard=1;
|
||||||
|
if(0==strcmp("rank",pKey)) iDiscard=1;
|
||||||
|
if(NULL!=strstr(pKey,"dim")) iDiscard=1;
|
||||||
|
if(0==iDiscard) {
|
||||||
|
sprintf(pBuffer,"%s.%s = %s",name,pKey,pValue,sizeof(pValue)-1);
|
||||||
|
SCWrite(pCon,pBuffer,eStatus);
|
||||||
|
}
|
||||||
|
pKey = StringDictGetNext(self->pOption,pValue,sizeof(pValue)-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Display Count Mode */
|
||||||
|
sprintf(pBuffer,"%s.CountMode = %s",name,pMode[self->pDriv->eCount]);
|
||||||
|
SCWrite(pCon,pBuffer,eStatus);
|
||||||
|
|
||||||
|
/* Display Preset */
|
||||||
|
sprintf(pBuffer,"%s.preset = %f",name,self->pDriv->fCountPreset);
|
||||||
|
SCWrite(pCon,pBuffer,eStatus);
|
||||||
|
|
||||||
|
if(self->pDriv->data->nTimeChan > 2) {
|
||||||
|
tofMode = 1;
|
||||||
|
} else {
|
||||||
|
tofMode = 0;
|
||||||
|
}
|
||||||
|
sprintf(pBuffer,"%s.tofMode = %d",name,tofMode);
|
||||||
|
SCWrite(pCon,pBuffer,eStatus);
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
int HistAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int HistAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
@ -998,10 +1085,12 @@ static int checkHMEnd(pHistMem self, char *text){
|
|||||||
strtolower(argv[1]);
|
strtolower(argv[1]);
|
||||||
if(strcmp(argv[1],"interest") == 0)
|
if(strcmp(argv[1],"interest") == 0)
|
||||||
{
|
{
|
||||||
lID = RegisterCallback(self->pCall, COUNTSTART, HMCountInterest,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||||
|
COUNTSTART, HMCountInterest,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
lID = RegisterCallback(self->pCall, COUNTEND, HMCountInterest,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||||
|
COUNTEND, HMCountInterest,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
@ -1165,6 +1254,11 @@ static int checkHMEnd(pHistMem self, char *text){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(strcmp(argv[1],"list") == 0)
|
||||||
|
{
|
||||||
|
HMListOption(self,pCon);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/* normal counting*/
|
/* normal counting*/
|
||||||
else if(strcmp(argv[1],"count") == 0)
|
else if(strcmp(argv[1],"count") == 0)
|
||||||
{
|
{
|
||||||
|
35
hkl.c
35
hkl.c
@ -205,7 +205,8 @@
|
|||||||
#include "selvar.i"
|
#include "selvar.i"
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static int HKLCallback(int iEvent, void *pEvent, void *pUser)
|
static int HKLCallback(int iEvent, void *pEvent, void *pUser,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
pHKL self = NULL;
|
pHKL self = NULL;
|
||||||
pSelVar pVar = NULL;
|
pSelVar pVar = NULL;
|
||||||
@ -236,6 +237,7 @@
|
|||||||
pICallBack pCall = NULL, pCall2 = NULL;
|
pICallBack pCall = NULL, pCall2 = NULL;
|
||||||
pDummy pDum = NULL;
|
pDummy pDum = NULL;
|
||||||
float fVal;
|
float fVal;
|
||||||
|
commandContext comCon;
|
||||||
|
|
||||||
assert(pCon);
|
assert(pCon);
|
||||||
assert(self);
|
assert(self);
|
||||||
@ -264,7 +266,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* install new callback */
|
/* install new callback */
|
||||||
|
comCon.transID = 0;
|
||||||
|
strncpy(comCon.deviceID,"internal",SCDEVIDLEN);
|
||||||
self->lID = RegisterCallback(pCall2,
|
self->lID = RegisterCallback(pCall2,
|
||||||
|
comCon,
|
||||||
WLCHANGE,
|
WLCHANGE,
|
||||||
HKLCallback,
|
HKLCallback,
|
||||||
self,
|
self,
|
||||||
@ -673,7 +678,7 @@ static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
|
|||||||
float fSet[4], double myPsi, int iRetry)
|
float fSet[4], double myPsi, int iRetry)
|
||||||
{
|
{
|
||||||
int i, iTest;
|
int i, iTest;
|
||||||
double stt, om, chi, phi, gamma, nu, psi;
|
double stt, om, chi, phi, gamma, nu, psi, omnb;
|
||||||
float currentPhi, currentChi;
|
float currentPhi, currentChi;
|
||||||
double ompsi, chipsi, phipsi;
|
double ompsi, chipsi, phipsi;
|
||||||
MATRIX chim, phim, z4, z3;
|
MATRIX chim, phim, z4, z3;
|
||||||
@ -694,6 +699,7 @@ static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
phim = mat_creat(3,3,ZERO_MATRIX);
|
phim = mat_creat(3,3,ZERO_MATRIX);
|
||||||
phimat(phim,(double)currentPhi);
|
phimat(phim,(double)currentPhi);
|
||||||
z4 = mat_mul(phim,z1);
|
z4 = mat_mul(phim,z1);
|
||||||
@ -703,6 +709,31 @@ static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
|
|||||||
mat_free(phim);
|
mat_free(phim);
|
||||||
mat_free(chim);
|
mat_free(chim);
|
||||||
mat_free(z4);
|
mat_free(z4);
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(!z1mToNormalBeam(self->fLambda, z1, &gamma, &omnb, &nu)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(checkNormalBeam(omnb, &gamma, nu,fSet,pCon,self)){
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!z1mToBisecting(self->fLambda,z1,&stt,&om,&chi,&phi))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(bisToNormalBeam(stt,om,chi,phi,
|
||||||
|
&omnb, &gamma, &nu))
|
||||||
|
{
|
||||||
|
/* om = -om + 180.; */
|
||||||
|
if(checkNormalBeam(omnb, &gamma, nu,fSet,pCon,self))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
do the bisecting angles first
|
do the bisecting angles first
|
||||||
|
22
ifile.c
22
ifile.c
@ -153,6 +153,28 @@
|
|||||||
{
|
{
|
||||||
return CreateNewEntry(name,value,pList);
|
return CreateNewEntry(name,value,pList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
IPair *IFSetOption(IPair *pList,char *name, char *value)
|
||||||
|
{
|
||||||
|
IPair *pCurrent;
|
||||||
|
if(NULL!=pList)
|
||||||
|
{
|
||||||
|
pCurrent = pList;
|
||||||
|
while((NULL!=pCurrent) && (0!=strcmp(name,pCurrent->name)))
|
||||||
|
{
|
||||||
|
pCurrent = pCurrent->pNext;
|
||||||
|
}
|
||||||
|
if(NULL!=pCurrent)
|
||||||
|
{ /* replace value */
|
||||||
|
free(pCurrent->value);
|
||||||
|
pCurrent->value = strdup(value);
|
||||||
|
return pCurrent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CreateNewEntry(name,value,pList);
|
||||||
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
int IFSaveOptions(IPair *pList,FILE *fd)
|
int IFSaveOptions(IPair *pList,FILE *fd)
|
||||||
|
2
ifile.h
2
ifile.h
@ -25,6 +25,8 @@ typedef struct __IFileE
|
|||||||
/* returns a value for a name
|
/* returns a value for a name
|
||||||
*/
|
*/
|
||||||
IPair *IFAddOption(IPair *pList,char *name, char *value);
|
IPair *IFAddOption(IPair *pList,char *name, char *value);
|
||||||
|
IPair *IFSetOption(IPair *pList,char *name, char *value);
|
||||||
|
|
||||||
int IFSaveOptions(IPair *pList,FILE *fp);
|
int IFSaveOptions(IPair *pList,FILE *fp);
|
||||||
void IFDeleteOptions(IPair *pList);
|
void IFDeleteOptions(IPair *pList);
|
||||||
|
|
||||||
|
@ -83,6 +83,7 @@ static float EmptyGet(void *self, SConnection *pCon){
|
|||||||
pRes->SetValue = EmptyValue;
|
pRes->SetValue = EmptyValue;
|
||||||
pRes->CheckStatus = EmptyStatus;
|
pRes->CheckStatus = EmptyStatus;
|
||||||
pRes->GetValue = EmptyGet;
|
pRes->GetValue = EmptyGet;
|
||||||
|
pRes->drivableStatus=HWIdle;
|
||||||
return pRes;
|
return pRes;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
33
interface.h
33
interface.h
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 365 "interface.w"
|
#line 381 "interface.w"
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
I N T E R F A C E S
|
I N T E R F A C E S
|
||||||
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#ifndef SICSINTERFACES
|
#ifndef SICSINTERFACES
|
||||||
#define SICSINTERFACES
|
#define SICSINTERFACES
|
||||||
|
#include "commandcontext.h"
|
||||||
|
|
||||||
/* interface ID's used to recognize an interface */
|
/* interface ID's used to recognize an interface */
|
||||||
#define DRIVEID 513
|
#define DRIVEID 513
|
||||||
@ -26,7 +27,7 @@
|
|||||||
|
|
||||||
/* ----------------------- The drivable interface -----------------------*/
|
/* ----------------------- The drivable interface -----------------------*/
|
||||||
|
|
||||||
#line 117 "interface.w"
|
#line 121 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -39,6 +40,7 @@
|
|||||||
int (*CheckStatus)(void *self, SConnection *pCon);
|
int (*CheckStatus)(void *self, SConnection *pCon);
|
||||||
float (*GetValue)(void *self, SConnection *pCon);
|
float (*GetValue)(void *self, SConnection *pCon);
|
||||||
int iErrorCount;
|
int iErrorCount;
|
||||||
|
int drivableStatus;
|
||||||
} IDrivable, *pIDrivable;
|
} IDrivable, *pIDrivable;
|
||||||
|
|
||||||
pIDrivable GetDrivableInterface(void *pObject);
|
pIDrivable GetDrivableInterface(void *pObject);
|
||||||
@ -46,14 +48,14 @@
|
|||||||
float *fPos);
|
float *fPos);
|
||||||
|
|
||||||
|
|
||||||
#line 390 "interface.w"
|
#line 407 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
pIDrivable CreateDrivableInterface(void);
|
pIDrivable CreateDrivableInterface(void);
|
||||||
|
|
||||||
/* ------------------------ The countable interface ---------------------*/
|
/* ------------------------ The countable interface ---------------------*/
|
||||||
|
|
||||||
#line 183 "interface.w"
|
#line 188 "interface.w"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int ID;
|
int ID;
|
||||||
@ -70,23 +72,23 @@
|
|||||||
pICountable GetCountableInterface(void *pObject);
|
pICountable GetCountableInterface(void *pObject);
|
||||||
|
|
||||||
|
|
||||||
#line 395 "interface.w"
|
#line 412 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
pICountable CreateCountableInterface(void);
|
pICountable CreateCountableInterface(void);
|
||||||
|
|
||||||
/* ------------------------- The CallBack Interface --------------------*/
|
/* ------------------------- The CallBack Interface --------------------*/
|
||||||
|
|
||||||
#line 236 "interface.w"
|
#line 241 "interface.w"
|
||||||
|
|
||||||
typedef void (*KillFuncIT)(void *pData);
|
typedef void (*KillFuncIT)(void *pData);
|
||||||
typedef int (*SICSCallBack)(int iEvent, void *pEventData,
|
typedef int (*SICSCallBack)(int iEvent, void *pEventData,
|
||||||
void *pUserData);
|
void *pUserData, commandContext cc);
|
||||||
|
|
||||||
#line 400 "interface.w"
|
#line 417 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
#line 258 "interface.w"
|
#line 263 "interface.w"
|
||||||
|
|
||||||
typedef struct __ICallBack *pICallBack;
|
typedef struct __ICallBack *pICallBack;
|
||||||
|
|
||||||
@ -96,7 +98,8 @@
|
|||||||
int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData);
|
int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData);
|
||||||
|
|
||||||
/* callback client side */
|
/* callback client side */
|
||||||
long RegisterCallback(pICallBack pInterface, int iEvent, SICSCallBack pFunc,
|
long RegisterCallback(pICallBack pInterface, commandContext comCon,
|
||||||
|
int iEvent, SICSCallBack pFunc,
|
||||||
void *pUserData, KillFuncIT pKill);
|
void *pUserData, KillFuncIT pKill);
|
||||||
int RemoveCallback(pICallBack pInterface, long iID);
|
int RemoveCallback(pICallBack pInterface, long iID);
|
||||||
int RemoveCallback2(pICallBack pInterface, void *pUserData);
|
int RemoveCallback2(pICallBack pInterface, void *pUserData);
|
||||||
@ -106,11 +109,11 @@
|
|||||||
|
|
||||||
pICallBack GetCallbackInterface(void *pData);
|
pICallBack GetCallbackInterface(void *pData);
|
||||||
|
|
||||||
#line 401 "interface.w"
|
#line 418 "interface.w"
|
||||||
|
|
||||||
/*---------------------- The Environment Interface --------------------*/
|
/*---------------------- The Environment Interface --------------------*/
|
||||||
|
|
||||||
#line 329 "interface.w"
|
#line 335 "interface.w"
|
||||||
|
|
||||||
typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;
|
typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -120,13 +123,13 @@
|
|||||||
int (*HandleError)(void *self);
|
int (*HandleError)(void *self);
|
||||||
} EVInterface, *pEVInterface;
|
} EVInterface, *pEVInterface;
|
||||||
|
|
||||||
#line 403 "interface.w"
|
#line 420 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
#line 355 "interface.w"
|
#line 361 "interface.w"
|
||||||
|
|
||||||
pEVInterface CreateEVInterface(void);
|
pEVInterface CreateEVInterface(void);
|
||||||
|
|
||||||
#line 404 "interface.w"
|
#line 421 "interface.w"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
\newcommand{\NWtarget}[2]{#2}
|
||||||
|
\newcommand{\NWlink}[2]{#2}
|
||||||
|
\newcommand{\NWtxtMacroDefBy}{Macro defined by}
|
||||||
|
\newcommand{\NWtxtMacroRefIn}{Macro referenced in}
|
||||||
|
\newcommand{\NWtxtMacroNoRef}{Macro never referenced}
|
||||||
|
\newcommand{\NWtxtDefBy}{Defined by}
|
||||||
|
\newcommand{\NWtxtRefIn}{Referenced in}
|
||||||
|
\newcommand{\NWtxtNoRef}{Not referenced}
|
||||||
|
\newcommand{\NWtxtFileDefBy}{File defined by}
|
||||||
|
\newcommand{\NWsep}{${\diamond}$}
|
||||||
\subsection{Object interfaces}\label{inter}
|
\subsection{Object interfaces}\label{inter}
|
||||||
In order to present themselves to the system SICS objects need to adhere to
|
In order to present themselves to the system SICS objects need to adhere to
|
||||||
certyain interfaces. These interfaces are described in this
|
certyain interfaces. These interfaces are described in this
|
||||||
@ -28,7 +38,7 @@ Let's start with the objectdescriptor:
|
|||||||
|
|
||||||
\begin{flushleft} \small
|
\begin{flushleft} \small
|
||||||
\begin{minipage}{\linewidth} \label{scrap1}
|
\begin{minipage}{\linewidth} \label{scrap1}
|
||||||
$\langle$obdes {\footnotesize ?}$\rangle\equiv$
|
$\langle\,$obdes\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
@ -50,11 +60,15 @@ $\langle$obdes {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@#ifndef SICSDESCRIPTOR@\\
|
\mbox{}\verb@#ifndef SICSDESCRIPTOR@\\
|
||||||
\mbox{}\verb@#define SICSDESCRIPTOR@\\
|
\mbox{}\verb@#define SICSDESCRIPTOR@\\
|
||||||
\mbox{}\verb@#include <stdio.h>@\\
|
\mbox{}\verb@#include <stdio.h>@\\
|
||||||
|
\mbox{}\verb@#include <ifile.h>@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ typedef struct {@\\
|
\mbox{}\verb@ typedef struct {@\\
|
||||||
\mbox{}\verb@ char *name;@\\
|
\mbox{}\verb@ char *name;@\\
|
||||||
\mbox{}\verb@ int (*SaveStatus)(void *self, char *name,FILE *fd);@\\
|
\mbox{}\verb@ int (*SaveStatus)(void *self, char *name,FILE *fd);@\\
|
||||||
\mbox{}\verb@ void *(*GetInterface)(void *self, int iInterfaceID);@\\
|
\mbox{}\verb@ void *(*GetInterface)(void *self, int iInterfaceID);@\\
|
||||||
|
\mbox{}\verb@ char *description;@\\
|
||||||
|
\mbox{}\verb@ char *group;@\\
|
||||||
|
\mbox{}\verb@ IPair *pKeys;@\\
|
||||||
\mbox{}\verb@ } ObjectDescriptor, *pObjectDescriptor;@\\
|
\mbox{}\verb@ } ObjectDescriptor, *pObjectDescriptor;@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ /*---------------------------------------------------------------------------*/@\\
|
\mbox{}\verb@ /*---------------------------------------------------------------------------*/@\\
|
||||||
@ -79,12 +93,12 @@ $\langle$obdes {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@ int iHasType(void *pData, char *Type);@\\
|
\mbox{}\verb@ int iHasType(void *pData, char *Type);@\\
|
||||||
\mbox{}\verb@ @\\
|
\mbox{}\verb@ @\\
|
||||||
\mbox{}\verb@#endif @\\
|
\mbox{}\verb@#endif @\\
|
||||||
\mbox{}\verb@@$\diamond$
|
\mbox{}\verb@@{\NWsep}
|
||||||
\end{list}
|
\end{list}
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||||
\item Macro referenced in scrap ?.
|
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
|
||||||
\end{list}
|
\end{list}
|
||||||
\end{minipage}\\[4ex]
|
\end{minipage}\\[4ex]
|
||||||
\end{flushleft}
|
\end{flushleft}
|
||||||
@ -128,7 +142,7 @@ environment controllers fit this bill as well.
|
|||||||
|
|
||||||
\begin{flushleft} \small
|
\begin{flushleft} \small
|
||||||
\begin{minipage}{\linewidth} \label{scrap2}
|
\begin{minipage}{\linewidth} \label{scrap2}
|
||||||
$\langle$driv {\footnotesize ?}$\rangle\equiv$
|
$\langle\,$driv\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
@ -143,18 +157,19 @@ $\langle$driv {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@ int (*CheckStatus)(void *self, SConnection *pCon);@\\
|
\mbox{}\verb@ int (*CheckStatus)(void *self, SConnection *pCon);@\\
|
||||||
\mbox{}\verb@ float (*GetValue)(void *self, SConnection *pCon); @\\
|
\mbox{}\verb@ float (*GetValue)(void *self, SConnection *pCon); @\\
|
||||||
\mbox{}\verb@ int iErrorCount;@\\
|
\mbox{}\verb@ int iErrorCount;@\\
|
||||||
|
\mbox{}\verb@ int drivableStatus;@\\
|
||||||
\mbox{}\verb@ } IDrivable, *pIDrivable;@\\
|
\mbox{}\verb@ } IDrivable, *pIDrivable;@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ pIDrivable GetDrivableInterface(void *pObject); @\\
|
\mbox{}\verb@ pIDrivable GetDrivableInterface(void *pObject); @\\
|
||||||
\mbox{}\verb@ int GetDrivablePosition(void *pObject, SConnection *pCon,@\\
|
\mbox{}\verb@ int GetDrivablePosition(void *pObject, SConnection *pCon,@\\
|
||||||
\mbox{}\verb@ float *fPos);@\\
|
\mbox{}\verb@ float *fPos);@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@@$\diamond$
|
\mbox{}\verb@@{\NWsep}
|
||||||
\end{list}
|
\end{list}
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||||
\item Macro referenced in scrap ?.
|
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
|
||||||
\end{list}
|
\end{list}
|
||||||
\end{minipage}\\[4ex]
|
\end{minipage}\\[4ex]
|
||||||
\end{flushleft}
|
\end{flushleft}
|
||||||
@ -207,7 +222,7 @@ This is an interface for interacting with anything which counts.
|
|||||||
|
|
||||||
\begin{flushleft} \small
|
\begin{flushleft} \small
|
||||||
\begin{minipage}{\linewidth} \label{scrap3}
|
\begin{minipage}{\linewidth} \label{scrap3}
|
||||||
$\langle$count {\footnotesize ?}$\rangle\equiv$
|
$\langle\,$count\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
@ -225,12 +240,12 @@ $\langle$count {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ pICountable GetCountableInterface(void *pObject); @\\
|
\mbox{}\verb@ pICountable GetCountableInterface(void *pObject); @\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@@$\diamond$
|
\mbox{}\verb@@{\NWsep}
|
||||||
\end{list}
|
\end{list}
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||||
\item Macro referenced in scrap ?.
|
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
|
||||||
\end{list}
|
\end{list}
|
||||||
\end{minipage}\\[4ex]
|
\end{minipage}\\[4ex]
|
||||||
\end{flushleft}
|
\end{flushleft}
|
||||||
@ -272,19 +287,19 @@ The first thing to define for such an interface is the type of the callback
|
|||||||
function:
|
function:
|
||||||
\begin{flushleft} \small
|
\begin{flushleft} \small
|
||||||
\begin{minipage}{\linewidth} \label{scrap4}
|
\begin{minipage}{\linewidth} \label{scrap4}
|
||||||
$\langle$callfunc {\footnotesize ?}$\rangle\equiv$
|
$\langle\,$callfunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ typedef void (*KillFuncIT)(void *pData);@\\
|
\mbox{}\verb@ typedef void (*KillFuncIT)(void *pData);@\\
|
||||||
\mbox{}\verb@ typedef int (*SICSCallBack)(int iEvent, void *pEventData, @\\
|
\mbox{}\verb@ typedef int (*SICSCallBack)(int iEvent, void *pEventData, @\\
|
||||||
\mbox{}\verb@ void *pUserData);@\\
|
\mbox{}\verb@ void *pUserData, commandContext cc);@\\
|
||||||
\mbox{}\verb@@$\diamond$
|
\mbox{}\verb@@{\NWsep}
|
||||||
\end{list}
|
\end{list}
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||||
\item Macro referenced in scrap ?.
|
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
|
||||||
\end{list}
|
\end{list}
|
||||||
\end{minipage}\\[4ex]
|
\end{minipage}\\[4ex]
|
||||||
\end{flushleft}
|
\end{flushleft}
|
||||||
@ -306,7 +321,7 @@ interface:
|
|||||||
|
|
||||||
\begin{flushleft} \small
|
\begin{flushleft} \small
|
||||||
\begin{minipage}{\linewidth} \label{scrap5}
|
\begin{minipage}{\linewidth} \label{scrap5}
|
||||||
$\langle$cifunc {\footnotesize ?}$\rangle\equiv$
|
$\langle\,$cifunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
@ -318,7 +333,8 @@ $\langle$cifunc {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@ int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData); @\\
|
\mbox{}\verb@ int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData); @\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ /* callback client side */@\\
|
\mbox{}\verb@ /* callback client side */@\\
|
||||||
\mbox{}\verb@ long RegisterCallback(pICallBack pInterface, int iEvent, SICSCallBack pFunc,@\\
|
\mbox{}\verb@ long RegisterCallback(pICallBack pInterface, commandContext comCon, @\\
|
||||||
|
\mbox{}\verb@ int iEvent, SICSCallBack pFunc,@\\
|
||||||
\mbox{}\verb@ void *pUserData, KillFuncIT pKill);@\\
|
\mbox{}\verb@ void *pUserData, KillFuncIT pKill);@\\
|
||||||
\mbox{}\verb@ int RemoveCallback(pICallBack pInterface, long iID);@\\
|
\mbox{}\verb@ int RemoveCallback(pICallBack pInterface, long iID);@\\
|
||||||
\mbox{}\verb@ int RemoveCallback2(pICallBack pInterface, void *pUserData);@\\
|
\mbox{}\verb@ int RemoveCallback2(pICallBack pInterface, void *pUserData);@\\
|
||||||
@ -327,12 +343,12 @@ $\langle$cifunc {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@ int argc, char *argv[]); @\\
|
\mbox{}\verb@ int argc, char *argv[]); @\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ pICallBack GetCallbackInterface(void *pData); @\\
|
\mbox{}\verb@ pICallBack GetCallbackInterface(void *pData); @\\
|
||||||
\mbox{}\verb@@$\diamond$
|
\mbox{}\verb@@{\NWsep}
|
||||||
\end{list}
|
\end{list}
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||||
\item Macro referenced in scrap ?.
|
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
|
||||||
\end{list}
|
\end{list}
|
||||||
\end{minipage}\\[4ex]
|
\end{minipage}\\[4ex]
|
||||||
\end{flushleft}
|
\end{flushleft}
|
||||||
@ -389,7 +405,7 @@ This interface is used by the environment monitor in order to monitor
|
|||||||
the status of a environment controller. The interface looks like this:
|
the status of a environment controller. The interface looks like this:
|
||||||
\begin{flushleft} \small
|
\begin{flushleft} \small
|
||||||
\begin{minipage}{\linewidth} \label{scrap6}
|
\begin{minipage}{\linewidth} \label{scrap6}
|
||||||
$\langle$envir {\footnotesize ?}$\rangle\equiv$
|
$\langle\,$envir\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
@ -400,12 +416,12 @@ $\langle$envir {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@ int (*IsInTolerance)(void *self);@\\
|
\mbox{}\verb@ int (*IsInTolerance)(void *self);@\\
|
||||||
\mbox{}\verb@ int (*HandleError)(void *self);@\\
|
\mbox{}\verb@ int (*HandleError)(void *self);@\\
|
||||||
\mbox{}\verb@ } EVInterface, *pEVInterface;@\\
|
\mbox{}\verb@ } EVInterface, *pEVInterface;@\\
|
||||||
\mbox{}\verb@@$\diamond$
|
\mbox{}\verb@@{\NWsep}
|
||||||
\end{list}
|
\end{list}
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||||
\item Macro referenced in scrap ?.
|
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
|
||||||
\end{list}
|
\end{list}
|
||||||
\end{minipage}\\[4ex]
|
\end{minipage}\\[4ex]
|
||||||
\end{flushleft}
|
\end{flushleft}
|
||||||
@ -428,17 +444,17 @@ in question.
|
|||||||
The environment interface has just one function associated with it:
|
The environment interface has just one function associated with it:
|
||||||
\begin{flushleft} \small
|
\begin{flushleft} \small
|
||||||
\begin{minipage}{\linewidth} \label{scrap7}
|
\begin{minipage}{\linewidth} \label{scrap7}
|
||||||
$\langle$envfunc {\footnotesize ?}$\rangle\equiv$
|
$\langle\,$envfunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ pEVInterface CreateEVInterface(void);@\\
|
\mbox{}\verb@ pEVInterface CreateEVInterface(void);@\\
|
||||||
\mbox{}\verb@@$\diamond$
|
\mbox{}\verb@@{\NWsep}
|
||||||
\end{list}
|
\end{list}
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||||
\item Macro referenced in scrap ?.
|
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
|
||||||
\end{list}
|
\end{list}
|
||||||
\end{minipage}\\[4ex]
|
\end{minipage}\\[4ex]
|
||||||
\end{flushleft}
|
\end{flushleft}
|
||||||
@ -446,19 +462,29 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
|
|||||||
|
|
||||||
\begin{flushleft} \small
|
\begin{flushleft} \small
|
||||||
\begin{minipage}{\linewidth} \label{scrap8}
|
\begin{minipage}{\linewidth} \label{scrap8}
|
||||||
\verb@"obdes.h"@ {\footnotesize ? }$\equiv$
|
\verb@"obdes.h"@\nobreak\ {\footnotesize \NWtarget{nuweb?}{?} }$\equiv$
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@@$\langle$obdes {\footnotesize ?}$\rangle$\verb@@\\
|
\mbox{}\verb@@\hbox{$\langle\,$obdes\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
|
||||||
\mbox{}\verb@@$\diamond$
|
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@/* Additional properties used by the ANSTO site to provide more information@\\
|
||||||
|
\mbox{}\verb@ * about each object instance, especially devices.@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ void SetDescriptorKey(pObjectDescriptor self, char *keyName, char *value);@\\
|
||||||
|
\mbox{}\verb@ void SetDescriptorGroup(pObjectDescriptor self, char *group);@\\
|
||||||
|
\mbox{}\verb@ void SetDescriptorDescription(pObjectDescriptor self, char *description);@\\
|
||||||
|
\mbox{}\verb@ char * GetDescriptorKey(pObjectDescriptor self, char *keyName);@\\
|
||||||
|
\mbox{}\verb@ char * GetDescriptorGroup(pObjectDescriptor self);@\\
|
||||||
|
\mbox{}\verb@ char * GetDescriptorDescription(pObjectDescriptor self);@\\
|
||||||
|
\mbox{}\verb@@{\NWsep}
|
||||||
\end{list}
|
\end{list}
|
||||||
\vspace{-2ex}
|
\vspace{-2ex}
|
||||||
\end{minipage}\\[4ex]
|
\end{minipage}\\[4ex]
|
||||||
\end{flushleft}
|
\end{flushleft}
|
||||||
\begin{flushleft} \small
|
\begin{flushleft} \small
|
||||||
\begin{minipage}{\linewidth} \label{scrap9}
|
\begin{minipage}{\linewidth} \label{scrap9}
|
||||||
\verb@"interface.h"@ {\footnotesize ? }$\equiv$
|
\verb@"interface.h"@\nobreak\ {\footnotesize \NWtarget{nuweb?}{?} }$\equiv$
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
@ -478,6 +504,7 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@#ifndef SICSINTERFACES@\\
|
\mbox{}\verb@#ifndef SICSINTERFACES@\\
|
||||||
\mbox{}\verb@#define SICSINTERFACES@\\
|
\mbox{}\verb@#define SICSINTERFACES@\\
|
||||||
|
\mbox{}\verb@#include "commandcontext.h"@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@/* interface ID's used to recognize an interface */@\\
|
\mbox{}\verb@/* interface ID's used to recognize an interface */@\\
|
||||||
\mbox{}\verb@#define DRIVEID 513@\\
|
\mbox{}\verb@#define DRIVEID 513@\\
|
||||||
@ -486,23 +513,23 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@#define ENVIRINTERFACE 949@\\
|
\mbox{}\verb@#define ENVIRINTERFACE 949@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@/* ----------------------- The drivable interface -----------------------*/@\\
|
\mbox{}\verb@/* ----------------------- The drivable interface -----------------------*/@\\
|
||||||
\mbox{}\verb@@$\langle$driv {\footnotesize ?}$\rangle$\verb@@\\
|
\mbox{}\verb@@\hbox{$\langle\,$driv\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ pIDrivable CreateDrivableInterface(void);@\\
|
\mbox{}\verb@ pIDrivable CreateDrivableInterface(void);@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@/* ------------------------ The countable interface ---------------------*/@\\
|
\mbox{}\verb@/* ------------------------ The countable interface ---------------------*/@\\
|
||||||
\mbox{}\verb@@$\langle$count {\footnotesize ?}$\rangle$\verb@@\\
|
\mbox{}\verb@@\hbox{$\langle\,$count\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ pICountable CreateCountableInterface(void);@\\
|
\mbox{}\verb@ pICountable CreateCountableInterface(void);@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@/* ------------------------- The CallBack Interface --------------------*/@\\
|
\mbox{}\verb@/* ------------------------- The CallBack Interface --------------------*/@\\
|
||||||
\mbox{}\verb@@$\langle$callfunc {\footnotesize ?}$\rangle$\verb@@\\
|
\mbox{}\verb@@\hbox{$\langle\,$callfunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
|
||||||
\mbox{}\verb@@$\langle$cifunc {\footnotesize ?}$\rangle$\verb@@\\
|
\mbox{}\verb@@\hbox{$\langle\,$cifunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
|
||||||
\mbox{}\verb@/*---------------------- The Environment Interface --------------------*/@\\
|
\mbox{}\verb@/*---------------------- The Environment Interface --------------------*/@\\
|
||||||
\mbox{}\verb@@$\langle$envir {\footnotesize ?}$\rangle$\verb@@\\
|
\mbox{}\verb@@\hbox{$\langle\,$envir\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
|
||||||
\mbox{}\verb@@$\langle$envfunc {\footnotesize ?}$\rangle$\verb@@\\
|
\mbox{}\verb@@\hbox{$\langle\,$envfunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
|
||||||
\mbox{}\verb@#endif@\\
|
\mbox{}\verb@#endif@\\
|
||||||
\mbox{}\verb@@$\diamond$
|
\mbox{}\verb@@{\NWsep}
|
||||||
\end{list}
|
\end{list}
|
||||||
\vspace{-2ex}
|
\vspace{-2ex}
|
||||||
\end{minipage}\\[4ex]
|
\end{minipage}\\[4ex]
|
||||||
|
21
interface.w
21
interface.w
@ -45,11 +45,15 @@ Let's start with the objectdescriptor:
|
|||||||
#ifndef SICSDESCRIPTOR
|
#ifndef SICSDESCRIPTOR
|
||||||
#define SICSDESCRIPTOR
|
#define SICSDESCRIPTOR
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <ifile.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *name;
|
char *name;
|
||||||
int (*SaveStatus)(void *self, char *name,FILE *fd);
|
int (*SaveStatus)(void *self, char *name,FILE *fd);
|
||||||
void *(*GetInterface)(void *self, int iInterfaceID);
|
void *(*GetInterface)(void *self, int iInterfaceID);
|
||||||
|
char *description;
|
||||||
|
char *group;
|
||||||
|
IPair *pKeys;
|
||||||
} ObjectDescriptor, *pObjectDescriptor;
|
} ObjectDescriptor, *pObjectDescriptor;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
@ -126,6 +130,7 @@ environment controllers fit this bill as well.
|
|||||||
int (*CheckStatus)(void *self, SConnection *pCon);
|
int (*CheckStatus)(void *self, SConnection *pCon);
|
||||||
float (*GetValue)(void *self, SConnection *pCon);
|
float (*GetValue)(void *self, SConnection *pCon);
|
||||||
int iErrorCount;
|
int iErrorCount;
|
||||||
|
int drivableStatus;
|
||||||
} IDrivable, *pIDrivable;
|
} IDrivable, *pIDrivable;
|
||||||
|
|
||||||
pIDrivable GetDrivableInterface(void *pObject);
|
pIDrivable GetDrivableInterface(void *pObject);
|
||||||
@ -236,7 +241,7 @@ function:
|
|||||||
@d callfunc @{
|
@d callfunc @{
|
||||||
typedef void (*KillFuncIT)(void *pData);
|
typedef void (*KillFuncIT)(void *pData);
|
||||||
typedef int (*SICSCallBack)(int iEvent, void *pEventData,
|
typedef int (*SICSCallBack)(int iEvent, void *pEventData,
|
||||||
void *pUserData);
|
void *pUserData, commandContext cc);
|
||||||
@}
|
@}
|
||||||
|
|
||||||
The callback function is meant to return 0 for failure or 1 for success.
|
The callback function is meant to return 0 for failure or 1 for success.
|
||||||
@ -264,7 +269,8 @@ interface:
|
|||||||
int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData);
|
int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData);
|
||||||
|
|
||||||
/* callback client side */
|
/* callback client side */
|
||||||
long RegisterCallback(pICallBack pInterface, int iEvent, SICSCallBack pFunc,
|
long RegisterCallback(pICallBack pInterface, commandContext comCon,
|
||||||
|
int iEvent, SICSCallBack pFunc,
|
||||||
void *pUserData, KillFuncIT pKill);
|
void *pUserData, KillFuncIT pKill);
|
||||||
int RemoveCallback(pICallBack pInterface, long iID);
|
int RemoveCallback(pICallBack pInterface, long iID);
|
||||||
int RemoveCallback2(pICallBack pInterface, void *pUserData);
|
int RemoveCallback2(pICallBack pInterface, void *pUserData);
|
||||||
@ -360,6 +366,16 @@ The environment interface has just one function associated with it:
|
|||||||
|
|
||||||
@o obdes.h -d @{
|
@o obdes.h -d @{
|
||||||
@<obdes@>
|
@<obdes@>
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* Additional properties used by the ANSTO site to provide more information
|
||||||
|
* about each object instance, especially devices.
|
||||||
|
*/
|
||||||
|
void SetDescriptorKey(pObjectDescriptor self, char *keyName, char *value);
|
||||||
|
void SetDescriptorGroup(pObjectDescriptor self, char *group);
|
||||||
|
void SetDescriptorDescription(pObjectDescriptor self, char *description);
|
||||||
|
char * GetDescriptorKey(pObjectDescriptor self, char *keyName);
|
||||||
|
char * GetDescriptorGroup(pObjectDescriptor self);
|
||||||
|
char * GetDescriptorDescription(pObjectDescriptor self);
|
||||||
@}
|
@}
|
||||||
|
|
||||||
@o interface.h -d @{
|
@o interface.h -d @{
|
||||||
@ -379,6 +395,7 @@ The environment interface has just one function associated with it:
|
|||||||
|
|
||||||
#ifndef SICSINTERFACES
|
#ifndef SICSINTERFACES
|
||||||
#define SICSINTERFACES
|
#define SICSINTERFACES
|
||||||
|
#include "commandcontext.h"
|
||||||
|
|
||||||
/* interface ID's used to recognize an interface */
|
/* interface ID's used to recognize an interface */
|
||||||
#define DRIVEID 513
|
#define DRIVEID 513
|
||||||
|
44
lin2ang.c
44
lin2ang.c
@ -8,6 +8,9 @@
|
|||||||
copyright: see copyright.h
|
copyright: see copyright.h
|
||||||
|
|
||||||
Mark Koennecke, February 2000
|
Mark Koennecke, February 2000
|
||||||
|
|
||||||
|
added zero point handling for the Jochen
|
||||||
|
Mark Koennecke, December 2005
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -25,12 +28,13 @@
|
|||||||
pIDrivable pDriv;
|
pIDrivable pDriv;
|
||||||
pMotor lin;
|
pMotor lin;
|
||||||
float length;
|
float length;
|
||||||
|
float zero;
|
||||||
}Lin2Ang, *pLin2Ang;
|
}Lin2Ang, *pLin2Ang;
|
||||||
|
|
||||||
/*-------------------------- conversion routines -------------------------*/
|
/*-------------------------- conversion routines -------------------------*/
|
||||||
static float ang2x(pLin2Ang self, float fAngle)
|
static float ang2x(pLin2Ang self, float fAngle)
|
||||||
{
|
{
|
||||||
return self->length*sin(fAngle/RD);
|
return self->length*sin((fAngle+self->zero)/RD);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
static float x2ang(pLin2Ang self, float fX)
|
static float x2ang(pLin2Ang self, float fX)
|
||||||
@ -40,7 +44,7 @@
|
|||||||
assert(self->length > 0.);
|
assert(self->length > 0.);
|
||||||
|
|
||||||
dt = fX/self->length;
|
dt = fX/self->length;
|
||||||
return RD*asin(dt);
|
return RD*asin(dt) - self->zero;
|
||||||
}
|
}
|
||||||
/*============== functions in the interface ============================*/
|
/*============== functions in the interface ============================*/
|
||||||
static void *Lin2AngGetInterface(void *pData, int iID)
|
static void *Lin2AngGetInterface(void *pData, int iID)
|
||||||
@ -65,7 +69,8 @@
|
|||||||
if(!self)
|
if(!self)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fprintf(fd,"%s.length %f\n",name, self->length);
|
fprintf(fd,"%s length %f\n",name, self->length);
|
||||||
|
fprintf(fd,"%s zero %f\n",name, self->zero);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -99,9 +104,7 @@
|
|||||||
|
|
||||||
self = (pLin2Ang)pData;
|
self = (pLin2Ang)pData;
|
||||||
assert(self);
|
assert(self);
|
||||||
fX = self->lin->pDrivInt->GetValue(self->lin,pCon);
|
MotorGetSoftPosition(self->lin,pCon,&fX);
|
||||||
MotorGetPar(self->lin,"softzero",&zero);
|
|
||||||
fX -= zero;
|
|
||||||
return x2ang(self,fX);
|
return x2ang(self,fX);
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
@ -271,6 +274,35 @@
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* zero point */
|
||||||
|
if(strcmp(argv[1],"zero") == 0)
|
||||||
|
{
|
||||||
|
if(argc >= 3)
|
||||||
|
{
|
||||||
|
iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&dVal);
|
||||||
|
if(iRet != TCL_OK)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: zero parameter not recognised as number",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!SCMatchRights(pCon,usUser))
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: Insufficient privilege to change zero point",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
self->zero = dVal;
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"%s.zero = %f",argv[0],self->zero);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* limits */
|
/* limits */
|
||||||
if(strstr(argv[1],"lim") != NULL)
|
if(strstr(argv[1],"lim") != NULL)
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,7 @@ lin2ang's datastructure is quite simple:
|
|||||||
pIDrivable pDriv;
|
pIDrivable pDriv;
|
||||||
pMotor lin;
|
pMotor lin;
|
||||||
float length;
|
float length;
|
||||||
|
float zero;
|
||||||
}Lin2Ang;
|
}Lin2Ang;
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
The fields are:
|
The fields are:
|
||||||
@ -22,6 +23,7 @@ The fields are:
|
|||||||
functionality of this object.
|
functionality of this object.
|
||||||
\item[lin] The translation table motor to use for driving the angle.
|
\item[lin] The translation table motor to use for driving the angle.
|
||||||
\item[length] The length of the arm around which the angle pivots.
|
\item[length] The length of the arm around which the angle pivots.
|
||||||
|
\item[zero] The angular zero point of this virtual motor.
|
||||||
\end{description}
|
\end{description}
|
||||||
|
|
||||||
The interface to this is quite simple, most of the functionality is
|
The interface to this is quite simple, most of the functionality is
|
||||||
|
@ -9,4 +9,4 @@
|
|||||||
|
|
||||||
MFLAGS=-f makefile_linux$(DUMMY)
|
MFLAGS=-f makefile_linux$(DUMMY)
|
||||||
|
|
||||||
HDFROOT=/afs/psi.ch/project/sinq/linux
|
HDFROOT=/usr/local
|
||||||
|
13
macro.c
13
macro.c
@ -707,6 +707,15 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
|||||||
eOut = eWarning;
|
eOut = eWarning;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
|
eOut = eFinish;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
eOut = eEvent;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
eOut = eWarning;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
eOut = eError;
|
eOut = eError;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -868,7 +877,9 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
|||||||
length += 10;
|
length += 10;
|
||||||
pPtr = (char *)malloc(length*sizeof(char));
|
pPtr = (char *)malloc(length*sizeof(char));
|
||||||
if(pPtr == NULL){
|
if(pPtr == NULL){
|
||||||
SCWrite(pCon,"ERROR: out of memory in TclAction",eError);
|
SCWrite(pCon,
|
||||||
|
"ERROR: out of memory in TclAction",
|
||||||
|
eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memset(pPtr,0,length*sizeof(char));
|
memset(pPtr,0,length*sizeof(char));
|
||||||
|
3
make_gen
3
make_gen
@ -29,7 +29,8 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
|||||||
fourlib.o motreg.o motreglist.o anticollider.o nxdataset.o \
|
fourlib.o motreg.o motreglist.o anticollider.o nxdataset.o \
|
||||||
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) mcreader.o mccontrol.o\
|
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) mcreader.o mccontrol.o\
|
||||||
hmdata.o nxscript.o tclintimpl.o sicsdata.o mcstascounter.o \
|
hmdata.o nxscript.o tclintimpl.o sicsdata.o mcstascounter.o \
|
||||||
mcstashm.o initializer.o remob.o
|
mcstashm.o initializer.o remob.o tclmotdriv.o protocol.o \
|
||||||
|
sinfox.o
|
||||||
|
|
||||||
MOTOROBJ = motor.o simdriv.o
|
MOTOROBJ = motor.o simdriv.o
|
||||||
COUNTEROBJ = countdriv.o simcter.o counter.o
|
COUNTEROBJ = countdriv.o simcter.o counter.o
|
||||||
|
@ -7,14 +7,15 @@
|
|||||||
#==========================================================================
|
#==========================================================================
|
||||||
# assign if the National Instrument GPIB driver is available
|
# assign if the National Instrument GPIB driver is available
|
||||||
SINQDIR=/afs/psi.ch/project/sinq
|
SINQDIR=/afs/psi.ch/project/sinq
|
||||||
NI= -DHAVENI
|
NI=
|
||||||
NIOBJ= nigpib.o
|
#NI= -DHAVENI
|
||||||
NILIB=$(SINQDIR)/linux/lib/cib.o
|
#NIOBJ= nigpib.o
|
||||||
|
#NILIB=$(SINQDIR)/linux/lib/cib.o
|
||||||
|
|
||||||
include linux_def
|
include linux_def
|
||||||
|
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 $(NI) \
|
CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 -DNXXML $(NI) \
|
||||||
-Ipsi/hardsup -I. \
|
-Ipsi/hardsup -I. \
|
||||||
-fwritable-strings -DCYGNUS -DNONINTF -g $(DFORTIFY)
|
-fwritable-strings -DCYGNUS -DNONINTF -g $(DFORTIFY)
|
||||||
|
|
||||||
@ -22,10 +23,10 @@ BINTARGET = bin
|
|||||||
EXTRA=nintf.o
|
EXTRA=nintf.o
|
||||||
SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \
|
SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \
|
||||||
psi/tecs/libtecsl.a
|
psi/tecs/libtecsl.a
|
||||||
LIBS = -static -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\
|
LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\
|
||||||
-ltcl8.3 $(HDFROOT)/lib/libhdf5.a \
|
-ltcl8.4 -lmxml $(HDFROOT)/lib/libhdf5.a \
|
||||||
$(HDFROOT)/lib/libmfhdf.a $(HDFROOT)/lib/libdf.a \
|
$(HDFROOT)/lib/libmfhdf.a $(HDFROOT)/lib/libdf.a \
|
||||||
$(HDFROOT)/lib/libjpeg.a -ldl -lz -lm -lc
|
-ljpeg -ldl -lz -lm -lc
|
||||||
|
|
||||||
include make_gen
|
include make_gen
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
106
|
119
|
||||||
NEVER, EVER modify or delete this file
|
NEVER, EVER modify or delete this file
|
||||||
You'll risk eternal damnation and a reincarnation as a cockroach!|n
|
You'll risk eternal damnation and a reincarnation as a cockroach!|n
|
@ -38,7 +38,8 @@ proc mcstasdump {pid} {
|
|||||||
error "Trying to dump invalid PID: $pid"
|
error "Trying to dump invalid PID: $pid"
|
||||||
}
|
}
|
||||||
clientput "Dumping ..."
|
clientput "Dumping ..."
|
||||||
catch {eval exec /usr/bin/kill -USR2 $pid}
|
# catch {eval exec /usr/bin/kill -USR2 $pid}
|
||||||
|
catch {eval exec /bin/kill -USR2 $pid}
|
||||||
wait $mcwaittime
|
wait $mcwaittime
|
||||||
}
|
}
|
||||||
#-----------------------------------------------------------------------
|
#-----------------------------------------------------------------------
|
||||||
@ -49,7 +50,9 @@ proc mcstasdump {pid} {
|
|||||||
# the Unix FAQ this is the best solution......
|
# the Unix FAQ this is the best solution......
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
proc readPID {pid} {
|
proc readPID {pid} {
|
||||||
set f [ open "| /bin/ps -up $pid" r]
|
# set f [ open "| /bin/ps -up $pid" r]
|
||||||
|
# This is system dependent. The above works for SL, below for Suse
|
||||||
|
set f [ open "| /bin/ps up $pid" r]
|
||||||
set pstxt [read $f]
|
set pstxt [read $f]
|
||||||
close $f
|
close $f
|
||||||
return $pstxt
|
return $pstxt
|
||||||
@ -58,11 +61,13 @@ proc readPID {pid} {
|
|||||||
proc mcstasisrunning {pid} {
|
proc mcstasisrunning {pid} {
|
||||||
global runningCount runningLast
|
global runningCount runningLast
|
||||||
|
|
||||||
|
# clientput "Checking McStas PID $pid"
|
||||||
if { $pid <= 0} {
|
if { $pid <= 0} {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
set pstxt " "
|
set pstxt " "
|
||||||
set ret [catch {set pstxt [readPID $pid]} msg]
|
set ret [catch {set pstxt [readPID $pid]} msg]
|
||||||
|
# clientput "pstext = $pstxt"
|
||||||
set pslist [split $pstxt "\n"]
|
set pslist [split $pstxt "\n"]
|
||||||
if { [llength $pslist] < 2} {
|
if { [llength $pslist] < 2} {
|
||||||
return 0
|
return 0
|
||||||
@ -84,13 +89,17 @@ proc mcstaskill {pid} {
|
|||||||
error "Trying to kill invalid PID $pid"
|
error "Trying to kill invalid PID $pid"
|
||||||
}
|
}
|
||||||
clientput "Killing $pid"
|
clientput "Killing $pid"
|
||||||
catch {eval exec /usr/bin/kill -TERM $pid}
|
# catch {eval exec /usr/bin/kill -TERM $pid} msg
|
||||||
|
# On Suse kill is /bin/kill, on others it is /usr/bin/kill
|
||||||
|
catch {eval exec /bin/kill -TERM $pid} msg
|
||||||
|
clientput "Kill message $msg"
|
||||||
# catch {mccontrol finish}
|
# catch {mccontrol finish}
|
||||||
wait 10
|
wait 10
|
||||||
}
|
}
|
||||||
#-----------------------------------------------------------------------
|
#-----------------------------------------------------------------------
|
||||||
proc mcinstall {} {
|
proc mcinstall {} {
|
||||||
allowexec /usr/bin/kill
|
allowexec /usr/bin/kill
|
||||||
|
allowexec /bin/kill
|
||||||
allowexec /bin/ps
|
allowexec /bin/ps
|
||||||
Publish mcstasdump User
|
Publish mcstasdump User
|
||||||
Publish mcstasisrunning User
|
Publish mcstasisrunning User
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# Initialization script for a virtual DMC instrument using a McStas
|
# Initialization script for a virtual DMC instrument using a McStas
|
||||||
# simulationas a data source
|
# simulationas a data source
|
||||||
#
|
#
|
||||||
@ -6,12 +6,12 @@
|
|||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# O P T I O N S
|
# O P T I O N S
|
||||||
|
|
||||||
set home $env(HOME)/src/workspace/sics/mcstas/dmc
|
set home $env(HOME)/psi/sics/mcstas/dmc
|
||||||
|
|
||||||
#--------------------------------- first all the server options are set
|
#--------------------------------- first all the server options are set
|
||||||
#ServerOption RedirectFile $home/stdcdmc
|
#ServerOption RedirectFile $home/stdcdmc
|
||||||
ServerOption ReadTimeOut 1
|
ServerOption ReadTimeOut 10
|
||||||
ServerOption AcceptTimeOut 1
|
ServerOption AcceptTimeOut 10
|
||||||
ServerOption ReadUserPasswdTimeout 500000
|
ServerOption ReadUserPasswdTimeout 500000
|
||||||
ServerOption LogFileBaseName "$home/vdmclog"
|
ServerOption LogFileBaseName "$home/vdmclog"
|
||||||
ServerOption LogFileDir $home/
|
ServerOption LogFileDir $home/
|
||||||
@ -137,3 +137,13 @@ source $home/vdmccom.tcl
|
|||||||
#-------------------- configure commandlog
|
#-------------------- configure commandlog
|
||||||
commandlog auto
|
commandlog auto
|
||||||
commandlog intervall 5
|
commandlog intervall 5
|
||||||
|
|
||||||
|
#----------- enable sycamore
|
||||||
|
InstallProtocolHandler
|
||||||
|
InstallSinfox
|
||||||
|
source sycFormat.tcl
|
||||||
|
source /usr/lib/tcllib1.6.1/stooop/stooop.tcl
|
||||||
|
namespace import stooop::*
|
||||||
|
source sinfo.tcl
|
||||||
|
source sycamore.tcl
|
||||||
|
Publish sinfo Spy
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
source $home/mcsupport.tcl
|
source $home/mcsupport.tcl
|
||||||
|
|
||||||
if { [info exists vdmcinit] == 0 } {
|
if { [info exists vdmcinit] == 0 } {
|
||||||
set vdmcinit 1
|
set vdmcinit 1f
|
||||||
Publish LogBook Spy
|
Publish LogBook Spy
|
||||||
Publish count User
|
Publish count User
|
||||||
Publish Repeat User
|
Publish Repeat User
|
||||||
@ -187,10 +187,9 @@ proc copydmcdata { } {
|
|||||||
mcreader insertmon \
|
mcreader insertmon \
|
||||||
"/$mcversion/DMC_diff/dmc.xml/PSD_sample/values" \
|
"/$mcversion/DMC_diff/dmc.xml/PSD_sample/values" \
|
||||||
counter 1 [expr 1./350]
|
counter 1 [expr 1./350]
|
||||||
mcreader insertmon \
|
# mcreader insertmon \
|
||||||
"/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values" \
|
# "/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values" \
|
||||||
counter 4
|
# counter 4
|
||||||
set hmScale [SplitReply [counter getmonitor 4]]
|
|
||||||
set val [mcreader getfield\
|
set val [mcreader getfield\
|
||||||
"/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values"]
|
"/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values"]
|
||||||
set l [split $val]
|
set l [split $val]
|
||||||
@ -212,7 +211,6 @@ proc dmcdump {pid} {
|
|||||||
#--do nothing: progress is doing it for us
|
#--do nothing: progress is doing it for us
|
||||||
}
|
}
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
#mccontrol configure mcstart rundmcsim
|
|
||||||
mccontrol configure mcstart rundmcoptsim
|
mccontrol configure mcstart rundmcoptsim
|
||||||
mccontrol configure mccopydata copydmcdata
|
mccontrol configure mccopydata copydmcdata
|
||||||
mccontrol configure update 30
|
mccontrol configure update 30
|
||||||
|
@ -201,13 +201,13 @@ a9 precision 0.010000
|
|||||||
a9 ignorefault 0.000000
|
a9 ignorefault 0.000000
|
||||||
a9 AccessCode 2.000000
|
a9 AccessCode 2.000000
|
||||||
a9 movecount 10.000000
|
a9 movecount 10.000000
|
||||||
title UNKNOWN
|
title D3C
|
||||||
title setAccess 2
|
title setAccess 2
|
||||||
user UNKNOWN
|
user UNKNOWN
|
||||||
user setAccess 2
|
user setAccess 2
|
||||||
collimation UNKNOWN
|
collimation UNKNOWN
|
||||||
collimation setAccess 2
|
collimation setAccess 2
|
||||||
sampleintern na2ca3al2f14
|
sampleintern D3C
|
||||||
sampleintern setAccess 2
|
sampleintern setAccess 2
|
||||||
comment1 UNKNOWN
|
comment1 UNKNOWN
|
||||||
comment1 setAccess 2
|
comment1 setAccess 2
|
||||||
@ -215,7 +215,7 @@ comment2 UNKNOWN
|
|||||||
comment2 setAccess 2
|
comment2 setAccess 2
|
||||||
comment3 UNKNOWN
|
comment3 UNKNOWN
|
||||||
comment3 setAccess 2
|
comment3 setAccess 2
|
||||||
starttime 2005-10-19 11:11:44
|
starttime 2005-12-20 05:13:05
|
||||||
starttime setAccess 2
|
starttime setAccess 2
|
||||||
adress UNKNOWN
|
adress UNKNOWN
|
||||||
adress setAccess 2
|
adress setAccess 2
|
||||||
|
59
motor.c
59
motor.c
@ -52,6 +52,7 @@
|
|||||||
#include "splitter.h"
|
#include "splitter.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
#include "servlog.h"
|
#include "servlog.h"
|
||||||
|
#include "tclmotdriv.h"
|
||||||
#include "site.h"
|
#include "site.h"
|
||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
some lokal defines
|
some lokal defines
|
||||||
@ -385,6 +386,12 @@ static void handleMoveCallback(pMotor self, SConnection *pCon)
|
|||||||
self = (pMotor)sulf;
|
self = (pMotor)sulf;
|
||||||
|
|
||||||
status = evaluateStatus(self,pCon);
|
status = evaluateStatus(self,pCon);
|
||||||
|
if (self->pDrivInt->drivableStatus!=status) {
|
||||||
|
((SConnection *)pCon)->conEventType=STATUS;
|
||||||
|
((SConnection *)pCon)->conStatus=status;
|
||||||
|
SCWrite(pCon, "", eEvent);
|
||||||
|
self->pDrivInt->drivableStatus=status;
|
||||||
|
}
|
||||||
if(status == HWBusy)
|
if(status == HWBusy)
|
||||||
{
|
{
|
||||||
handleMoveCallback(self,pCon);
|
handleMoveCallback(self,pCon);
|
||||||
@ -741,7 +748,7 @@ extern void KillPiPiezo(void *pData);
|
|||||||
iRet = MotorCheckBoundary(self,fNew,&fHard,pBueffel,511);
|
iRet = MotorCheckBoundary(self,fNew,&fHard,pBueffel,511);
|
||||||
if(!iRet)
|
if(!iRet)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,pBueffel,eWarning);
|
SCWrite(pCon,pBueffel,eStatus);
|
||||||
SCSetInterrupt(pCon,eAbortOperation);
|
SCSetInterrupt(pCon,eAbortOperation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1000,6 +1007,21 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
|||||||
SCWrite(pCon,pBueffel,eError);
|
SCWrite(pCon,pBueffel,eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}else if (strcmp(argv[2],"tclmot") == 0)
|
||||||
|
{
|
||||||
|
pDriver = CreateTclMotDriv(pCon,argc,argv);
|
||||||
|
if(!pDriver)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* create the motor */
|
||||||
|
pNew = MotorInit("TCLMOT",argv[1],pDriver);
|
||||||
|
if(!pNew)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"Failure to create motor %s",argv[1]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1034,8 +1056,8 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
|||||||
int i, iLen;
|
int i, iLen;
|
||||||
|
|
||||||
iLen = ObParLength(self->ParArray);
|
iLen = ObParLength(self->ParArray);
|
||||||
sprintf(pBueffel,"Parameter Listing for motor %s\n",self->name);
|
sprintf(pBueffel,"Parameter Listing for motor %s",self->name);
|
||||||
SCWrite(pCon,pBueffel,eStatus);
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
snprintf(pBueffel,511,"%s.hardupperlim = %f",self->name,
|
snprintf(pBueffel,511,"%s.hardupperlim = %f",self->name,
|
||||||
self->pDriver->fUpper);
|
self->pDriver->fUpper);
|
||||||
SCWrite(pCon,pBueffel,eValue);
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
@ -1073,6 +1095,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
char *pName;
|
char *pName;
|
||||||
SConnection *pCon;
|
SConnection *pCon;
|
||||||
|
float lastValue;
|
||||||
} MotInfo, *pMotInfo;
|
} MotInfo, *pMotInfo;
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
static void KillInfo(void *pData)
|
static void KillInfo(void *pData)
|
||||||
@ -1088,7 +1111,8 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
|||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
/*------------------- The CallBack function for interest ------------------*/
|
/*------------------- The CallBack function for interest ------------------*/
|
||||||
static int InterestCallback(int iEvent, void *pEvent, void *pUser)
|
static int InterestCallback(int iEvent, void *pEvent, void *pUser,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
pMotInfo pInfo = NULL;
|
pMotInfo pInfo = NULL;
|
||||||
char pBueffel[80];
|
char pBueffel[80];
|
||||||
@ -1100,8 +1124,12 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
|||||||
psCall = (MotCallback *)pEvent;
|
psCall = (MotCallback *)pEvent;
|
||||||
pInfo = (MotInfo *)pUser;
|
pInfo = (MotInfo *)pUser;
|
||||||
|
|
||||||
sprintf(pBueffel,"%s.position = %f ", pInfo->pName, psCall->fVal);
|
if (pInfo->lastValue != psCall->fVal) {
|
||||||
SCWrite(pInfo->pCon,pBueffel,eValue);
|
pInfo->lastValue = psCall->fVal;
|
||||||
|
(pInfo->pCon)->conEventType=POSITION;
|
||||||
|
sprintf(pBueffel,"%s.position = %f ", pInfo->pName, pInfo->lastValue);
|
||||||
|
SCWriteInContext(pInfo->pCon,pBueffel,eEvent,cc);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
@ -1113,7 +1141,8 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*------------------------ The endscript callback function ----------------*/
|
/*------------------------ The endscript callback function ----------------*/
|
||||||
static int EndScriptCallback(int iEvent, void *pEvent, void *pUser)
|
static int EndScriptCallback(int iEvent, void *pEvent, void *pUser,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
char *pScript = NULL;
|
char *pScript = NULL;
|
||||||
MotCallback *psCall;
|
MotCallback *psCall;
|
||||||
@ -1178,7 +1207,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
|||||||
if(!iRet)
|
if(!iRet)
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"Error obtaining position for %s",argv[0]);
|
sprintf(pBueffel,"Error obtaining position for %s",argv[0]);
|
||||||
SCWrite(pCon,pBueffel,eValue);
|
SCWrite(pCon,pBueffel,eError);
|
||||||
DeleteTokenList(pList);
|
DeleteTokenList(pList);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1220,7 +1249,17 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
|||||||
}
|
}
|
||||||
pMoti->pName = strdup(argv[0]);
|
pMoti->pName = strdup(argv[0]);
|
||||||
pMoti->pCon = pCon;
|
pMoti->pCon = pCon;
|
||||||
lID = RegisterCallback(self->pCall, MOTDRIVE, InterestCallback,
|
iRet = MotorGetSoftPosition(self,pCon,&fValue);
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"Failed to register interest, Reason:Error obtaining current position for %s",argv[0]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
DeleteTokenList(pList);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pMoti->lastValue = fValue;
|
||||||
|
|
||||||
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),MOTDRIVE, InterestCallback,
|
||||||
pMoti, KillInfo);
|
pMoti, KillInfo);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
DeleteTokenList(pList);
|
DeleteTokenList(pList);
|
||||||
@ -1252,7 +1291,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
self->endScriptID =
|
self->endScriptID =
|
||||||
RegisterCallback(self->pCall, MOTEND, EndScriptCallback,
|
RegisterCallback(self->pCall, SCGetContext(pCon),MOTEND, EndScriptCallback,
|
||||||
strdup(pCurrent->text), KillScript);
|
strdup(pCurrent->text), KillScript);
|
||||||
SCRegister(pCon,pSics, self->pCall,self->endScriptID);
|
SCRegister(pCon,pSics, self->pCall,self->endScriptID);
|
||||||
DeleteTokenList(pList);
|
DeleteTokenList(pList);
|
||||||
|
34
nserver.c
34
nserver.c
@ -6,10 +6,8 @@
|
|||||||
|
|
||||||
Mark Koennecke, October 1996
|
Mark Koennecke, October 1996
|
||||||
Revised for use with tasker: Mark Koennecke, September 1997
|
Revised for use with tasker: Mark Koennecke, September 1997
|
||||||
|
Added code to redirect stdout/sterr to file, Mark Koennecke, May 2000
|
||||||
Added code to redirect stdout/sterr to file.
|
Define handler in InitServer to ignore SIGPIPE. Paul Hathaway, May 2004
|
||||||
|
|
||||||
Mark Koennecke, May 2000
|
|
||||||
|
|
||||||
Copyright: see copyright.h
|
Copyright: see copyright.h
|
||||||
----------------------------------------------------------------------------*/
|
----------------------------------------------------------------------------*/
|
||||||
@ -19,6 +17,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "sics.h"
|
#include "sics.h"
|
||||||
@ -93,6 +92,8 @@
|
|||||||
memset(self,0,sizeof(SicsServer));
|
memset(self,0,sizeof(SicsServer));
|
||||||
*pServ = self;
|
*pServ = self;
|
||||||
|
|
||||||
|
/* define any signal handlers */
|
||||||
|
signal(SIGPIPE,SIG_IGN);
|
||||||
|
|
||||||
/* configure fortify */
|
/* configure fortify */
|
||||||
iFortifyScope = Fortify_EnterScope();
|
iFortifyScope = Fortify_EnterScope();
|
||||||
@ -458,7 +459,7 @@
|
|||||||
/*--------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------
|
||||||
UserWait: the user command for waiting, expects one arg:
|
UserWait: the user command for waiting, expects one arg:
|
||||||
time to wait in seconds
|
time to wait in seconds
|
||||||
*/
|
---------------------------------------------------------------------------*/
|
||||||
int UserWait(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int UserWait(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -517,7 +518,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
int SicsWait(long lTime)
|
int SicsWaitOld(long lTime)
|
||||||
{
|
{
|
||||||
WaitStruct sWait;
|
WaitStruct sWait;
|
||||||
pTaskMan pTasker = NULL;
|
pTaskMan pTasker = NULL;
|
||||||
@ -537,7 +538,28 @@
|
|||||||
TaskWait(pTasker,lID);
|
TaskWait(pTasker,lID);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
The new SicsWait is still on probation. It prevents commands to be
|
||||||
|
executed on the same task on which the Sicswait is acting.
|
||||||
|
M.K. December 2005
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
int SicsWait(long lTime)
|
||||||
|
{
|
||||||
|
pTaskMan pTasker = NULL;
|
||||||
|
time_t endTime;
|
||||||
|
|
||||||
|
if(pServ->simMode)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
pTasker = GetTasker();
|
||||||
|
endTime = time(NULL) + lTime;
|
||||||
|
while(time(NULL) < endTime)
|
||||||
|
{
|
||||||
|
TaskYield(pTasker);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
void ServerWriteGlobal(char *pMessage,int iOut)
|
void ServerWriteGlobal(char *pMessage,int iOut)
|
||||||
{
|
{
|
||||||
|
10
nxupdate.c
10
nxupdate.c
@ -46,7 +46,8 @@ static int UpdateTask(void *pData){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------*/
|
||||||
static int CountCallback(int iEvent, void *pEventData, void *pUser){
|
static int CountCallback(int iEvent, void *pEventData, void *pUser,
|
||||||
|
commandContext cc){
|
||||||
pNXupdate self = NULL;
|
pNXupdate self = NULL;
|
||||||
SConnection *pCon = NULL;
|
SConnection *pCon = NULL;
|
||||||
|
|
||||||
@ -257,6 +258,7 @@ int UpdateFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
char pBueffel[256];
|
char pBueffel[256];
|
||||||
pNXupdate self = NULL;
|
pNXupdate self = NULL;
|
||||||
CommandList *pCom = NULL;
|
CommandList *pCom = NULL;
|
||||||
|
commandContext comCon;
|
||||||
|
|
||||||
if(argc < 3){
|
if(argc < 3){
|
||||||
SCWrite(pCon,"ERROR: insuffcient number of argument to UpdateFactory",
|
SCWrite(pCon,"ERROR: insuffcient number of argument to UpdateFactory",
|
||||||
@ -309,9 +311,11 @@ int UpdateFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
/*
|
/*
|
||||||
register callbacks
|
register callbacks
|
||||||
*/
|
*/
|
||||||
RegisterCallback(pCall,COUNTSTART,CountCallback,
|
comCon.transID = 0;
|
||||||
|
strncpy(comCon.deviceID,"internal",SCDEVIDLEN);
|
||||||
|
RegisterCallback(pCall,comCon,COUNTSTART,CountCallback,
|
||||||
self,NULL);
|
self,NULL);
|
||||||
RegisterCallback(pCall,COUNTEND,CountCallback,
|
RegisterCallback(pCall,comCon,COUNTEND,CountCallback,
|
||||||
self,NULL);
|
self,NULL);
|
||||||
|
|
||||||
AddCommand(pSics,argv[1],UpdateAction,KillUpdate,self);
|
AddCommand(pSics,argv[1],UpdateAction,KillUpdate,self);
|
||||||
|
78
obdes.c
78
obdes.c
@ -66,6 +66,9 @@
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
pRes->name = strdup(name);
|
pRes->name = strdup(name);
|
||||||
|
pRes->pKeys = NULL;
|
||||||
|
pRes->description = NULL;
|
||||||
|
pRes->group = NULL;
|
||||||
pRes->SaveStatus = DefaultSave;
|
pRes->SaveStatus = DefaultSave;
|
||||||
pRes->GetInterface = DefaultGetInterface;
|
pRes->GetInterface = DefaultGetInterface;
|
||||||
return pRes;
|
return pRes;
|
||||||
@ -74,10 +77,10 @@
|
|||||||
void DeleteDescriptor(pObjectDescriptor self)
|
void DeleteDescriptor(pObjectDescriptor self)
|
||||||
{
|
{
|
||||||
assert(self);
|
assert(self);
|
||||||
|
if(self->name) free(self->name);
|
||||||
if(self->name)
|
if(self->description) free(self->description);
|
||||||
free(self->name);
|
if(self->group) free(self->group);
|
||||||
|
if(self->pKeys) IFDeleteOptions(self->pKeys);
|
||||||
free(self);
|
free(self);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -134,11 +137,72 @@
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
pObjectDescriptor FindDescriptor(void *pData)
|
pObjectDescriptor FindDescriptor(void *pData)
|
||||||
{
|
{
|
||||||
pDummy pDum = NULL;
|
pDummy pDum = NULL;
|
||||||
|
|
||||||
assert(pData);
|
assert(pData);
|
||||||
pDum = (pDummy)pData;
|
pDum = (pDummy)pData;
|
||||||
return pDum->pDescriptor;
|
return pDum->pDescriptor;
|
||||||
}
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
void SetDescriptorKey(pObjectDescriptor self, char *keyName, char *eltValue)
|
||||||
|
{
|
||||||
|
if(NULL!=self)
|
||||||
|
{
|
||||||
|
IFSetOption(self->pKeys,keyName,eltValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
void SetDescriptorGroup(pObjectDescriptor self, char *group)
|
||||||
|
{
|
||||||
|
if(NULL==self)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(NULL != self->group)
|
||||||
|
{
|
||||||
|
free(self->group);
|
||||||
|
}
|
||||||
|
self->group = strdup(group);
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
void SetDescriptorDescription(pObjectDescriptor self, char *description)
|
||||||
|
{
|
||||||
|
if(NULL==self)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(NULL != self->description)
|
||||||
|
{
|
||||||
|
free(self->description);
|
||||||
|
}
|
||||||
|
self->description = strdup(description);
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
char * GetDescriptorKey(pObjectDescriptor self, char *keyName)
|
||||||
|
{
|
||||||
|
if(NULL==self)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return IFindOption(self->pKeys,keyName);
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
char * GetDescriptorGroup(pObjectDescriptor self)
|
||||||
|
{
|
||||||
|
if(NULL==self)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return self->group;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
char * GetDescriptorDescription(pObjectDescriptor self)
|
||||||
|
{
|
||||||
|
if(NULL==self)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return self->description;
|
||||||
|
}
|
||||||
|
18
obdes.h
18
obdes.h
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 361 "interface.w"
|
#line 367 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
#line 29 "interface.w"
|
#line 29 "interface.w"
|
||||||
@ -22,11 +22,15 @@
|
|||||||
#ifndef SICSDESCRIPTOR
|
#ifndef SICSDESCRIPTOR
|
||||||
#define SICSDESCRIPTOR
|
#define SICSDESCRIPTOR
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <ifile.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *name;
|
char *name;
|
||||||
int (*SaveStatus)(void *self, char *name,FILE *fd);
|
int (*SaveStatus)(void *self, char *name,FILE *fd);
|
||||||
void *(*GetInterface)(void *self, int iInterfaceID);
|
void *(*GetInterface)(void *self, int iInterfaceID);
|
||||||
|
char *description;
|
||||||
|
char *group;
|
||||||
|
IPair *pKeys;
|
||||||
} ObjectDescriptor, *pObjectDescriptor;
|
} ObjectDescriptor, *pObjectDescriptor;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
@ -52,5 +56,15 @@ typedef struct {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#line 362 "interface.w"
|
#line 368 "interface.w"
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* Additional properties used by the ANSTO site to provide more information
|
||||||
|
* about each object instance, especially devices.
|
||||||
|
*/
|
||||||
|
void SetDescriptorKey(pObjectDescriptor self, char *keyName, char *value);
|
||||||
|
void SetDescriptorGroup(pObjectDescriptor self, char *group);
|
||||||
|
void SetDescriptorDescription(pObjectDescriptor self, char *description);
|
||||||
|
char * GetDescriptorKey(pObjectDescriptor self, char *keyName);
|
||||||
|
char * GetDescriptorGroup(pObjectDescriptor self);
|
||||||
|
char * GetDescriptorDescription(pObjectDescriptor self);
|
||||||
|
10
ofac.c
10
ofac.c
@ -114,6 +114,8 @@
|
|||||||
#include "tasscanub.h"
|
#include "tasscanub.h"
|
||||||
#include "mcreader.h"
|
#include "mcreader.h"
|
||||||
#include "mccontrol.h"
|
#include "mccontrol.h"
|
||||||
|
#include "protocol.h"
|
||||||
|
#include "sinfox.h"
|
||||||
/*----------------------- Server options creation -------------------------*/
|
/*----------------------- Server options creation -------------------------*/
|
||||||
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
@ -237,6 +239,7 @@
|
|||||||
AddCommand(pInter,"sicsdatafactory",SICSDataFactory,NULL,NULL);
|
AddCommand(pInter,"sicsdatafactory",SICSDataFactory,NULL,NULL);
|
||||||
AddCommand(pInter,"scriptcallback",CallbackScript,NULL,NULL);
|
AddCommand(pInter,"scriptcallback",CallbackScript,NULL,NULL);
|
||||||
AddCommand(pInter,"help",SicsHelp,KillHelp,NULL);
|
AddCommand(pInter,"help",SicsHelp,KillHelp,NULL);
|
||||||
|
AddCommand(pInter,"sicsatt",SicsAtt,NULL,NULL);
|
||||||
|
|
||||||
/* commands to do with the executor. Only StopExe carries the
|
/* commands to do with the executor. Only StopExe carries the
|
||||||
DeleteFunction in order to avoid double deletion. All the
|
DeleteFunction in order to avoid double deletion. All the
|
||||||
@ -311,6 +314,10 @@
|
|||||||
McStasReaderFactory,NULL,NULL);
|
McStasReaderFactory,NULL,NULL);
|
||||||
AddCommand(pInter,"MakeMcStasController",
|
AddCommand(pInter,"MakeMcStasController",
|
||||||
McStasControllerFactory,NULL,NULL);
|
McStasControllerFactory,NULL,NULL);
|
||||||
|
AddCommand(pInter,"InstallProtocolHandler",
|
||||||
|
InstallProtocol,NULL,NULL);
|
||||||
|
AddCommand(pInter,"InstallSinfox",
|
||||||
|
InstallSinfox,NULL,NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
install site specific commands
|
install site specific commands
|
||||||
@ -376,7 +383,8 @@
|
|||||||
RemoveCommand(pSics,"MakeTasUB");
|
RemoveCommand(pSics,"MakeTasUB");
|
||||||
RemoveCommand(pSics,"MakeTasScan");
|
RemoveCommand(pSics,"MakeTasScan");
|
||||||
RemoveCommand(pSics,"MakemcStasReader");
|
RemoveCommand(pSics,"MakemcStasReader");
|
||||||
|
RemoveCommand(pSics,"InstallProtocolHandler");
|
||||||
|
RemoveCommand(pSics,"InstallSinfox");
|
||||||
/*
|
/*
|
||||||
remove site specific installation commands
|
remove site specific installation commands
|
||||||
*/
|
*/
|
||||||
|
@ -15,8 +15,11 @@
|
|||||||
"inerror",
|
"inerror",
|
||||||
"status",
|
"status",
|
||||||
"value",
|
"value",
|
||||||
|
"start",
|
||||||
|
"finish",
|
||||||
|
"event",
|
||||||
"warning",
|
"warning",
|
||||||
"error",
|
"error",
|
||||||
NULL };
|
NULL };
|
||||||
static int iNoCodes = 7;
|
static int iNoCodes = 10;
|
||||||
#endif
|
#endif
|
||||||
|
@ -147,7 +147,8 @@
|
|||||||
return self->fCPS;
|
return self->fCPS;
|
||||||
}
|
}
|
||||||
/*------------------- The CallBack function for interest ------------------*/
|
/*------------------- The CallBack function for interest ------------------*/
|
||||||
static int InterestCallback(int iEvent, void *pEvent, void *pUser)
|
static int InterestCallback(int iEvent, void *pEvent, void *pUser,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
float *fPos;
|
float *fPos;
|
||||||
SConnection *pCon;
|
SConnection *pCon;
|
||||||
@ -160,7 +161,7 @@
|
|||||||
pCon = (SConnection *)pUser;
|
pCon = (SConnection *)pUser;
|
||||||
|
|
||||||
sprintf(pBueffel,"Performance = %f", *fPos);
|
sprintf(pBueffel,"Performance = %f", *fPos);
|
||||||
SCWrite(pCon,pBueffel,eValue);
|
SCWriteInContext(pCon,pBueffel,eValue,cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
@ -206,7 +207,8 @@
|
|||||||
|
|
||||||
if(strcmp(argv[1],"interest") == 0)
|
if(strcmp(argv[1],"interest") == 0)
|
||||||
{
|
{
|
||||||
lID = RegisterCallback(self->pCall, VALUECHANGE, InterestCallback,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||||
|
VALUECHANGE, InterestCallback,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
|
616
protocol.c
Normal file
616
protocol.c
Normal file
@ -0,0 +1,616 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
ANSTO Protocol Command Object
|
||||||
|
Paul Hathaway, November, 2004
|
||||||
|
Copyright: See copyright.txt
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <conman.h>
|
||||||
|
#include <obdes.h>
|
||||||
|
#include <sics.h>
|
||||||
|
#include <conman.h>
|
||||||
|
#include <fupa.h>
|
||||||
|
#include <splitter.h>
|
||||||
|
#include <outcode.c>
|
||||||
|
#include <dynstring.h>
|
||||||
|
#include "protocol.h"
|
||||||
|
|
||||||
|
#define MAXMSG 1024
|
||||||
|
#define INIT_STR_SIZE 256
|
||||||
|
#define STR_RESIZE_LENGTH 256
|
||||||
|
|
||||||
|
typedef struct __Protocol {
|
||||||
|
pObjectDescriptor pDes; /* required as first field */
|
||||||
|
char *name; /* protocol handler name */
|
||||||
|
char *version; /* protocol version string */
|
||||||
|
int iNumPros; /* number of valid protocols? */
|
||||||
|
writeFunc defaultWriter; /* default write function */
|
||||||
|
int isDefaultSet;
|
||||||
|
char *pProList[5]; /* list of valid protocols? */
|
||||||
|
} Protocol;
|
||||||
|
|
||||||
|
char *pEventType[]={
|
||||||
|
"VALUECHANGE", /* 0 */
|
||||||
|
"MOTDRIVE", /* 1 */
|
||||||
|
"MONITOR", /* 2 */
|
||||||
|
"ROTSTART", /* 3 */
|
||||||
|
"ROTMOVE", /* 4 */
|
||||||
|
"SCANEND", /* 5 */
|
||||||
|
"SCANSTART", /* 6 */
|
||||||
|
"SCANPOINT", /* 7 */
|
||||||
|
"WLCHANGE", /* 8 */
|
||||||
|
"REFLECTIONDONE", /* 9 */
|
||||||
|
"COUNTSTART", /* 10 */
|
||||||
|
"COUNTEND", /* 11 */
|
||||||
|
"FILELOADED", /* 12 */
|
||||||
|
"MOTEND", /* 13 */
|
||||||
|
"BATCHSTART", /* 14 */
|
||||||
|
"BATCHAREA", /* 15 */
|
||||||
|
"BATCHEND", /* 16 */
|
||||||
|
"DRIVSTAT", /* 17 */
|
||||||
|
"STATUS", /* 18 */
|
||||||
|
"POSITION" /* 19 Motor position events, ffr */
|
||||||
|
};
|
||||||
|
|
||||||
|
char *pStatus[]={
|
||||||
|
"UNSET",
|
||||||
|
"OKOK", /* 1 */
|
||||||
|
"HWIdle", /* 2 */
|
||||||
|
"HWBusy", /* 3 */
|
||||||
|
"HWFault", /* 4 */
|
||||||
|
"HWPosFault", /* 5 */
|
||||||
|
"HWCrash", /* 6 */
|
||||||
|
"NOMEMORY", /* 7 */
|
||||||
|
"HWNoBeam", /* 8 */
|
||||||
|
"HWPause", /* 9 */
|
||||||
|
"HWWarn", /* 10 */
|
||||||
|
"HWRedo", /* 11 */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct __Protocol *pProtocol;
|
||||||
|
|
||||||
|
/* alternate implementation of protocol list if data hiding in
|
||||||
|
* Protocol struct via CreateProtocol does not work
|
||||||
|
* static char *pPros[] = {
|
||||||
|
* "default",
|
||||||
|
* "outcodes",
|
||||||
|
* "sycamore"
|
||||||
|
* NULL };
|
||||||
|
* static int iNumPros = 3
|
||||||
|
*/
|
||||||
|
|
||||||
|
pProtocol CreateProtocol(void);
|
||||||
|
static int ProtocolOptions(SConnection* pCon, pProtocol pPro);
|
||||||
|
static int ProtocolHelp(SConnection* pCon, Protocol* pPro);
|
||||||
|
static int ProtocolSet(SConnection* pCon, Protocol* pPro, char *pProName);
|
||||||
|
static int ProtocolGet(SConnection* pCon, Protocol* pPro, char *pProName,
|
||||||
|
int *pIndex);
|
||||||
|
static int ProtocolList(SConnection* pCon, Protocol* pPro);
|
||||||
|
int ProtocolAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
static int EnumChoice(char *pList[], int iLength, char *pInput);
|
||||||
|
static int InitDefaultProtocol(SConnection* pCon, Protocol *pPro);
|
||||||
|
|
||||||
|
/* Signatures for protocol writers implemented in this file */
|
||||||
|
int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
pProtocol CreateProtocol(void)
|
||||||
|
{
|
||||||
|
int i, iNumPros = 4;
|
||||||
|
char *pPros[5] = {"default",
|
||||||
|
"normal",
|
||||||
|
"withcode",
|
||||||
|
"sycamore",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
pProtocol pNew = NULL;
|
||||||
|
|
||||||
|
pNew = (pProtocol)malloc(sizeof(Protocol));
|
||||||
|
if(!pNew)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pNew->pDes = CreateDescriptor("Protocol");
|
||||||
|
if(!pNew->pDes)
|
||||||
|
{
|
||||||
|
free(pNew);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pNew->name = strdup("protocol");
|
||||||
|
pNew->version = strdup("1.0");
|
||||||
|
pNew->iNumPros = iNumPros;
|
||||||
|
// pNew->pProList = (char *)malloc(sizeof(pPros));
|
||||||
|
for(i=0;i<iNumPros;i++)
|
||||||
|
{
|
||||||
|
pNew->pProList[i] = strdup(pPros[i]);
|
||||||
|
}
|
||||||
|
pNew->pProList[i] = NULL;
|
||||||
|
pNew->isDefaultSet = 0;
|
||||||
|
|
||||||
|
return pNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
void DeleteProtocol(void *self)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
pProtocol pOld = (pProtocol)self;
|
||||||
|
|
||||||
|
if(NULL==pOld)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(pOld->name)
|
||||||
|
{
|
||||||
|
free(pOld->name);
|
||||||
|
}
|
||||||
|
if(pOld->pDes)
|
||||||
|
{
|
||||||
|
DeleteDescriptor(pOld->pDes);
|
||||||
|
}
|
||||||
|
if(pOld->version)
|
||||||
|
{
|
||||||
|
free(pOld->version);
|
||||||
|
}
|
||||||
|
if(pOld->pProList)
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
while(NULL!=pOld->pProList[i])
|
||||||
|
{
|
||||||
|
free(pOld->pProList[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(pOld);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------*/
|
||||||
|
static int ContextDo(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]){
|
||||||
|
commandContext comCon;
|
||||||
|
char command[1024];
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if(argc < 3){
|
||||||
|
SCWrite(pCon,"ERROR: insufficient arguments to contextdo",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = Tcl_GetInt(pSics->pTcl,argv[1],&comCon.transID);
|
||||||
|
if(status != TCL_OK){
|
||||||
|
snprintf(command,1023,"ERROR: failed to convert %s to transaction ID", argv[1]);
|
||||||
|
SCWrite(pCon,command,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
strncpy(comCon.deviceID,argv[2],SCDEVIDLEN);
|
||||||
|
memset(command,0,1024*sizeof(char));
|
||||||
|
Arg2Text(argc-2,&argv[2],command,1023);
|
||||||
|
|
||||||
|
SCPushContext2(pCon,comCon);
|
||||||
|
status = InterpExecute(pSics,pCon,command);
|
||||||
|
SCPopContext(pCon);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
int InstallProtocol(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
pProtocol pNew = NULL;
|
||||||
|
pNew = CreateProtocol();
|
||||||
|
if(NULL==pNew)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"No memory to create Protocol",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
AddCommand(pSics,"Protocol",ProtocolAction,DeleteProtocol,pNew);
|
||||||
|
AddCommand(pSics,"contextdo",ContextDo,NULL,NULL);
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static int ProtocolOptions(SConnection* pCon, pProtocol pPro)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char pBuffer[80];
|
||||||
|
for(i=0;i<pPro->iNumPros;i++)
|
||||||
|
{
|
||||||
|
sprintf(pBuffer,"Protocol[%d] = %s",i,pPro->pProList[i]);
|
||||||
|
SCWrite(pCon,pBuffer,eStatus);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static int ProtocolHelp(SConnection* pCon, Protocol* pPro)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,
|
||||||
|
"Usage: protocol {help|list|options|reset} | set protocolName",
|
||||||
|
eStatus);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static int ProtocolSet(SConnection* pCon, Protocol* pPro, char *pProName)
|
||||||
|
{
|
||||||
|
int proID;
|
||||||
|
if(!SCVerifyConnection(pCon))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lazy initialisation of defaultWriter since connection is verified */
|
||||||
|
InitDefaultProtocol(pCon,pPro);
|
||||||
|
|
||||||
|
/* Do not die if no data */
|
||||||
|
if(NULL == pProName)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check list of protocols for valid name and assign functions based */
|
||||||
|
/* on match of pProName */
|
||||||
|
proID = EnumChoice(pPro->pProList,pPro->iNumPros,pProName);
|
||||||
|
switch(proID)
|
||||||
|
{
|
||||||
|
case -1: /* invalid */
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: /* normal (connection start default) */
|
||||||
|
SCSetWriteFunc(pCon,SCNormalWrite);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: /* outcodes */
|
||||||
|
SCSetWriteFunc(pCon,SCWriteWithOutcode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: /* sycamore */
|
||||||
|
SCSetWriteFunc(pCon,SCWriteSycamore);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0: /* default = psi_sics */
|
||||||
|
default:
|
||||||
|
SCSetWriteFunc(pCon,pPro->defaultWriter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pCon->iProtocolID = proID;
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static int ProtocolGet(SConnection* pCon, Protocol* pPro, char *pProName,
|
||||||
|
int *pIndex)
|
||||||
|
{
|
||||||
|
if(!SCVerifyConnection(pCon))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lazy initialisation of defaultWriter since connection is verified */
|
||||||
|
if(0==pPro->isDefaultSet)
|
||||||
|
{
|
||||||
|
pPro->defaultWriter = SCGetWriteFunc(pCon);
|
||||||
|
pPro->isDefaultSet = 1;
|
||||||
|
pCon->iProtocolID = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pIndex = (int)malloc(sizeof(int));
|
||||||
|
*pIndex = pCon->iProtocolID;
|
||||||
|
|
||||||
|
/* check list of protocols for valid name */
|
||||||
|
switch(*pIndex)
|
||||||
|
{
|
||||||
|
case 0: /* default = psi_sics */
|
||||||
|
case 1: /* normal (connection start default) */
|
||||||
|
case 2: /* outcodes */
|
||||||
|
case 3: /* sycamore */
|
||||||
|
pProName = strdup(pPro->pProList[*pIndex]);
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static int ProtocolList(SConnection* pCon, Protocol* pPro)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,
|
||||||
|
"Usage: protocol {help|list|options|reset} | set protocolName",
|
||||||
|
eStatus);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
int ProtocolAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int iRet;
|
||||||
|
char **argx;
|
||||||
|
FuPaResult PaRes;
|
||||||
|
pProtocol pPro = NULL;
|
||||||
|
|
||||||
|
const int iNumCmds = 5;
|
||||||
|
FuncTemplate CommandTemplate[] = {
|
||||||
|
{"help",0,{0,0}},
|
||||||
|
{"list",0,{0,0}},
|
||||||
|
{"options",0,{0,0}},
|
||||||
|
{"set",1,{FUPATEXT}},
|
||||||
|
{"reset",0,{0,0}},
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(pCon);
|
||||||
|
assert(pSics);
|
||||||
|
pPro = (pProtocol)pData;
|
||||||
|
assert(pPro);
|
||||||
|
|
||||||
|
/* You need to have User level access rights to use this facility */
|
||||||
|
if(!SCMatchRights(pCon,usUser))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse function args */
|
||||||
|
argtolower(argc,argv);
|
||||||
|
argx = &argv[1];
|
||||||
|
iRet = EvaluateFuPa((pFuncTemplate)&CommandTemplate,iNumCmds,argc-1,argx,&PaRes);
|
||||||
|
|
||||||
|
/* if invalid (iRet < 0) then default to "help" command */
|
||||||
|
|
||||||
|
switch(iRet)
|
||||||
|
{
|
||||||
|
case 1: /* list */
|
||||||
|
iRet = ProtocolList(pCon,pPro);
|
||||||
|
break;
|
||||||
|
case 2: /* options */
|
||||||
|
iRet = ProtocolOptions(pCon,pPro);
|
||||||
|
break;
|
||||||
|
case 3: /* set */
|
||||||
|
iRet = ProtocolSet(pCon,pPro,PaRes.Arg[0].text);
|
||||||
|
break;
|
||||||
|
case 4: /* reset */
|
||||||
|
iRet = ProtocolSet(pCon,pPro,"default");
|
||||||
|
break;
|
||||||
|
case 0: /* help */
|
||||||
|
default:
|
||||||
|
iRet = ProtocolHelp(pCon,pPro);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static int EnumChoice(char *pList[], int iLength, char *pInput)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int iRet = -1;
|
||||||
|
|
||||||
|
for(i=0;i<iLength;i++)
|
||||||
|
{
|
||||||
|
if(0==strcmp(pInput,pList[i]))
|
||||||
|
{
|
||||||
|
iRet = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------*/
|
||||||
|
static int InitDefaultProtocol(SConnection* pCon, Protocol *pPro)
|
||||||
|
{
|
||||||
|
if(NULL==pCon)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lazy initialisation of defaultWriter since connection is verified */
|
||||||
|
if(0==pPro->isDefaultSet)
|
||||||
|
{
|
||||||
|
pPro->defaultWriter = SCGetWriteFunc(pCon);
|
||||||
|
pPro->isDefaultSet = 1;
|
||||||
|
pCon->iProtocolID = 0;
|
||||||
|
}
|
||||||
|
return pPro->isDefaultSet;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut)
|
||||||
|
{
|
||||||
|
int i, iPtr, iRet;
|
||||||
|
int bDevIDdone = 0;
|
||||||
|
int bFlagDone = 0;
|
||||||
|
char pBueffel[MAXMSG];
|
||||||
|
long taskID = 0;
|
||||||
|
/* char pPrefix[40];*/
|
||||||
|
pDynString pMsg = NULL;
|
||||||
|
pDynString pMsgOut = NULL;
|
||||||
|
pDynString parseCmd = NULL;
|
||||||
|
SicsInterp *pSics;
|
||||||
|
TokenList *pList = NULL;
|
||||||
|
TokenList *pCurrent;
|
||||||
|
commandContext comCon;
|
||||||
|
char *savedTclResult = NULL;
|
||||||
|
|
||||||
|
/* For calling sycParse from interpreter */
|
||||||
|
char **argv = NULL;
|
||||||
|
int argc;
|
||||||
|
char *parser = "sycformat ";
|
||||||
|
char batchName[50];
|
||||||
|
strcpy(batchName,"::ansto::batch::next");
|
||||||
|
CommandList *pCommand = NULL;
|
||||||
|
|
||||||
|
if(!SCVerifyConnection(pCon))
|
||||||
|
{
|
||||||
|
DeleteDynString(parseCmd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
comCon = SCGetContext(pCon);
|
||||||
|
|
||||||
|
if (strcmp(comCon.deviceID, batchName) == 0) {
|
||||||
|
DeleteDynString(parseCmd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* Return 0 without dying if no message data */
|
||||||
|
if(pBuffer == NULL)
|
||||||
|
{
|
||||||
|
DeleteDynString(parseCmd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
build the Tcl-command to execute for formatting the
|
||||||
|
data into a sycamore string
|
||||||
|
*/
|
||||||
|
pSics = GetInterpreter();
|
||||||
|
taskID = comCon.transID;
|
||||||
|
taskID = taskID % 1000000;
|
||||||
|
|
||||||
|
pMsg = CreateDynString(INIT_STR_SIZE, STR_RESIZE_LENGTH);
|
||||||
|
pBueffel[0] = '\0';
|
||||||
|
|
||||||
|
sprintf(pBueffel,"con%4.4d",pCon->ident); /* field 1: connID */
|
||||||
|
DynStringConcat(pMsg,pBueffel);
|
||||||
|
sprintf(pBueffel," t%6.6d",taskID); /* field 2: taskID */
|
||||||
|
DynStringConcat(pMsg,pBueffel);
|
||||||
|
DynStringConcatChar(pMsg,' ');
|
||||||
|
/* deviceID */
|
||||||
|
DynStringConcat(pMsg,comCon.deviceID);
|
||||||
|
DynStringConcatChar(pMsg,' ');
|
||||||
|
|
||||||
|
/* msgFlag */
|
||||||
|
switch(iOut) {
|
||||||
|
case 5: /* eValue */
|
||||||
|
DynStringConcat(pMsg,"out");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DynStringConcat(pMsg,pCode[iOut]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DynStringConcatChar(pMsg,' ');
|
||||||
|
DynStringConcat(pMsg, " { ");
|
||||||
|
DynStringConcat(pMsg, comCon.deviceID);
|
||||||
|
DynStringConcat(pMsg, " } {");
|
||||||
|
if (iOut == eStart){
|
||||||
|
DynStringConcat(pMsg, comCon.deviceID);
|
||||||
|
}
|
||||||
|
parseCmd = CreateDynString(INIT_STR_SIZE, STR_RESIZE_LENGTH);
|
||||||
|
DynStringCopy(parseCmd, parser);
|
||||||
|
DynStringConcat(parseCmd,GetCharArray(pMsg));
|
||||||
|
DynStringConcat(parseCmd,pBuffer);
|
||||||
|
|
||||||
|
if (iOut == eEvent) {
|
||||||
|
DynStringConcat(parseCmd, " type.");
|
||||||
|
DynStringConcat(parseCmd, pEventType[pCon->conEventType]);
|
||||||
|
DynStringConcat(parseCmd, " status.");
|
||||||
|
DynStringConcat(parseCmd, pStatus[pCon->conStatus]);
|
||||||
|
}
|
||||||
|
DynStringConcatChar(parseCmd, '}');
|
||||||
|
savedTclResult = strdup(Tcl_GetStringResult(pSics->pTcl));
|
||||||
|
Tcl_Eval(pSics->pTcl, GetCharArray(parseCmd));
|
||||||
|
pMsgOut = CreateDynString(INIT_STR_SIZE, STR_RESIZE_LENGTH);
|
||||||
|
DynStringCopy(pMsgOut, (char *)Tcl_GetStringResult(pSics->pTcl));
|
||||||
|
if(savedTclResult != NULL){
|
||||||
|
Tcl_SetResult(pSics->pTcl,savedTclResult,TCL_VOLATILE);
|
||||||
|
free(savedTclResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* log it for any case */
|
||||||
|
if(pCon->pSock)
|
||||||
|
{
|
||||||
|
iRet = pCon->pSock->sockid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iRet = 0;
|
||||||
|
}
|
||||||
|
sprintf(pBueffel,"Next line intended for socket: %d",iRet);
|
||||||
|
SICSLogWrite(pBueffel,eInternal);
|
||||||
|
SICSLogWrite(GetCharArray(pMsgOut),iOut);
|
||||||
|
|
||||||
|
/* write to commandlog if user or manager privilege */
|
||||||
|
if(SCGetRights(pCon) <= usUser)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"To sock %d :",iRet);
|
||||||
|
WriteToCommandLog(pBueffel,GetCharArray(pMsgOut));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* put it into the interpreter if present */
|
||||||
|
if(SCinMacro(pCon))
|
||||||
|
{
|
||||||
|
InterpWrite(pSics,pBuffer);
|
||||||
|
iRet = SCDoSockWrite(pCon,GetCharArray(pMsgOut));
|
||||||
|
}
|
||||||
|
else /* not in interpreter, normal logic */
|
||||||
|
{
|
||||||
|
/* is this really to be printed ? */
|
||||||
|
if(iOut < pCon->iOutput)
|
||||||
|
{
|
||||||
|
DeleteDynString(parseCmd);
|
||||||
|
DeleteDynString(pMsg);
|
||||||
|
DeleteDynString(pMsgOut);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* first the socket */
|
||||||
|
/*strcat(pMsg, pBueffel);*/
|
||||||
|
iRet = SCDoSockWrite(pCon,GetCharArray(pMsgOut));
|
||||||
|
SCWriteToLogFiles(pCon,GetCharArray(pMsgOut));
|
||||||
|
}
|
||||||
|
if(pMsgOut != NULL){
|
||||||
|
DeleteDynString(pMsgOut);
|
||||||
|
}
|
||||||
|
DeleteDynString(parseCmd);
|
||||||
|
DeleteDynString(pMsg);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Protocol API */
|
||||||
|
char * GetProtocolName(SConnection* pCon)
|
||||||
|
{
|
||||||
|
pProtocol pPro;
|
||||||
|
pSicsInterp pSics;
|
||||||
|
|
||||||
|
if(!SCVerifyConnection(pCon))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pSics = GetInterpreter();
|
||||||
|
if(!pSics) return NULL;
|
||||||
|
|
||||||
|
pPro = FindCommandData(pSics,"protocol","Protocol");
|
||||||
|
if(!pPro) return NULL;
|
||||||
|
|
||||||
|
InitDefaultProtocol(pCon,pPro);
|
||||||
|
|
||||||
|
/* check list of protocols for valid name */
|
||||||
|
switch(pCon->iProtocolID)
|
||||||
|
{
|
||||||
|
case 0: /* default = psi_sics */
|
||||||
|
case 1: /* normal (connection start default) */
|
||||||
|
case 2: /* outcodes */
|
||||||
|
case 3: /* sycamore */
|
||||||
|
return strdup(pPro->pProList[pCon->iProtocolID]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return strdup("invalid");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------*/
|
||||||
|
int GetProtocolID(SConnection* pCon)
|
||||||
|
{
|
||||||
|
if(NULL!=pCon)
|
||||||
|
{
|
||||||
|
return pCon->iProtocolID;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
34
protocol.h
Normal file
34
protocol.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
#ifndef ANSTO_PROTOCOL
|
||||||
|
#define ANSTO_PROTOCOL
|
||||||
|
#include <sics.h>
|
||||||
|
#include <conman.h>
|
||||||
|
|
||||||
|
static const int iNumProTags = 2;
|
||||||
|
static char *pProTags[3] = {
|
||||||
|
"start",
|
||||||
|
"finish",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
#define esStart -1
|
||||||
|
#define esFinish -2
|
||||||
|
|
||||||
|
/*--------------------- lifecycle -------------------------------------- */
|
||||||
|
int InstallProtocol(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
void DeleteProtocol(void *pSelf);
|
||||||
|
|
||||||
|
/*--------------------- operations --------------------------------------*/
|
||||||
|
int ProtocolAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
/*--------------------- implement protocol sycamore ---------------------*/
|
||||||
|
int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut);
|
||||||
|
|
||||||
|
/*--------------------- implement protocol API -----------------------*/
|
||||||
|
char * GetProtocolName(SConnection *pCon);
|
||||||
|
int GetProtocolID(SConnection *pCon);
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
#endif
|
@ -250,6 +250,32 @@ int readRS232TillTerm(prs232 self, void *data, int *datalen){
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
int readRS232UntilWord(prs232 self,
|
||||||
|
char *buffer, int buflen, char *word){
|
||||||
|
time_t endTime;
|
||||||
|
int status;
|
||||||
|
int bytesRead = 0;
|
||||||
|
|
||||||
|
endTime = time(NULL) + self->timeout;
|
||||||
|
memset(buffer,0,buflen);
|
||||||
|
while(time(NULL) < endTime){
|
||||||
|
if(availableRS232(self)){
|
||||||
|
bytesRead = recv(self->pSock->sockid,buffer + bytesRead,
|
||||||
|
buflen - bytesRead - 1,0);
|
||||||
|
if(bytesRead < 0){
|
||||||
|
return BADREAD;
|
||||||
|
}
|
||||||
|
if(strstr(buffer,word) != NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SicsWait(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
int availableRS232(prs232 self)
|
int availableRS232(prs232 self)
|
||||||
{
|
{
|
||||||
@ -736,6 +762,31 @@ int RS232Action(SConnection *pCon, SicsInterp *pSics,
|
|||||||
SCWrite(pCon,pBuffer,eValue);
|
SCWrite(pCon,pBuffer,eValue);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else if(strcmp(argv[1],"readchar") == 0){
|
||||||
|
if(argc < 3){
|
||||||
|
SCWrite(pCon,"ERROR: need number of chars to read",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iRead);
|
||||||
|
if(iRet != TCL_OK){
|
||||||
|
SCWrite(pCon,"ERROR: failed to convert argument to number",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!availableRS232(self))
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"Nothing to read!",eError);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
iRet = readRS232(self,pBuffer,&iRead);
|
||||||
|
if(iRet < 0)
|
||||||
|
{
|
||||||
|
getRS232Error(iRet,pError,255);
|
||||||
|
SCWrite(pCon,pError,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SCWrite(pCon,pBuffer,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
else if(strcmp(argv[1],"available") == 0)
|
else if(strcmp(argv[1],"available") == 0)
|
||||||
{
|
{
|
||||||
iRet = availableRS232(self);
|
iRet = availableRS232(self);
|
||||||
|
@ -56,6 +56,8 @@
|
|||||||
int writeRS232(prs232 self, void *data, int dataLen);
|
int writeRS232(prs232 self, void *data, int dataLen);
|
||||||
int readRS232(prs232 self, void *data, int *dataLen);
|
int readRS232(prs232 self, void *data, int *dataLen);
|
||||||
int readRS232TillTerm(prs232 self, void *data, int *datalen);
|
int readRS232TillTerm(prs232 self, void *data, int *datalen);
|
||||||
|
int readRS232UntilWord(prs232 self,
|
||||||
|
char *buffer, int buflen, char *word);
|
||||||
int availableRS232(prs232 self);
|
int availableRS232(prs232 self);
|
||||||
int availableNetRS232(prs232 self);
|
int availableNetRS232(prs232 self);
|
||||||
int transactRS232(prs232 self, void *send, int sendLen,
|
int transactRS232(prs232 self, void *send, int sendLen,
|
||||||
|
43
scan.c
43
scan.c
@ -1236,7 +1236,8 @@ int isScanVarSoft(pScanData self){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static int ScanInterest(int iEvent, void *pEventData, void *pUser)
|
static int ScanInterest(int iEvent, void *pEventData, void *pUser,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
pScanData self = NULL;
|
pScanData self = NULL;
|
||||||
SConnection *pCon = NULL;
|
SConnection *pCon = NULL;
|
||||||
@ -1253,12 +1254,12 @@ int isScanVarSoft(pScanData self){
|
|||||||
|
|
||||||
if(iEvent == SCANSTART)
|
if(iEvent == SCANSTART)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"NewScan",eWarning);
|
SCWriteInContext(pCon,"NewScan",eWarning,cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if(iEvent == SCANEND)
|
else if(iEvent == SCANEND)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ScanEnd",eWarning);
|
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if(iEvent == SCANPOINT)
|
else if(iEvent == SCANPOINT)
|
||||||
@ -1299,7 +1300,8 @@ int isScanVarSoft(pScanData self){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static int ScanDynInterest(int iEvent, void *pEventData, void *pUser)
|
static int ScanDynInterest(int iEvent, void *pEventData, void *pUser,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
pScanData self = NULL;
|
pScanData self = NULL;
|
||||||
SConnection *pCon = NULL;
|
SConnection *pCon = NULL;
|
||||||
@ -1319,12 +1321,12 @@ int isScanVarSoft(pScanData self){
|
|||||||
|
|
||||||
if(iEvent == SCANSTART)
|
if(iEvent == SCANSTART)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"NewScan",eWarning);
|
SCWriteInContext(pCon,"NewScan",eWarning,cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if(iEvent == SCANEND)
|
else if(iEvent == SCANEND)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ScanEnd",eWarning);
|
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if(iEvent == SCANPOINT)
|
else if(iEvent == SCANPOINT)
|
||||||
@ -1346,12 +1348,13 @@ int isScanVarSoft(pScanData self){
|
|||||||
}
|
}
|
||||||
snprintf(pBueffel,255,"%s.scanpoint = {%d %f %ld}",
|
snprintf(pBueffel,255,"%s.scanpoint = {%d %f %ld}",
|
||||||
self->objectName,i,fVal,lVal);
|
self->objectName,i,fVal,lVal);
|
||||||
SCWrite(pCon,pBueffel,eValue);
|
SCWriteInContext(pCon,pBueffel,eValue,cc);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static int ScanUUInterest(int iEvent, void *pEventData, void *pUser)
|
static int ScanUUInterest(int iEvent, void *pEventData, void *pUser,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
pScanData self = NULL;
|
pScanData self = NULL;
|
||||||
SConnection *pCon = NULL;
|
SConnection *pCon = NULL;
|
||||||
@ -1368,12 +1371,12 @@ int isScanVarSoft(pScanData self){
|
|||||||
|
|
||||||
if(iEvent == SCANSTART)
|
if(iEvent == SCANSTART)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"NewScan",eWarning);
|
SCWriteInContext(pCon,"NewScan",eWarning,cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if(iEvent == SCANEND)
|
else if(iEvent == SCANEND)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ScanEnd",eWarning);
|
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if(iEvent == SCANPOINT)
|
else if(iEvent == SCANPOINT)
|
||||||
@ -1395,7 +1398,9 @@ int isScanVarSoft(pScanData self){
|
|||||||
{
|
{
|
||||||
iData[i] = htonl((int)lData[i]);
|
iData[i] = htonl((int)lData[i]);
|
||||||
}
|
}
|
||||||
|
SCPushContext2(pCon,cc);
|
||||||
SCWriteUUencoded(pCon,"ScanData",iData,self->iNP*sizeof(int));
|
SCWriteUUencoded(pCon,"ScanData",iData,self->iNP*sizeof(int));
|
||||||
|
SCPopContext(pCon);
|
||||||
free(lData);
|
free(lData);
|
||||||
free(iData);
|
free(iData);
|
||||||
return 1;
|
return 1;
|
||||||
@ -1896,13 +1901,13 @@ static int DumpScan(pScanData self, SConnection *pCon)
|
|||||||
/*-------- interest */
|
/*-------- interest */
|
||||||
else if(strcmp(argv[1],"interest") == 0)
|
else if(strcmp(argv[1],"interest") == 0)
|
||||||
{
|
{
|
||||||
lID = RegisterCallback(self->pCall, SCANSTART, ScanInterest,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanInterest,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
lID = RegisterCallback(self->pCall, SCANEND, ScanInterest,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANEND, ScanInterest,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
lID = RegisterCallback(self->pCall, SCANPOINT, ScanInterest,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanInterest,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
@ -1911,13 +1916,13 @@ static int DumpScan(pScanData self, SConnection *pCon)
|
|||||||
/*-------- interest */
|
/*-------- interest */
|
||||||
else if(strcmp(argv[1],"dyninterest") == 0)
|
else if(strcmp(argv[1],"dyninterest") == 0)
|
||||||
{
|
{
|
||||||
lID = RegisterCallback(self->pCall, SCANSTART, ScanDynInterest,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanDynInterest,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
lID = RegisterCallback(self->pCall, SCANEND, ScanDynInterest,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon), SCANEND, ScanDynInterest,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
lID = RegisterCallback(self->pCall, SCANPOINT, ScanDynInterest,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanDynInterest,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
@ -1926,13 +1931,13 @@ static int DumpScan(pScanData self, SConnection *pCon)
|
|||||||
/*-------- uuinterest */
|
/*-------- uuinterest */
|
||||||
else if(strcmp(argv[1],"uuinterest") == 0)
|
else if(strcmp(argv[1],"uuinterest") == 0)
|
||||||
{
|
{
|
||||||
lID = RegisterCallback(self->pCall, SCANSTART, ScanUUInterest,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanUUInterest,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
lID = RegisterCallback(self->pCall, SCANEND, ScanUUInterest,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANEND, ScanUUInterest,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
lID = RegisterCallback(self->pCall, SCANPOINT, ScanUUInterest,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanUUInterest,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
|
11
selvar.c
11
selvar.c
@ -474,7 +474,8 @@
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
static int WaveLengthCallBack(int iEvent, void *pEvent, void *pUser)
|
static int WaveLengthCallBack(int iEvent, void *pEvent, void *pUser,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
SConnection *pCon = NULL;
|
SConnection *pCon = NULL;
|
||||||
pSelVar self = NULL;
|
pSelVar self = NULL;
|
||||||
@ -488,7 +489,7 @@
|
|||||||
|
|
||||||
fVal = GetSelValue(self,pCon);
|
fVal = GetSelValue(self,pCon);
|
||||||
sprintf(pBueffel,"%s.value = %f", self->name, fVal);
|
sprintf(pBueffel,"%s.value = %f", self->name, fVal);
|
||||||
SCWrite(pCon,pBueffel,eValue);
|
SCWriteInContext(pCon,pBueffel,eValue,cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------
|
||||||
@ -520,7 +521,8 @@
|
|||||||
strtolower(argv[1]);
|
strtolower(argv[1]);
|
||||||
if(strcmp(argv[1],"interest") == 0)
|
if(strcmp(argv[1],"interest") == 0)
|
||||||
{
|
{
|
||||||
lID = RegisterCallback(self->pCall, WLCHANGE, WaveLengthCallBack,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||||
|
WLCHANGE, WaveLengthCallBack,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
@ -589,7 +591,8 @@
|
|||||||
strtolower(argv[1]);
|
strtolower(argv[1]);
|
||||||
if(strcmp(argv[1],"interest") == 0)
|
if(strcmp(argv[1],"interest") == 0)
|
||||||
{
|
{
|
||||||
lID = RegisterCallback(self->pCall, WLCHANGE, WaveLengthCallBack,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||||
|
WLCHANGE, WaveLengthCallBack,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
|
102
servlog.c
102
servlog.c
@ -39,6 +39,13 @@
|
|||||||
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
|
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
|
||||||
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
||||||
MODIFICATIONS.
|
MODIFICATIONS.
|
||||||
|
|
||||||
|
Modified: Paul Hathaway, June 2004
|
||||||
|
SICSLogWrite
|
||||||
|
- no longer asserts existence of the log file, writing
|
||||||
|
to stderr and skipping further file writes.
|
||||||
|
- NETWrites log message (if enabled) before attempt to write to file
|
||||||
|
- uses OpenVerifyLogFile helper function (removed duplicate code)
|
||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
#include "fortify.h"
|
#include "fortify.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -223,30 +230,17 @@
|
|||||||
static FILE *fLogFile = NULL;
|
static FILE *fLogFile = NULL;
|
||||||
static int iFile = 0;
|
static int iFile = 0;
|
||||||
static int iLineCount = 0;
|
static int iLineCount = 0;
|
||||||
|
static int iLogUsable = 1;
|
||||||
|
|
||||||
void SICSLogWrite(char *pText, OutCode eOut)
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int OpenVerifyLogFile()
|
||||||
{
|
{
|
||||||
char pFile[256];
|
char pFile[256];
|
||||||
char *pChar = NULL;
|
char *pChar = NULL;
|
||||||
pCaptureEntry pCurrent;
|
|
||||||
char pBueffel[256];
|
|
||||||
|
|
||||||
#ifdef NOLOG
|
|
||||||
return ;
|
|
||||||
#endif
|
|
||||||
if(fLogFile == NULL) /* first time of */
|
|
||||||
{
|
|
||||||
/* no options: startup or serious trouble, print to stdout*/
|
|
||||||
if(!pSICSOptions)
|
|
||||||
{
|
|
||||||
printf(" %s \n",pText);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the filename */
|
|
||||||
pChar = IFindOption(pSICSOptions,"LogFileBaseName");
|
pChar = IFindOption(pSICSOptions,"LogFileBaseName");
|
||||||
if(!pChar)
|
if(!pChar)
|
||||||
{
|
{ /* Try to write to file "server" in*/
|
||||||
strcpy(pFile,"server");
|
strcpy(pFile,"server");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -257,44 +251,68 @@
|
|||||||
fLogFile = fopen(pFile,"w");
|
fLogFile = fopen(pFile,"w");
|
||||||
if(!fLogFile)
|
if(!fLogFile)
|
||||||
{
|
{
|
||||||
printf("ERROR: cannot open logfile %s for writing\n",
|
fprintf(stderr,"ERROR: Cannot open logfile %s for writing\n",pFile);
|
||||||
pFile);
|
|
||||||
fLogFile = NULL;
|
fLogFile = NULL;
|
||||||
return;
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* switch file if to many lines */
|
/*---------------------------------------------------------------------------*/
|
||||||
if(iLineCount == MAXLOG)
|
void SICSLogWrite(char *pText, OutCode eOut)
|
||||||
|
{
|
||||||
|
char pFile[256];
|
||||||
|
char *pChar = NULL;
|
||||||
|
pCaptureEntry pCurrent;
|
||||||
|
char pBueffel[256];
|
||||||
|
|
||||||
|
#ifdef NOLOG
|
||||||
|
return ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* do all captured */
|
||||||
|
pCurrent = pCapture;
|
||||||
|
while(pCurrent)
|
||||||
|
{
|
||||||
|
if( (pCurrent->iOut == eOut) || (pCurrent->iAllFlag == 1) )
|
||||||
|
{
|
||||||
|
NETWrite(pCurrent->pCon->pSock,pText,strlen(pText));
|
||||||
|
}
|
||||||
|
pCurrent = pCurrent->pNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(0 == iLogUsable) return;
|
||||||
|
|
||||||
|
if(fLogFile == NULL) /* first time of use*/
|
||||||
|
{
|
||||||
|
/* no options: startup or serious trouble, print to stdout*/
|
||||||
|
if(!pSICSOptions)
|
||||||
|
{
|
||||||
|
printf("WARNING: Cannot log(%s)\n",pText);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
iLogUsable = OpenVerifyLogFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* switch file if too many lines */
|
||||||
|
if(iLineCount >= MAXLOG)
|
||||||
{
|
{
|
||||||
fclose(fLogFile);
|
fclose(fLogFile);
|
||||||
fLogFile = NULL;
|
fLogFile = NULL;
|
||||||
iFile++;
|
iFile++;
|
||||||
|
iLineCount = 0;
|
||||||
if(iFile >= MAXFILES)
|
if(iFile >= MAXFILES)
|
||||||
{
|
{
|
||||||
iFile = 0;
|
iFile = 0;
|
||||||
}
|
}
|
||||||
pChar = IFindOption(pSICSOptions,"LogFileBaseName");
|
iLogUsable = OpenVerifyLogFile();
|
||||||
if(!pChar)
|
|
||||||
{
|
|
||||||
strcpy(pFile,"server");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strcpy(pFile,pChar);
|
|
||||||
}
|
|
||||||
sprintf(pFile,"%s%1d.log",pFile, iFile);
|
|
||||||
fLogFile = fopen(pFile,"w");
|
|
||||||
if(!fLogFile)
|
|
||||||
{
|
|
||||||
printf("ERROR: cannot open logfile %s for writing\n",
|
|
||||||
pFile);
|
|
||||||
fLogFile = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
iLineCount = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(1 == iLogUsable)
|
||||||
|
{
|
||||||
fprintf(fLogFile,"%s\n",pText);
|
fprintf(fLogFile,"%s\n",pText);
|
||||||
fflush(fLogFile);
|
fflush(fLogFile);
|
||||||
iLineCount++;
|
iLineCount++;
|
||||||
@ -310,4 +328,4 @@
|
|||||||
pCurrent = pCurrent->pNext;
|
pCurrent = pCurrent->pNext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
230
sicsstat.tcl
230
sicsstat.tcl
@ -1,230 +0,0 @@
|
|||||||
exe batchpath ./
|
|
||||||
exe syspath ./
|
|
||||||
#---- tasUB module tasub
|
|
||||||
tasub mono dd 3.350000
|
|
||||||
tasub mono hb1 1.000000
|
|
||||||
tasub mono hb2 1.000000
|
|
||||||
tasub mono vb1 1.000000
|
|
||||||
tasub mono vb2 1.000000
|
|
||||||
tasub mono ss 1
|
|
||||||
tasub ana dd 3.350000
|
|
||||||
tasub ana hb1 1.000000
|
|
||||||
tasub ana hb2 1.000000
|
|
||||||
tasub ana vb1 1.000000
|
|
||||||
tasub ana vb2 1.000000
|
|
||||||
tasub ana ss 1
|
|
||||||
tasub cell 1.000000 1.000000 1.000000 90.000000 90.000000 90.000000
|
|
||||||
tasub clear
|
|
||||||
tasub const ki
|
|
||||||
tasub ss 1
|
|
||||||
tasub setub 1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 1.000000
|
|
||||||
tasub setnormal 0.000000 0.000000 0.000000
|
|
||||||
tasub settarget 0.000000 0.000000 0.000000 0.000000 0.000000
|
|
||||||
tasub update
|
|
||||||
scaninfo 0,Unknown,1.0,.1
|
|
||||||
scaninfo setAccess 0
|
|
||||||
polfile UNKNOWN
|
|
||||||
polfile setAccess 2
|
|
||||||
local UNKNOWN
|
|
||||||
local setAccess 2
|
|
||||||
output UNKNOWN
|
|
||||||
output setAccess 2
|
|
||||||
lastcommand UNKNOWN
|
|
||||||
lastcommand setAccess 2
|
|
||||||
user Albert von Villigen
|
|
||||||
user setAccess 2
|
|
||||||
title UNKNOWN
|
|
||||||
title setAccess 2
|
|
||||||
# Counter counter
|
|
||||||
counter SetPreset 10.000000
|
|
||||||
counter SetMode Timer
|
|
||||||
# Motor agl
|
|
||||||
agl sign 1.000000
|
|
||||||
agl SoftZero 0.000000
|
|
||||||
agl SoftLowerLim -10.000000
|
|
||||||
agl SoftUpperLim 10.000000
|
|
||||||
agl Fixed -1.000000
|
|
||||||
agl InterruptMode 0.000000
|
|
||||||
agl precision 0.010000
|
|
||||||
agl AccessCode 2.000000
|
|
||||||
agl movecount 10.000000
|
|
||||||
# Motor sgu
|
|
||||||
sgu sign 1.000000
|
|
||||||
sgu SoftZero 0.000000
|
|
||||||
sgu SoftLowerLim -16.000000
|
|
||||||
sgu SoftUpperLim 16.000000
|
|
||||||
sgu Fixed -1.000000
|
|
||||||
sgu InterruptMode 0.000000
|
|
||||||
sgu precision 0.010000
|
|
||||||
sgu AccessCode 2.000000
|
|
||||||
sgu movecount 10.000000
|
|
||||||
# Motor sgl
|
|
||||||
sgl sign 1.000000
|
|
||||||
sgl SoftZero 0.000000
|
|
||||||
sgl SoftLowerLim -16.000000
|
|
||||||
sgl SoftUpperLim 16.000000
|
|
||||||
sgl Fixed -1.000000
|
|
||||||
sgl InterruptMode 0.000000
|
|
||||||
sgl precision 0.010000
|
|
||||||
sgl AccessCode 2.000000
|
|
||||||
sgl movecount 10.000000
|
|
||||||
# Motor mgl
|
|
||||||
mgl sign 1.000000
|
|
||||||
mgl SoftZero 0.000000
|
|
||||||
mgl SoftLowerLim -10.000000
|
|
||||||
mgl SoftUpperLim 10.000000
|
|
||||||
mgl Fixed -1.000000
|
|
||||||
mgl InterruptMode 0.000000
|
|
||||||
mgl precision 0.010000
|
|
||||||
mgl AccessCode 2.000000
|
|
||||||
mgl movecount 10.000000
|
|
||||||
# Motor atu
|
|
||||||
atu sign 1.000000
|
|
||||||
atu SoftZero 0.000000
|
|
||||||
atu SoftLowerLim -17.000000
|
|
||||||
atu SoftUpperLim 16.879999
|
|
||||||
atu Fixed -1.000000
|
|
||||||
atu InterruptMode 0.000000
|
|
||||||
atu precision 0.010000
|
|
||||||
atu AccessCode 2.000000
|
|
||||||
atu movecount 10.000000
|
|
||||||
# Motor atl
|
|
||||||
atl sign 1.000000
|
|
||||||
atl SoftZero 0.000000
|
|
||||||
atl SoftLowerLim -17.000000
|
|
||||||
atl SoftUpperLim 17.000000
|
|
||||||
atl Fixed -1.000000
|
|
||||||
atl InterruptMode 0.000000
|
|
||||||
atl precision 0.010000
|
|
||||||
atl AccessCode 2.000000
|
|
||||||
atl movecount 10.000000
|
|
||||||
# Motor stu
|
|
||||||
stu sign 1.000000
|
|
||||||
stu SoftZero 0.000000
|
|
||||||
stu SoftLowerLim -30.000000
|
|
||||||
stu SoftUpperLim 30.000000
|
|
||||||
stu Fixed -1.000000
|
|
||||||
stu InterruptMode 0.000000
|
|
||||||
stu precision 0.010000
|
|
||||||
stu AccessCode 2.000000
|
|
||||||
stu movecount 10.000000
|
|
||||||
# Motor stl
|
|
||||||
stl sign 1.000000
|
|
||||||
stl SoftZero 0.000000
|
|
||||||
stl SoftLowerLim -30.000000
|
|
||||||
stl SoftUpperLim 30.000000
|
|
||||||
stl Fixed -1.000000
|
|
||||||
stl InterruptMode 0.000000
|
|
||||||
stl precision 0.010000
|
|
||||||
stl AccessCode 2.000000
|
|
||||||
stl movecount 10.000000
|
|
||||||
# Motor mtu
|
|
||||||
mtu sign 1.000000
|
|
||||||
mtu SoftZero 0.000000
|
|
||||||
mtu SoftLowerLim -17.000000
|
|
||||||
mtu SoftUpperLim 17.000000
|
|
||||||
mtu Fixed -1.000000
|
|
||||||
mtu InterruptMode 0.000000
|
|
||||||
mtu precision 0.010000
|
|
||||||
mtu AccessCode 2.000000
|
|
||||||
mtu movecount 10.000000
|
|
||||||
# Motor mtl
|
|
||||||
mtl sign 1.000000
|
|
||||||
mtl SoftZero 0.000000
|
|
||||||
mtl SoftLowerLim -17.000000
|
|
||||||
mtl SoftUpperLim 17.000000
|
|
||||||
mtl Fixed -1.000000
|
|
||||||
mtl InterruptMode 0.000000
|
|
||||||
mtl precision 0.010000
|
|
||||||
mtl AccessCode 2.000000
|
|
||||||
mtl movecount 10.000000
|
|
||||||
# Motor ach
|
|
||||||
ach sign 1.000000
|
|
||||||
ach SoftZero 0.000000
|
|
||||||
ach SoftLowerLim -0.500000
|
|
||||||
ach SoftUpperLim 11.500000
|
|
||||||
ach Fixed -1.000000
|
|
||||||
ach InterruptMode 0.000000
|
|
||||||
ach precision 0.010000
|
|
||||||
ach AccessCode 2.000000
|
|
||||||
ach movecount 10.000000
|
|
||||||
# Motor sro
|
|
||||||
sro sign 1.000000
|
|
||||||
sro SoftZero 0.000000
|
|
||||||
sro SoftLowerLim 0.000000
|
|
||||||
sro SoftUpperLim 351.000000
|
|
||||||
sro Fixed -1.000000
|
|
||||||
sro InterruptMode 0.000000
|
|
||||||
sro precision 0.010000
|
|
||||||
sro AccessCode 2.000000
|
|
||||||
sro movecount 10.000000
|
|
||||||
# Motor mcv
|
|
||||||
mcv sign 1.000000
|
|
||||||
mcv SoftZero 0.000000
|
|
||||||
mcv SoftLowerLim -9.000000
|
|
||||||
mcv SoftUpperLim 124.000000
|
|
||||||
mcv Fixed -1.000000
|
|
||||||
mcv InterruptMode 0.000000
|
|
||||||
mcv precision 0.010000
|
|
||||||
mcv AccessCode 2.000000
|
|
||||||
mcv movecount 10.000000
|
|
||||||
# Motor a6
|
|
||||||
a6 sign 1.000000
|
|
||||||
a6 SoftZero 0.000000
|
|
||||||
a6 SoftLowerLim -116.000000
|
|
||||||
a6 SoftUpperLim 166.000000
|
|
||||||
a6 Fixed -1.000000
|
|
||||||
a6 InterruptMode 0.000000
|
|
||||||
a6 precision 0.010000
|
|
||||||
a6 AccessCode 2.000000
|
|
||||||
a6 movecount 10.000000
|
|
||||||
# Motor a5
|
|
||||||
a5 sign 1.000000
|
|
||||||
a5 SoftZero 0.000000
|
|
||||||
a5 SoftLowerLim -200.000000
|
|
||||||
a5 SoftUpperLim 200.000000
|
|
||||||
a5 Fixed -1.000000
|
|
||||||
a5 InterruptMode 0.000000
|
|
||||||
a5 precision 0.010000
|
|
||||||
a5 AccessCode 2.000000
|
|
||||||
a5 movecount 10.000000
|
|
||||||
# Motor a4
|
|
||||||
a4 sign 1.000000
|
|
||||||
a4 SoftZero 0.000000
|
|
||||||
a4 SoftLowerLim -135.100006
|
|
||||||
a4 SoftUpperLim 123.400002
|
|
||||||
a4 Fixed -1.000000
|
|
||||||
a4 InterruptMode 0.000000
|
|
||||||
a4 precision 0.010000
|
|
||||||
a4 AccessCode 2.000000
|
|
||||||
a4 movecount 10.000000
|
|
||||||
# Motor a3
|
|
||||||
a3 sign 1.000000
|
|
||||||
a3 SoftZero 0.000000
|
|
||||||
a3 SoftLowerLim -177.300003
|
|
||||||
a3 SoftUpperLim 177.300003
|
|
||||||
a3 Fixed -1.000000
|
|
||||||
a3 InterruptMode 0.000000
|
|
||||||
a3 precision 0.010000
|
|
||||||
a3 AccessCode 2.000000
|
|
||||||
a3 movecount 10.000000
|
|
||||||
# Motor a2
|
|
||||||
a2 sign 1.000000
|
|
||||||
a2 SoftZero 0.000000
|
|
||||||
a2 SoftLowerLim -129.100006
|
|
||||||
a2 SoftUpperLim -22.000000
|
|
||||||
a2 Fixed -1.000000
|
|
||||||
a2 InterruptMode 0.000000
|
|
||||||
a2 precision 0.010000
|
|
||||||
a2 AccessCode 2.000000
|
|
||||||
a2 movecount 10.000000
|
|
||||||
# Motor a1
|
|
||||||
a1 sign 1.000000
|
|
||||||
a1 SoftZero 0.000000
|
|
||||||
a1 SoftLowerLim -87.000000
|
|
||||||
a1 SoftUpperLim 6.100000
|
|
||||||
a1 Fixed -1.000000
|
|
||||||
a1 InterruptMode 0.000000
|
|
||||||
a1 precision 0.010000
|
|
||||||
a1 AccessCode 2.000000
|
|
||||||
a1 movecount 10.000000
|
|
||||||
|
21
sicvar.c
21
sicvar.c
@ -374,12 +374,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------*/
|
||||||
static int VarInterestCallback(int iEvent, void *pEvent, void *pUser)
|
static int VarInterestCallback(int iEvent, void *pEvent, void *pUser,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
SConnection *pCon;
|
SConnection *pCon;
|
||||||
char pBueffel[512];
|
char pBueffel[512];
|
||||||
pSicsVariable pVar = NULL;
|
pSicsVariable pVar = NULL;
|
||||||
int iVal;
|
int iVal, status;
|
||||||
float fVal;
|
float fVal;
|
||||||
char *pText;
|
char *pText;
|
||||||
|
|
||||||
@ -388,18 +389,21 @@
|
|||||||
|
|
||||||
pVar = (pSicsVariable)pEvent;
|
pVar = (pSicsVariable)pEvent;
|
||||||
pCon = (SConnection *)pUser;
|
pCon = (SConnection *)pUser;
|
||||||
|
SCPushContext2(pCon,cc);
|
||||||
switch(pVar->eType)
|
switch(pVar->eType)
|
||||||
{
|
{
|
||||||
case veInt:
|
case veInt:
|
||||||
VarGetInt(pVar,&iVal);
|
VarGetInt(pVar,&iVal);
|
||||||
sprintf(pBueffel,"%s = %d",pVar->name,iVal);
|
sprintf(pBueffel,"%s = %d",pVar->name,iVal);
|
||||||
SCWrite(pCon,pBueffel,eValue);
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
return 1;
|
status = 1;
|
||||||
|
break;
|
||||||
case veFloat:
|
case veFloat:
|
||||||
VarGetFloat(pVar,&fVal);
|
VarGetFloat(pVar,&fVal);
|
||||||
sprintf(pBueffel,"%s = %f",pVar->name,fVal);
|
sprintf(pBueffel,"%s = %f",pVar->name,fVal);
|
||||||
SCWrite(pCon,pBueffel,eValue);
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
return 1;
|
status = 1;
|
||||||
|
break;
|
||||||
case veText:
|
case veText:
|
||||||
VarGetText(pVar,&pText);
|
VarGetText(pVar,&pText);
|
||||||
sprintf(pBueffel,"%s = %s", pVar->name,pText);
|
sprintf(pBueffel,"%s = %s", pVar->name,pText);
|
||||||
@ -408,9 +412,11 @@
|
|||||||
{
|
{
|
||||||
free(pText);
|
free(pText);
|
||||||
}
|
}
|
||||||
return 1;
|
status = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 1;
|
SCPopContext(pCon);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
static int VarSetFromText(pSicsVariable self, SConnection *pCon, char *text)
|
static int VarSetFromText(pSicsVariable self, SConnection *pCon, char *text)
|
||||||
@ -559,7 +565,8 @@ static int VarSetFromText(pSicsVariable self, SConnection *pCon, char *text)
|
|||||||
}
|
}
|
||||||
else if(strcmp(pCurrent->text,"interest") == 0) /* interest */
|
else if(strcmp(pCurrent->text,"interest") == 0) /* interest */
|
||||||
{
|
{
|
||||||
lID = RegisterCallback(pVar->pCall, VALUECHANGE, VarInterestCallback,
|
lID = RegisterCallback(pVar->pCall, SCGetContext(pCon),
|
||||||
|
VALUECHANGE, VarInterestCallback,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pInterp, pVar->pCall,lID);
|
SCRegister(pCon,pInterp, pVar->pCall,lID);
|
||||||
DeleteTokenList(pList);
|
DeleteTokenList(pList);
|
||||||
|
387
sinfo.tcl
Normal file
387
sinfo.tcl
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
# requires stooop package from tcllib
|
||||||
|
# loaded from sycamore.tcl
|
||||||
|
|
||||||
|
proc arga argStr {
|
||||||
|
set args [ split $argStr ]
|
||||||
|
set argc [llength $args]
|
||||||
|
# syc::debug "arga.argc = %s" $argc
|
||||||
|
set objName ""
|
||||||
|
set key ""
|
||||||
|
set name ""
|
||||||
|
set val ""
|
||||||
|
set bObj [expr $argc > 0]
|
||||||
|
set bKey [expr $argc > 1]
|
||||||
|
set bName [expr $argc > 2]
|
||||||
|
set bVal [expr $argc > 3]
|
||||||
|
if $bObj {
|
||||||
|
set objName [string tolower [lindex $args 0]]
|
||||||
|
#syc::debug "arga.objName = %s" $objName
|
||||||
|
}
|
||||||
|
if $bKey {
|
||||||
|
set key [string tolower [lindex $args 1]]
|
||||||
|
#syc::debug "arga.key = %s" $key
|
||||||
|
}
|
||||||
|
if $bName {
|
||||||
|
set name [string tolower [lindex $args 2]]
|
||||||
|
}
|
||||||
|
if $bVal {
|
||||||
|
set val [string tolower [lindex $args 3]]
|
||||||
|
}
|
||||||
|
# ? cannot get 'array set' to work in the form:
|
||||||
|
# array set argv {
|
||||||
|
# argc $argc
|
||||||
|
# objName $objName
|
||||||
|
# ... etcetera
|
||||||
|
# }
|
||||||
|
set argv(argc) $argc
|
||||||
|
set argv(bObj) $bObj
|
||||||
|
set argv(bKey) $bKey
|
||||||
|
set argv(bName) $bName
|
||||||
|
set argv(bVal) $bVal
|
||||||
|
set argv(objName) $objName
|
||||||
|
set argv(key) $key
|
||||||
|
set argv(name) $name
|
||||||
|
set argv(val) $val
|
||||||
|
# would like to return associative array
|
||||||
|
# for now, settle for list
|
||||||
|
# syc::debug "arga.argv = { %s }" [array get argv]
|
||||||
|
return [array get argv]
|
||||||
|
}
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
class sinfo { ;# base class definition
|
||||||
|
proc sinfo {this} { ;# base class constructor
|
||||||
|
# non-static data member initialisation
|
||||||
|
set ($this,objectID) $this
|
||||||
|
}
|
||||||
|
|
||||||
|
proc ~sinfo {this} {} ;# base class destructor
|
||||||
|
|
||||||
|
proc id {this} {
|
||||||
|
return [format "sin.objectID = \{ %s \}" $($this,objectID)]
|
||||||
|
}
|
||||||
|
|
||||||
|
# static data member variables
|
||||||
|
# set File default.dat
|
||||||
|
set delimiter ", "
|
||||||
|
set debug 0
|
||||||
|
set init 0
|
||||||
|
set name "sinfo"
|
||||||
|
set usage {sinfo init|diag|config|server|device|command [parameter]}
|
||||||
|
set version 0.6
|
||||||
|
|
||||||
|
class server {
|
||||||
|
proc server {this name} {
|
||||||
|
set ($this,name) $name
|
||||||
|
|
||||||
|
proc name {this} {
|
||||||
|
return [format "server.name = \{ %s \}" $($this,name)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
proc ~server {this} {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class sinfot {
|
||||||
|
proc sinfot {this} {}
|
||||||
|
proc ~sinfot {this} {}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc helpMsgStr args {
|
||||||
|
return [formatMsg $sinfo::name "usage" $sinfo::usage]
|
||||||
|
}
|
||||||
|
|
||||||
|
proc debug args {
|
||||||
|
if {$sinfo::debug < 1} {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
set l [llength $args]
|
||||||
|
set dMsg "Script code event"
|
||||||
|
set dVal " "
|
||||||
|
if {$l > 0} {
|
||||||
|
set dMsg [lindex $args 0]
|
||||||
|
if {$l > 1} {
|
||||||
|
set dVal [lindex $args 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sinWrite [format "sinfo::debug: %s" [format $dMsg $dVal]] "value"
|
||||||
|
}
|
||||||
|
|
||||||
|
proc diag args {
|
||||||
|
set flag [lindex $args 0]
|
||||||
|
set msg [format "diag=%s" $flag]
|
||||||
|
switch $flag {
|
||||||
|
"on" {
|
||||||
|
set sinfo::debug 1
|
||||||
|
}
|
||||||
|
"off" {
|
||||||
|
set sinfo::debug 0
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
if {1 == $sinfo::debug} {
|
||||||
|
set msg "diag=on"
|
||||||
|
} else {
|
||||||
|
set msg "diag=off"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [format "sinfo.diag = \{ %s \}" $msg]
|
||||||
|
}
|
||||||
|
|
||||||
|
proc formatMsg {objName parName msg} {
|
||||||
|
# return [format "%s.%s = \{ %s \}" $objName $parName $msg]
|
||||||
|
# set msgStr [format "%s.%s = %s " $objName $parName $msg]
|
||||||
|
#sinWrite "DEBUG formatMsg: msg = $msg" "value"
|
||||||
|
return "$objName.$parName=$msg"
|
||||||
|
}
|
||||||
|
|
||||||
|
proc writeObjPar {objName parName} {
|
||||||
|
return [format "%s.%s = \{ %s \}" \
|
||||||
|
$objName $parName [set ::$objName::$parName]]
|
||||||
|
}
|
||||||
|
|
||||||
|
proc writeError {objName msg} {
|
||||||
|
# return [format "%s.error = \{ %s \}" $objName $msg]
|
||||||
|
set msg [format "%s.error = \{ %s \}" $objName $msg]
|
||||||
|
sinWrite $msg "error"
|
||||||
|
return $msg
|
||||||
|
}
|
||||||
|
|
||||||
|
proc writeNspPar {objName parName} {
|
||||||
|
set result ::
|
||||||
|
append result $objName :: $parName
|
||||||
|
# return [format "%s.%s = \{ %s \}" $objName $parName [set $result]]
|
||||||
|
sinWrite [format "%s" [set $result]] "value"
|
||||||
|
}
|
||||||
|
|
||||||
|
proc writeList {objName parName parList} {
|
||||||
|
# return [format "%s.%s = %s " $objName $parName \
|
||||||
|
# [join $parList $sinfo::delimiter]]
|
||||||
|
set msg [format "%s" [join $parList $sinfo::delimiter]]
|
||||||
|
sinWrite $msg "value"
|
||||||
|
#return $msg
|
||||||
|
}
|
||||||
|
|
||||||
|
proc writeNamespaceChildren {obj key nsp} {
|
||||||
|
set chList {}
|
||||||
|
set nameList {}
|
||||||
|
set chList [namespace children $nsp]
|
||||||
|
set l [llength $chList]
|
||||||
|
for {set i 0} {$i < $l} {incr i} {
|
||||||
|
lappend nameList [namespace tail [lindex $chList $i]]
|
||||||
|
}
|
||||||
|
writeList $obj $key $nameList
|
||||||
|
}
|
||||||
|
|
||||||
|
proc writeNamespaceList {obj key nsp} {
|
||||||
|
set nameList {}
|
||||||
|
foreach v [info vars ${nsp}::*] {
|
||||||
|
lappend nameList [namespace tail $v]
|
||||||
|
}
|
||||||
|
writeList $obj $key $nameList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc sinfo::server args {
|
||||||
|
array set argv [arga $args]
|
||||||
|
debug "sinfo::server, server.argv = { %s }" [array get argv]
|
||||||
|
set parSet {}
|
||||||
|
set parNames {}
|
||||||
|
if {$argv(bKey)} {
|
||||||
|
set key $argv(key)
|
||||||
|
debug "sinfo::server, key = $key"
|
||||||
|
switch $key {
|
||||||
|
"connection" -
|
||||||
|
"experiment" -
|
||||||
|
"help" -
|
||||||
|
"key" -
|
||||||
|
"list"
|
||||||
|
{
|
||||||
|
debug "sinfo::server, in switch $key, sinfox list server $key"
|
||||||
|
set nameList [sinfox list server $key]
|
||||||
|
sinfo::writeList "server" $key $nameList
|
||||||
|
}
|
||||||
|
"command" -
|
||||||
|
"device" -
|
||||||
|
"devicetype" -
|
||||||
|
"group" -
|
||||||
|
"interface"
|
||||||
|
{
|
||||||
|
if {$argv(bName)} {
|
||||||
|
set name $argv(name)
|
||||||
|
debug "sinfo::server, using name $name"
|
||||||
|
#sinWrite [format "DEBUG: if bname, key = %s, name = %s" $key $name] "value"
|
||||||
|
set nameList [sinfox list server $key $name]
|
||||||
|
sinfo::writeList "server" $name $nameList
|
||||||
|
#todo: improve response for unknown name
|
||||||
|
# eg server.error={device=foo}
|
||||||
|
} else {
|
||||||
|
set nameList [sinfox list server $key]
|
||||||
|
debug "sinfo::server, key=$key, nameList = $nameList"
|
||||||
|
sinfo::writeList "server" $key $nameList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"gtdevice"
|
||||||
|
{
|
||||||
|
if {$argv(bName)} {
|
||||||
|
set name $argv(name)
|
||||||
|
if [info exists ::server::gtDeviceList::$name] {
|
||||||
|
sinfo::writeNspPar server::gtDeviceList $name
|
||||||
|
} else {
|
||||||
|
set msg [format "key=%s.%s" "server" $key]
|
||||||
|
return [sinfo::writeList "server" error $msg]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
writeList "server" $key [gumtree::gtDeviceList]
|
||||||
|
# sinfo::writeNamespaceList "server" $key \
|
||||||
|
# [ ::server::gtDeviceList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default {
|
||||||
|
puts default
|
||||||
|
if [info exists ::server::$key] {
|
||||||
|
sinfo::writeNspPar server $key
|
||||||
|
} else {
|
||||||
|
set msg [format "key=%s.%s" "server" $key]
|
||||||
|
return [sinfo::writeList "server" error $msg]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
# writeNamespaceList $objName
|
||||||
|
set nameList [sinfox list server list]
|
||||||
|
writeList "server" "list" $nameList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc sinfo::checkType {objName} {
|
||||||
|
if { [string compare -nocase $objName server] == 0 } then {
|
||||||
|
set return "server"
|
||||||
|
} elseif { [string compare -nocase $objName sequencer] == 0 } then {
|
||||||
|
set return "sequencer"
|
||||||
|
} else {
|
||||||
|
switch [SICSType $objName] {
|
||||||
|
COUNT -
|
||||||
|
DRIV { return "device" }
|
||||||
|
COM { return "command" }
|
||||||
|
TEXT { return "object" }
|
||||||
|
default { return "unknown" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc sinfo::list args {
|
||||||
|
array set argv [arga $args]
|
||||||
|
debug "sinfo.argv = { %s }" [array get argv]
|
||||||
|
set argc [llength $args]
|
||||||
|
set objName $argv(objName)
|
||||||
|
set key $argv(key)
|
||||||
|
set name $argv(name)
|
||||||
|
sinfo::debug "sinfo.numargs = %s" $argc
|
||||||
|
if {$argc < 1} {
|
||||||
|
sinWrite [sinfo::helpMsgStr] "value"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sinfo::debug "object = %s" $argv(objName)
|
||||||
|
if $argv(bKey) {
|
||||||
|
sinfo::debug "key = %s" $argv(key)
|
||||||
|
}
|
||||||
|
if $argv(bName) {
|
||||||
|
sinfo::debug "name = %s" $argv(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
set parList {}
|
||||||
|
set numPars 0
|
||||||
|
|
||||||
|
set objType [checkType $objName]
|
||||||
|
sinfo::debug "sinfo.objectType = %s" $objType
|
||||||
|
|
||||||
|
switch $objType {
|
||||||
|
device
|
||||||
|
{
|
||||||
|
set nameList [sinfox list $objName $key $name]
|
||||||
|
writeList $objName $key $nameList
|
||||||
|
}
|
||||||
|
command
|
||||||
|
{
|
||||||
|
debug "sinfo.message = { %s is command objectType}" $objName
|
||||||
|
}
|
||||||
|
server
|
||||||
|
{
|
||||||
|
set cmd [format "sinfo::server %s %s %s %s" \
|
||||||
|
$objName $key $argv(name) $argv(val)]
|
||||||
|
return [eval $cmd]
|
||||||
|
}
|
||||||
|
sequencer
|
||||||
|
{
|
||||||
|
debug "sinfo.message = { %s is sequencer objectType}" $objName
|
||||||
|
if {$argv(bKey)} {
|
||||||
|
set key $argv(key)
|
||||||
|
switch $key {
|
||||||
|
"command"
|
||||||
|
{
|
||||||
|
if $bName {
|
||||||
|
set target [format "::sequencer::%s" $name]
|
||||||
|
sinfo::writeNamespaceList $objName $name $target
|
||||||
|
} else {
|
||||||
|
sinfo::writeNamespaceChildren $objName \
|
||||||
|
$key ::sequencer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sinfo::writeNamespaceList "sequencer" "list" "::sequencer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object
|
||||||
|
{
|
||||||
|
# todo: test for interface name
|
||||||
|
switch $objName {
|
||||||
|
default {
|
||||||
|
writeError "sinfo" \
|
||||||
|
[format "'%s' is invalid object" $objName]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unknown -
|
||||||
|
default {
|
||||||
|
writeError "sinfo" [format "'%s' has invalid object type" $objName]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# wrapper procs for sinfo class
|
||||||
|
|
||||||
|
proc sinfo args {
|
||||||
|
set l [llength $args]
|
||||||
|
if {$l < 1} {
|
||||||
|
sinWrite [sinfo::helpMsgStr] "value"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
set arglist [ split $args ]
|
||||||
|
set objName [lindex $arglist 0]
|
||||||
|
set cmd [format "sinfo::%s $args" $objName]
|
||||||
|
#sinWrite "DEBUG: $cmd" "value"
|
||||||
|
# set cmd $args
|
||||||
|
#set cmd "sinfo::list $args"
|
||||||
|
#FIXME the command should provide the output code for sinWrite
|
||||||
|
#sinWrite [eval $cmd] "value"
|
||||||
|
eval $cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
proc sin args {
|
||||||
|
set argc [llength $args]
|
||||||
|
if {$argc < 1} {
|
||||||
|
set msg \
|
||||||
|
"sin.usage = \
|
||||||
|
{ sin \[server|sequencer|device|command\] \[parameter\] }"
|
||||||
|
sinWrite $msg "value"
|
||||||
|
} else {
|
||||||
|
sinWrite [sinfo::list $args] "value"
|
||||||
|
}
|
||||||
|
}
|
115
sinfox.h
Normal file
115
sinfox.h
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
#ifndef ANSTO_SINFOX
|
||||||
|
#define ANSTO_SINFOX
|
||||||
|
#include <sics.h>
|
||||||
|
#include <conman.h>
|
||||||
|
|
||||||
|
typedef struct __Sinfox {
|
||||||
|
pObjectDescriptor pDes; /* required as first field */
|
||||||
|
const char *buildVersion;
|
||||||
|
const char *configName;
|
||||||
|
const char *configVersion;
|
||||||
|
const char *description;
|
||||||
|
const char *instrument;
|
||||||
|
const char *schemaVersion;
|
||||||
|
Tcl_Interp *tTcl;
|
||||||
|
} Sinfox;
|
||||||
|
|
||||||
|
typedef struct __Sinfox *pSinfox;
|
||||||
|
|
||||||
|
#ifndef SICSSITE /* Avoid duplicate declaration in site_ansto.c */
|
||||||
|
|
||||||
|
const int iNumInfoKeys = 6;
|
||||||
|
char *pInfoKeys[7] = {
|
||||||
|
"buildVersion",
|
||||||
|
"configName",
|
||||||
|
"configVersion",
|
||||||
|
"description",
|
||||||
|
"instrument",
|
||||||
|
"schemaVersion",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const int iNumCommandKeys = 3;
|
||||||
|
char *pCommandKeys[4] = {
|
||||||
|
"argument",
|
||||||
|
"device",
|
||||||
|
"interface",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const int iNumDeviceKeys = 3;
|
||||||
|
char *pDeviceKeys[4] = {
|
||||||
|
"attribute",
|
||||||
|
"command",
|
||||||
|
"interface",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const int iNumDeviceTypes = 24;
|
||||||
|
char *pDeviceTypes[25] = {
|
||||||
|
"4-circle-calculus",
|
||||||
|
"anticollider",
|
||||||
|
"chopper",
|
||||||
|
"chopperadaptor",
|
||||||
|
"connection",
|
||||||
|
"crystalselector",
|
||||||
|
"environment monitor",
|
||||||
|
"environment controller",
|
||||||
|
"gpib",
|
||||||
|
"hklscan",
|
||||||
|
"hmcontrol",
|
||||||
|
"lin2ang",
|
||||||
|
"local maximum detector",
|
||||||
|
"maximizer",
|
||||||
|
"mesure",
|
||||||
|
"motor",
|
||||||
|
"mulmot",
|
||||||
|
"omega2theta",
|
||||||
|
"rs232 controller",
|
||||||
|
"scanobject",
|
||||||
|
"sicsvariable",
|
||||||
|
"singlecounter",
|
||||||
|
"velocityselector",
|
||||||
|
"xytable",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const int iNumIFaces = 4;
|
||||||
|
char *pIFaces[5] = {
|
||||||
|
"callback",
|
||||||
|
"countable",
|
||||||
|
"drivable",
|
||||||
|
"environment",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const int iNumServerKeys = 10;
|
||||||
|
char *pServerKeys[11] = {
|
||||||
|
"help",
|
||||||
|
"list",
|
||||||
|
"command",
|
||||||
|
"connection",
|
||||||
|
"device",
|
||||||
|
"devicetype",
|
||||||
|
"experiment",
|
||||||
|
"group",
|
||||||
|
"interface",
|
||||||
|
"key",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* SICSSITE */
|
||||||
|
|
||||||
|
/*--------------------- lifecycle -------------------------------------- */
|
||||||
|
int InstallSinfox(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
void DeleteSinfox(void *pSelf);
|
||||||
|
|
||||||
|
/*--------------------- operations --------------------------------------*/
|
||||||
|
int SinfoxAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
#endif /* ANSTO_SINFOX */
|
8
status.c
8
status.c
@ -181,7 +181,8 @@
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*------------------- The CallBack function for interest ------------------*/
|
/*------------------- The CallBack function for interest ------------------*/
|
||||||
static int StatusCallback(int iEvent, void *pEvent, void *pUser)
|
static int StatusCallback(int iEvent, void *pEvent, void *pUser,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
SConnection *pCon;
|
SConnection *pCon;
|
||||||
char pBueffel[80];
|
char pBueffel[80];
|
||||||
@ -191,7 +192,9 @@
|
|||||||
pCon = (SConnection *)pUser;
|
pCon = (SConnection *)pUser;
|
||||||
|
|
||||||
sprintf(pBueffel,"status = %s", pText[(int)eCode]);
|
sprintf(pBueffel,"status = %s", pText[(int)eCode]);
|
||||||
|
SCPushContext2(pCon,cc);
|
||||||
SCWrite(pCon,pBueffel,eWarning);
|
SCWrite(pCon,pBueffel,eWarning);
|
||||||
|
SCPopContext(pCon);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +220,8 @@
|
|||||||
strtolower(argv[1]);
|
strtolower(argv[1]);
|
||||||
if(strcmp(argv[1],"interest") == 0)
|
if(strcmp(argv[1],"interest") == 0)
|
||||||
{
|
{
|
||||||
lID = RegisterCallback(pCall, VALUECHANGE, StatusCallback,
|
lID = RegisterCallback(pCall, SCGetContext(pCon),
|
||||||
|
VALUECHANGE, StatusCallback,
|
||||||
pCon, NULL);
|
pCon, NULL);
|
||||||
SCRegister(pCon,pSics, pCall,lID);
|
SCRegister(pCon,pSics, pCall,lID);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
|
18
stptok.h
Normal file
18
stptok.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
** stptok() -- public domain by Ray Gardner, modified by Bob Stout
|
||||||
|
**
|
||||||
|
** You pass this function a string to parse, a buffer to receive the
|
||||||
|
** "token" that gets scanned, the length of the buffer, and a string of
|
||||||
|
** "break" characters that stop the scan. It will copy the string into
|
||||||
|
** the buffer up to any of the break characters, or until the buffer is
|
||||||
|
** full, and will always leave the buffer null-terminated. It will
|
||||||
|
** return a pointer to the first non-breaking character after the one
|
||||||
|
** that stopped the scan.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STPSTPTOK
|
||||||
|
#define STPSTPTOK
|
||||||
|
|
||||||
|
char *stptok(const char *s, char *tok, size_t toklen, char *brk);
|
||||||
|
|
||||||
|
#endif
|
91
sycFormat.tcl
Normal file
91
sycFormat.tcl
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# Implements sycFormat which is needed by the sycamore protocol.
|
||||||
|
# Deobjectified version of the ANSTO original
|
||||||
|
#
|
||||||
|
# Original Implementor: Paul Hathaway, Ferdi Francescini
|
||||||
|
#
|
||||||
|
# More bugs introduced by: Mark Koennecke
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if { [info exists sycinit] == 0 } {
|
||||||
|
set sycinit 1
|
||||||
|
Publish sycformat Spy
|
||||||
|
}
|
||||||
|
|
||||||
|
array set statusMap [ list OKOK "ok" \
|
||||||
|
HWIdle "idle" \
|
||||||
|
HWBusy "running" \
|
||||||
|
HWFault "fault" \
|
||||||
|
HWPosFault "posfault" \
|
||||||
|
HWCrash "crash" \
|
||||||
|
NOMEMORY "nomemory" \
|
||||||
|
HWNoBeam "nobeam" \
|
||||||
|
HWPause "pause" \
|
||||||
|
HWWarn "warn" \
|
||||||
|
HWRedo "redo" ]
|
||||||
|
|
||||||
|
|
||||||
|
# 'tag' and 'msgString' parameters must be passed within braces
|
||||||
|
# eg sycFormat con0004 t000005 s1 event {s1} {type.position status.HWBusy}
|
||||||
|
proc sycformat {connID transID devID msgFlag tag msgString} {
|
||||||
|
global statusMap cache
|
||||||
|
|
||||||
|
set fullmatch ""; set msg ""; set eventType ""; set status ""
|
||||||
|
set position ""
|
||||||
|
|
||||||
|
proc _prefix {flag} {
|
||||||
|
upvar connID cID transID tID devID dID
|
||||||
|
return "\[$cID:$tID:$dID:$flag\]"
|
||||||
|
}
|
||||||
|
|
||||||
|
regexp {<(.*)>} $msgString match msg
|
||||||
|
regexp {type\.(\w*)} $msgString match eventType
|
||||||
|
regexp {status\.(\w*)} $msgString match status
|
||||||
|
|
||||||
|
# Skip useless messages
|
||||||
|
if {[string first "Parameter Listing for motor" $msgString] > -1} {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
switch $msgFlag {
|
||||||
|
"start" {
|
||||||
|
set output "[_prefix start] $msgString"
|
||||||
|
|
||||||
|
}
|
||||||
|
"event" {
|
||||||
|
switch $eventType {
|
||||||
|
"POSITION" {
|
||||||
|
regexp {(\w+)\.position *= *(\d+(?:\.\d+)?)} $msgString match device position
|
||||||
|
set output "[_prefix event] $tag={type=$eventType,$devID.position=$position}"
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
# Error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"out" {
|
||||||
|
# Concatenate multiple messages into a comma separated list
|
||||||
|
if [info exists cache($transID)] {
|
||||||
|
append msg ", " $msgString
|
||||||
|
eval "lappend cache($transID) $msg"
|
||||||
|
} else {
|
||||||
|
eval "lappend cache($transID) $msgString"
|
||||||
|
}
|
||||||
|
set output ""
|
||||||
|
}
|
||||||
|
"finish" {
|
||||||
|
if [info exists cache($transID)] {
|
||||||
|
set output "[_prefix out] $tag=\{$cache($transID)\}"
|
||||||
|
append output "\n[_prefix finish]"
|
||||||
|
unset cache($transID)
|
||||||
|
} else {
|
||||||
|
set output "[_prefix finish]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
set output "[_prefix $msgFlag] $msgString"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $output
|
||||||
|
}
|
||||||
|
|
219
sycamore.tcl
Normal file
219
sycamore.tcl
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
#source $sychome/stooop/mkpkgidx.tcl
|
||||||
|
#source stooop.tcl
|
||||||
|
#set tcl_pkgPath $sychome
|
||||||
|
# ClientPut $tcl_pkgPath "value"
|
||||||
|
# package require stooop 4 ;# load stooop package
|
||||||
|
# namespace forget stooop::* ;# remove if previously loaded
|
||||||
|
# namespace import stooop::*
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# source $sychome/ns_site.tcl
|
||||||
|
# source $sychome/ns_sequencer.tcl
|
||||||
|
# source $sychome/ns_server.tcl
|
||||||
|
|
||||||
|
set STACKTRACE 0
|
||||||
|
proc stackTrace args {
|
||||||
|
set level [ info level ]
|
||||||
|
ClientPut "====================" "value"
|
||||||
|
for {set i 1} {$i < $level} {incr i} {
|
||||||
|
ClientPut [info level $i] "value"
|
||||||
|
ClientPut " " "value"
|
||||||
|
}
|
||||||
|
ClientPut "====================" "value"
|
||||||
|
}
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# testing stubs when SICS modules not available
|
||||||
|
# proc sinfox args
|
||||||
|
# proc ClientPut {msg oCode}
|
||||||
|
# proc SICSType {objName}
|
||||||
|
# source stubs.tcl
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Sycamore Utilities: tcl procedures required by sycamore implementation
|
||||||
|
|
||||||
|
proc sinWrite {msg oCode} {
|
||||||
|
# simplest processing of format for now
|
||||||
|
global STACKTRACE
|
||||||
|
if {$STACKTRACE} {
|
||||||
|
stackTrace
|
||||||
|
}
|
||||||
|
ClientPut $msg $oCode
|
||||||
|
}
|
||||||
|
|
||||||
|
proc varexist {nsp var} {
|
||||||
|
return [expr [string compare $nsp$var [namespace which -variable $nsp$var]]==0]
|
||||||
|
}
|
||||||
|
|
||||||
|
#proc sycFormat {connID transID devID msgFlag args} {
|
||||||
|
# return "\[$connID:$transID:$devID:$msgFlag\] $args"
|
||||||
|
#}
|
||||||
|
#source $sychome/sycFormat.tcl
|
||||||
|
#publish sycFormat spy
|
||||||
|
|
||||||
|
proc arga argStr {
|
||||||
|
set args [ split $argStr ]
|
||||||
|
set argc [llength $args]
|
||||||
|
# syc::debug "arga.argc = %s" $argc
|
||||||
|
set objName ""
|
||||||
|
set key ""
|
||||||
|
set name ""
|
||||||
|
set val ""
|
||||||
|
set bObj [expr $argc > 0]
|
||||||
|
set bKey [expr $argc > 1]
|
||||||
|
set bName [expr $argc > 2]
|
||||||
|
set bVal [expr $argc > 3]
|
||||||
|
if $bObj {
|
||||||
|
set objName [string tolower [lindex $args 0]]
|
||||||
|
#syc::debug "arga.objName = %s" $objName
|
||||||
|
}
|
||||||
|
if $bKey {
|
||||||
|
set key [string tolower [lindex $args 1]]
|
||||||
|
#syc::debug "arga.key = %s" $key
|
||||||
|
}
|
||||||
|
if $bName {
|
||||||
|
set name [string tolower [lindex $args 2]]
|
||||||
|
}
|
||||||
|
if $bVal {
|
||||||
|
set val [string tolower [lindex $args 3]]
|
||||||
|
}
|
||||||
|
# ? cannot get 'array set' to work in the form:
|
||||||
|
# array set argv {
|
||||||
|
# argc $argc
|
||||||
|
# objName $objName
|
||||||
|
# ... etcetera
|
||||||
|
# }
|
||||||
|
set argv(argc) $argc
|
||||||
|
set argv(bObj) $bObj
|
||||||
|
set argv(bKey) $bKey
|
||||||
|
set argv(bName) $bName
|
||||||
|
set argv(bVal) $bVal
|
||||||
|
set argv(objName) $objName
|
||||||
|
set argv(key) $key
|
||||||
|
set argv(name) $name
|
||||||
|
set argv(val) $val
|
||||||
|
# would like to return associative array
|
||||||
|
# for now, settle for list
|
||||||
|
# syc::debug "arga.argv = { %s }" [array get argv]
|
||||||
|
return [array get argv]
|
||||||
|
}
|
||||||
|
|
||||||
|
# alternative solution for passing arguments around
|
||||||
|
#class argv {
|
||||||
|
# proc argv {this args} {
|
||||||
|
# set ($this,argc) [llength $args]
|
||||||
|
# set ($this,objName) ""
|
||||||
|
# set ($this,key) ""
|
||||||
|
# set ($this,name) ""
|
||||||
|
# set ($this,val) ""
|
||||||
|
# set ($this,bObj) [expr $l > 0]
|
||||||
|
# set ($this,bKey) [expr $l > 0]
|
||||||
|
# set ($this,bName) [expr $l > 1]
|
||||||
|
# set ($this,bVal) [expr $l > 2]
|
||||||
|
# if $($this,bObj) {
|
||||||
|
# set ($this,objName) [lindex $args 0]
|
||||||
|
# }
|
||||||
|
# if $($this,bKey) {
|
||||||
|
# set ($this,key) [lindex $args 0]
|
||||||
|
# }
|
||||||
|
# if $($this,bName) {
|
||||||
|
# set ($this,name) [lindex $args 1]
|
||||||
|
# }
|
||||||
|
# if $($this,bVal) {
|
||||||
|
# set ($this,val) [lindex $args 2]
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# proc ~argv {this} {}
|
||||||
|
#}
|
||||||
|
#
|
||||||
|
## -----------------------------------------------------------------------------
|
||||||
|
# working idea for making diagnostic class global
|
||||||
|
class diagnostic {
|
||||||
|
proc diagnostic {this} {
|
||||||
|
set ($this,id) $this
|
||||||
|
set ($this,debug) 0
|
||||||
|
}
|
||||||
|
proc ~diagnostic {this} {}
|
||||||
|
|
||||||
|
proc diag {this flag} {
|
||||||
|
set msg [format "diag=%s" $flag]
|
||||||
|
switch $flag {
|
||||||
|
"on" {
|
||||||
|
set ($this,debug) 1
|
||||||
|
}
|
||||||
|
"off" {
|
||||||
|
set ($this,debug) 0
|
||||||
|
}
|
||||||
|
default {}
|
||||||
|
}
|
||||||
|
if {1 == ($this,debug)} {
|
||||||
|
set msg "diag=on"
|
||||||
|
} else {
|
||||||
|
set msg "diag=off"
|
||||||
|
}
|
||||||
|
return [format "%s.diag = \{ %s \}" $this $msg]
|
||||||
|
}
|
||||||
|
|
||||||
|
proc debug {this dMsg dVal} {
|
||||||
|
if {1 > ($this,debug)} {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sinWrite [format "%s::debug: %s" $this [format $dMsg $dVal]] "value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------------
|
||||||
|
# Class for module static variables and methods
|
||||||
|
class syc {
|
||||||
|
# class lifecycle methods
|
||||||
|
proc syc {this} {}
|
||||||
|
proc ~syc {this} {}
|
||||||
|
|
||||||
|
# static data members
|
||||||
|
set debug 0
|
||||||
|
|
||||||
|
# static methods
|
||||||
|
proc debug args {
|
||||||
|
if {$syc::debug < 1} {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
set l [llength $args]
|
||||||
|
set dMsg "Script code event"
|
||||||
|
set dVal " "
|
||||||
|
if {$l > 0} {
|
||||||
|
set dMsg [lindex $args 0]
|
||||||
|
if {$l > 1} {
|
||||||
|
set dVal [lindex $args 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sinWrite [format "syc::debug: %s" [format $dMsg $dVal]] "value"
|
||||||
|
}
|
||||||
|
|
||||||
|
proc diag args {
|
||||||
|
set flag [lindex $args 0]
|
||||||
|
set msg [format "diag=%s" $flag]
|
||||||
|
switch $flag {
|
||||||
|
"on" {
|
||||||
|
set syc::debug 1
|
||||||
|
}
|
||||||
|
"off" {
|
||||||
|
set syc::debug 0
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
if {1 == $syc::debug} {
|
||||||
|
set msg "diag=on"
|
||||||
|
} else {
|
||||||
|
set msg "diag=off"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [format "syc.diag = \{ %s \}" $msg]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------------
|
||||||
|
sinWrite "Loading sinfo" "value"
|
||||||
|
#source $sychome/sinfo.tcl
|
||||||
|
#publish sinfo spy
|
||||||
|
# source $sychome/sequencer.tcl
|
||||||
|
|
2
task.c
2
task.c
@ -293,7 +293,7 @@ ente:
|
|||||||
assert(self);
|
assert(self);
|
||||||
assert(self->iID == TASKERID);
|
assert(self->iID == TASKERID);
|
||||||
|
|
||||||
/* Cycle until back at our selves killed. */
|
/* Cycle until back at ourselves */
|
||||||
pEnd = self->pCurrent;
|
pEnd = self->pCurrent;
|
||||||
pEnd->iStatus = WAITING;
|
pEnd->iStatus = WAITING;
|
||||||
IncrTaskPointer(self);
|
IncrTaskPointer(self);
|
||||||
|
2
task.h
2
task.h
@ -106,7 +106,7 @@
|
|||||||
int TaskYield(pTaskMan self);
|
int TaskYield(pTaskMan self);
|
||||||
/*
|
/*
|
||||||
does one cycle of the task loop and returns to the caller.This call allows
|
does one cycle of the task loop and returns to the caller.This call allows
|
||||||
other tasks to execute while a task executeds a lengthy calculation.
|
other tasks to execute while a task executes a lengthy calculation.
|
||||||
*/
|
*/
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
int TaskSignal(pTaskMan self, int iSignal, void *pSigData);
|
int TaskSignal(pTaskMan self, int iSignal, void *pSigData);
|
||||||
|
395
tclmotdriv.c
Normal file
395
tclmotdriv.c
Normal file
@ -0,0 +1,395 @@
|
|||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
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.
|
||||||
|
|
||||||
|
The Tcl functions to implement the interface are called with the name
|
||||||
|
of the motor as first parameter followed by any additional parameters
|
||||||
|
such as the position to run to for run. Functions have to return the proper
|
||||||
|
SICS return codes for a motor driver as integer numbers.
|
||||||
|
|
||||||
|
The Tcl function list is initialized from a Tcl-array which holds function
|
||||||
|
names for the entries:
|
||||||
|
- getpos
|
||||||
|
- run
|
||||||
|
- status
|
||||||
|
- geterror
|
||||||
|
- fixit
|
||||||
|
This Tcl-array is passed as parameter on creating the motor. In order to
|
||||||
|
facilitate error handling, a motor parameter errorcode is available to
|
||||||
|
store errors between invocations.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, December 2005
|
||||||
|
--------------------------------------------------------------------------*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "sics.h"
|
||||||
|
#include "modriv.h"
|
||||||
|
#include "tclmotdriv.h"
|
||||||
|
|
||||||
|
#define FUNCNOTFOUND -11000
|
||||||
|
#define TCLERROR -11001
|
||||||
|
#define NOTCLRESULT -11002
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
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);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int GetTclPos(void *self, float *fPos){
|
||||||
|
TCLDriv *pDriv;
|
||||||
|
char tclCommand[1024];
|
||||||
|
int status;
|
||||||
|
const char *result = NULL;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
pDriv = (TCLDriv *)self;
|
||||||
|
|
||||||
|
pDriv->errorCode = 0;
|
||||||
|
if(!buildStandardCommandPart(pDriv,"getpos",tclCommand,1023)){
|
||||||
|
pDriv->errorCode = FUNCNOTFOUND;
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = Tcl_Eval(pServ->pSics->pTcl,tclCommand);
|
||||||
|
result = Tcl_GetStringResult(pServ->pSics->pTcl);
|
||||||
|
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 tclCommand[1024];
|
||||||
|
char num[80];
|
||||||
|
int status;
|
||||||
|
const char *result = NULL;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
pDriv = (TCLDriv *)self;
|
||||||
|
|
||||||
|
pDriv->errorCode = 0;
|
||||||
|
if(!buildStandardCommandPart(pDriv,"run",tclCommand,1023)){
|
||||||
|
pDriv->errorCode = FUNCNOTFOUND;
|
||||||
|
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);
|
||||||
|
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 TclError(void *self, int *iCode, char *error, int iErrLen){
|
||||||
|
TCLDriv *pDriv;
|
||||||
|
char tclCommand[1024];
|
||||||
|
int status = 1;
|
||||||
|
const char *result = NULL;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
pDriv = (TCLDriv *)self;
|
||||||
|
|
||||||
|
if(evaluateInternalErrors(pDriv,iCode,error,iErrLen) == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
strncpy(error,result,iErrLen);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int TclFix(void *self, int iError, float fNew){
|
||||||
|
TCLDriv *pDriv;
|
||||||
|
char tclCommand[1024];
|
||||||
|
char num[80];
|
||||||
|
int status;
|
||||||
|
const char *result = NULL;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
pDriv = (TCLDriv *)self;
|
||||||
|
|
||||||
|
pDriv->errorCode = 0;
|
||||||
|
if(!buildStandardCommandPart(pDriv,"fixit",tclCommand,1023)){
|
||||||
|
pDriv->errorCode = FUNCNOTFOUND;
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
snprintf(num,79,"%f",fNew);
|
||||||
|
strncat(tclCommand,num,1023-strlen(tclCommand));
|
||||||
|
|
||||||
|
status = Tcl_Eval(pServ->pSics->pTcl,tclCommand);
|
||||||
|
result = Tcl_GetStringResult(pServ->pSics->pTcl);
|
||||||
|
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 TclHalt(void *self)
|
||||||
|
{
|
||||||
|
TCLDriv *pDriv;
|
||||||
|
char tclCommand[1024];
|
||||||
|
int status;
|
||||||
|
const char *result = NULL;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
pDriv = (TCLDriv *)self;
|
||||||
|
|
||||||
|
pDriv->errorCode = 0;
|
||||||
|
if(!buildStandardCommandPart(pDriv,"halt",tclCommand,1023)){
|
||||||
|
pDriv->errorCode = FUNCNOTFOUND;
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = Tcl_Eval(pServ->pSics->pTcl,tclCommand);
|
||||||
|
result = Tcl_GetStringResult(pServ->pSics->pTcl);
|
||||||
|
if(result == NULL){
|
||||||
|
pDriv->errorCode = NOTCLRESULT;
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
if(status != TCL_OK){
|
||||||
|
pDriv->errorCode = TCLERROR;
|
||||||
|
strncpy(pDriv->tclError,result,1023);
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
return OKOK;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static int TclStat(void *self)
|
||||||
|
{
|
||||||
|
TCLDriv *pDriv;
|
||||||
|
char tclCommand[1024];
|
||||||
|
int status;
|
||||||
|
const char *result = NULL;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
pDriv = (TCLDriv *)self;
|
||||||
|
|
||||||
|
pDriv->errorCode = 0;
|
||||||
|
if(!buildStandardCommandPart(pDriv,"status",tclCommand,1023)){
|
||||||
|
pDriv->errorCode = FUNCNOTFOUND;
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = Tcl_Eval(pServ->pSics->pTcl,tclCommand);
|
||||||
|
result = Tcl_GetStringResult(pServ->pSics->pTcl);
|
||||||
|
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 TclSetPar(void *self, SConnection *pCon, char *name, float newValue){
|
||||||
|
TCLDriv *pDriv = (TCLDriv *) self;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
assert(pCon);
|
||||||
|
|
||||||
|
if(strcmp(name,"hardupperlim") == 0)
|
||||||
|
{
|
||||||
|
pDriv->fUpper = newValue;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(strcmp(name,"hardlowerlim") == 0)
|
||||||
|
{
|
||||||
|
pDriv->fLower = newValue;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(strcmp(name,"errorcode") == 0)
|
||||||
|
{
|
||||||
|
pDriv->errorCode = (int)newValue;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
static int TclGetPar(void *self, char *name, float *value){
|
||||||
|
TCLDriv *pDriv = (TCLDriv *) self;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
|
||||||
|
if(strcmp(name,"errorcode") == 0)
|
||||||
|
{
|
||||||
|
*value = (float)pDriv->errorCode;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void KillTCL(void *pData)
|
||||||
|
{
|
||||||
|
TCLDriv *pDriv = (TCLDriv *) pData;
|
||||||
|
|
||||||
|
if(pDriv != NULL){
|
||||||
|
DeleteStringDict(pDriv->mappings);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
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;
|
||||||
|
|
||||||
|
while(funcText[count] != NULL) {
|
||||||
|
funcName = Tcl_GetVar2(pServ->pSics->pTcl,arrayName,funcText[count],TCL_GLOBAL_ONLY);
|
||||||
|
if(funcName == NULL) {
|
||||||
|
snprintf(error,255,"ERROR: entry for %s not found in tcl-array %s",
|
||||||
|
funcText[count], arrayName);
|
||||||
|
SCWrite(pCon,error,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
StringDictAddPair(pDriv->mappings,funcText[count],(char *)funcName);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
pDriv->name = strdup("Tcl-Driver");
|
||||||
|
strncpy(pDriv->motName, argv[1], 131);
|
||||||
|
pDriv->GetPosition = GetTclPos;
|
||||||
|
pDriv->RunTo = TclRun;
|
||||||
|
pDriv->GetStatus = TclStat;
|
||||||
|
pDriv->GetError = TclError;
|
||||||
|
pDriv->TryAndFixIt = TclFix;
|
||||||
|
pDriv->SetDriverPar = TclSetPar;
|
||||||
|
pDriv->GetDriverPar = TclGetPar;
|
||||||
|
pDriv->Halt = TclHalt;
|
||||||
|
pDriv->KillPrivate = KillTCL;
|
||||||
|
|
||||||
|
return (MotorDriver *)pDriv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
41
tclmotdriv.h
Normal file
41
tclmotdriv.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
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 errorCode;
|
||||||
|
char tclError[1024];
|
||||||
|
char motName[132];
|
||||||
|
} TCLDriv;
|
||||||
|
#endif
|
193
velo.c
193
velo.c
@ -1,4 +1,4 @@
|
|||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
V E L O C I T Y S E L E C T O R
|
V E L O C I T Y S E L E C T O R
|
||||||
|
|
||||||
The velocity selector module for SICS. For documentation see velo.w
|
The velocity selector module for SICS. For documentation see velo.w
|
||||||
@ -116,6 +116,37 @@
|
|||||||
/* Success ! */
|
/* Success ! */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
static void VSListForbidden(pVelSel self, SConnection *pCon){
|
||||||
|
Tcl_DString message;
|
||||||
|
int status;
|
||||||
|
Verbot Alcatraz;
|
||||||
|
char pBueffel[256];
|
||||||
|
|
||||||
|
Tcl_DStringInit(&message);
|
||||||
|
/*
|
||||||
|
The first entry in the forbidden region thing is meant to
|
||||||
|
contain the overall range: skip it!
|
||||||
|
*/
|
||||||
|
status = LLDnodePtr2First(self->iForbidden);
|
||||||
|
LLDnodeDataTo(self->iForbidden,&Alcatraz);
|
||||||
|
if(status == 1){
|
||||||
|
snprintf(pBueffel,255,"%s.forbidden = {%f -inf", self->pName, Alcatraz.fMax);
|
||||||
|
Tcl_DStringAppend(&message,pBueffel,strlen(pBueffel));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now search the forbidden regions */
|
||||||
|
status = LLDnodePtr2Next(self->iForbidden);
|
||||||
|
while(status != 0){
|
||||||
|
LLDnodeDataTo(self->iForbidden,&Alcatraz);
|
||||||
|
snprintf(pBueffel,255,", %f - %f", Alcatraz.fMin, Alcatraz.fMax);
|
||||||
|
Tcl_DStringAppend(&message,pBueffel,strlen(pBueffel));
|
||||||
|
status = LLDnodePtr2Next(self->iForbidden);
|
||||||
|
}
|
||||||
|
Tcl_DStringAppend(&message,"}",1);
|
||||||
|
SCWrite(pCon,Tcl_DStringValue(&message),eValue);
|
||||||
|
Tcl_DStringFree(&message);
|
||||||
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static long VSSetValue(void *pData,SConnection *pCon, float fVal)
|
static long VSSetValue(void *pData,SConnection *pCon, float fVal)
|
||||||
{
|
{
|
||||||
@ -701,7 +732,7 @@
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static pEVDriver MakeDummyVel(pVelSel pVel)
|
pEVDriver MakeDummyVel(pVelSel pVel)
|
||||||
{
|
{
|
||||||
pEVDriver pNew = NULL;
|
pEVDriver pNew = NULL;
|
||||||
pVelPrivate ich = NULL;
|
pVelPrivate ich = NULL;
|
||||||
@ -869,51 +900,6 @@
|
|||||||
EVRegisterController(FindEMON(pSics),pBueffel,pNew->pMonitor,pCon);
|
EVRegisterController(FindEMON(pSics),pBueffel,pNew->pMonitor,pCon);
|
||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
static int TTFindNumber(Tcl_Interp *pTcl,char *pPtr, float *fVal)
|
|
||||||
{
|
|
||||||
int iRet;
|
|
||||||
char *pEnd;
|
|
||||||
char *pMark;
|
|
||||||
double dVal;
|
|
||||||
|
|
||||||
pEnd = pPtr + strlen(pPtr);
|
|
||||||
|
|
||||||
/* advance to first non blank or non = character */
|
|
||||||
while( (isspace(*pPtr)) || (*pPtr == '=') )
|
|
||||||
{
|
|
||||||
pPtr++;
|
|
||||||
if(pPtr >= pEnd)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find end of string */
|
|
||||||
pMark = pPtr;
|
|
||||||
while( (!isspace(*pMark)))
|
|
||||||
{
|
|
||||||
pMark++;
|
|
||||||
if(pMark >= pEnd)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* replace pMark temporarily by \0 */
|
|
||||||
*pMark = '\0';
|
|
||||||
|
|
||||||
/* now read number from pPtr */
|
|
||||||
iRet = Tcl_GetDouble(pTcl,pPtr,&dVal);
|
|
||||||
if(iRet != TCL_OK)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fix back and return */
|
|
||||||
*pMark = ' ';
|
|
||||||
*fVal = (float)dVal;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SConnection *pCon;
|
SConnection *pCon;
|
||||||
@ -935,7 +921,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
static int RotationInterest(int iEvent, void *pData, void *pUser)
|
static int RotationInterest(int iEvent, void *pData, void *pUser,
|
||||||
|
commandContext cc)
|
||||||
{
|
{
|
||||||
CBData *pDat = NULL;
|
CBData *pDat = NULL;
|
||||||
float *fVal = NULL;
|
float *fVal = NULL;
|
||||||
@ -949,12 +936,12 @@
|
|||||||
if(iEvent == ROTSTART)
|
if(iEvent == ROTSTART)
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"%s Starting",pDat->pName);
|
sprintf(pBueffel,"%s Starting",pDat->pName);
|
||||||
SCWrite(pDat->pCon,pBueffel,eWarning);
|
SCWriteInContext(pDat->pCon,pBueffel,eWarning,cc);
|
||||||
}
|
}
|
||||||
else if(iEvent == ROTMOVE)
|
else if(iEvent == ROTMOVE)
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"%s.rpm = %f",pDat->pName, *fVal);
|
sprintf(pBueffel,"%s.rpm = %f",pDat->pName, *fVal);
|
||||||
SCWrite(pDat->pCon,pBueffel,eWarning);
|
SCWriteInContext(pDat->pCon,pBueffel,eWarning,cc);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -980,10 +967,6 @@
|
|||||||
assert(pCon);
|
assert(pCon);
|
||||||
assert(pSics);
|
assert(pSics);
|
||||||
|
|
||||||
/* convert to text for parsing */
|
|
||||||
Arg2Text(argc,argv,pCommand, 511);
|
|
||||||
strtolower(pCommand);
|
|
||||||
|
|
||||||
if(argc < 2)
|
if(argc < 2)
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"ERROR: %s expects at least one parameter",argv[0]);
|
sprintf(pBueffel,"ERROR: %s expects at least one parameter",argv[0]);
|
||||||
@ -1026,10 +1009,10 @@
|
|||||||
}
|
}
|
||||||
pCB->pCon = pCon;
|
pCB->pCon = pCon;
|
||||||
pCB->pName = strdup(argv[0]);
|
pCB->pName = strdup(argv[0]);
|
||||||
lID = RegisterCallback(self->pCall, ROTSTART, RotationInterest,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon), ROTSTART, RotationInterest,
|
||||||
pCB, KillCB);
|
pCB, KillCB);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
lID = RegisterCallback(self->pCall, ROTMOVE, RotationInterest,
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon), ROTMOVE, RotationInterest,
|
||||||
pCB, NULL);
|
pCB, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
@ -1082,6 +1065,13 @@
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* list forbidden regions */
|
||||||
|
if(strcmp(argv[1],"forbidden") == 0)
|
||||||
|
{
|
||||||
|
VSListForbidden(self,pCon);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* status, prints a status message */
|
/* status, prints a status message */
|
||||||
if(strcmp(argv[1],"status") == 0)
|
if(strcmp(argv[1],"status") == 0)
|
||||||
{
|
{
|
||||||
@ -1133,6 +1123,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(strcmp(argv[1],"rottolerance") == 0){
|
||||||
|
if(argc > 2){
|
||||||
|
/* set case */
|
||||||
|
iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&dVal);
|
||||||
|
if(iRet != TCL_OK){
|
||||||
|
sprintf(pBueffel,"ERROR: %s not recognized as numeric value for fMax",
|
||||||
|
argv[2]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!SCMatchRights(pCon,usUser)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
self->pDriv->fTolerance = dVal;
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
sprintf(pBueffel,"%s.rottolerance = %f",
|
||||||
|
argv[0],self->pDriv->fTolerance);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* initialise the tilt and rot to current values */
|
/* initialise the tilt and rot to current values */
|
||||||
iRet = VSGetRotation(self,&fRot);
|
iRet = VSGetRotation(self,&fRot);
|
||||||
if(!iRet)
|
if(!iRet)
|
||||||
@ -1143,61 +1157,50 @@
|
|||||||
iRet = MotorGetSoftPosition(self->pTilt,pCon,&fTilt);
|
iRet = MotorGetSoftPosition(self->pTilt,pCon,&fTilt);
|
||||||
if(!iRet)
|
if(!iRet)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ERROR: velocity selector operation aborted",eError);
|
SCWrite(pCon,"ERROR: failed to read tilt angle",eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* search for Tilt */
|
/* search for Tilt */
|
||||||
pPtr = strstr(pCommand,"tilt");
|
if(strcmp(argv[1],"tilt") == 0){
|
||||||
if(pPtr) /* analyse tilt */
|
if(argc > 2){
|
||||||
{
|
/* set case */
|
||||||
|
iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&dVal);
|
||||||
|
if(iRet != TCL_OK){
|
||||||
|
sprintf(pBueffel,"ERROR: %s not recognized as numeric value for fMax",
|
||||||
|
argv[2]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
fTilt = dVal;
|
||||||
iDrive = 1;
|
iDrive = 1;
|
||||||
iRet = TTFindNumber(pSics->pTcl,pPtr+strlen("tilt"),&fTilt);
|
} else {
|
||||||
if(!iRet)
|
|
||||||
{
|
|
||||||
/* no new value, just print the current one */
|
|
||||||
MotorGetSoftPosition(self->pTilt,pCon,&fTilt);
|
|
||||||
sprintf(pBueffel,"%s tilt = %f",argv[0],fTilt);
|
sprintf(pBueffel,"%s tilt = %f",argv[0],fTilt);
|
||||||
SCWrite(pCon,pBueffel,eError);
|
SCWrite(pCon,pBueffel,eError);
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* serch for rottolerance */
|
|
||||||
pPtr = strstr(pCommand,"rottolerance");
|
|
||||||
if(pPtr) /* analyse rottolerance */
|
|
||||||
{
|
|
||||||
iDrive = 1;
|
|
||||||
iRet = TTFindNumber(pSics->pTcl,pPtr+strlen("rottolerance"),&fTol);
|
|
||||||
if(!iRet)
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"%s.rottolerance = %f",
|
|
||||||
argv[0],self->pDriv->fTolerance);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self->pDriv->fTolerance = fTol;
|
|
||||||
SCSendOK(pCon);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* same for rot */
|
/* same for rot */
|
||||||
pPtr = strstr(pCommand,"rot");
|
if(strcmp(argv[1],"rot") == 0){
|
||||||
if(pPtr) /* analyse tilt */
|
if(argc > 2){
|
||||||
{
|
/* set case */
|
||||||
iDrive = 1;
|
iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&dVal);
|
||||||
iRet = TTFindNumber(pSics->pTcl,pPtr+strlen("rot"),&fVal);
|
if(iRet != TCL_OK){
|
||||||
if(!iRet)
|
sprintf(pBueffel,"ERROR: %s not recognized as numeric value for fMax",
|
||||||
{
|
argv[2]);
|
||||||
sprintf(pBueffel,"%s rot = %f",argv[0],fRot);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
SCWrite(pCon,pBueffel,eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fRot = fVal;
|
fRot = dVal;
|
||||||
|
iDrive = 1;
|
||||||
|
} else {
|
||||||
|
sprintf(pBueffel,"%s rot = %f",argv[0],fRot);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do drive if we really need to */
|
/* do drive if we really need to */
|
||||||
|
1
velo.h
1
velo.h
@ -46,7 +46,6 @@
|
|||||||
|
|
||||||
#line 264 "velo.w"
|
#line 264 "velo.w"
|
||||||
|
|
||||||
|
|
||||||
#line 164 "velo.w"
|
#line 164 "velo.w"
|
||||||
|
|
||||||
int VSGetLossCurrent(pVelSel self, SConnection *pCon, float *fLoss);
|
int VSGetLossCurrent(pVelSel self, SConnection *pCon, float *fLoss);
|
||||||
|
@ -11,7 +11,7 @@ lappend auto_path /data/koenneck/bin/tcl
|
|||||||
|
|
||||||
set INI(DefUser) Spy
|
set INI(DefUser) Spy
|
||||||
set INI(DefPasswd) 007
|
set INI(DefPasswd) 007
|
||||||
set INI(ServerPort) 3006
|
set INI(ServerPort) 2911
|
||||||
set INI(InterruptPort) 2913
|
set INI(InterruptPort) 2913
|
||||||
set INI(box) localhost
|
set INI(box) localhost
|
||||||
set INI(usPasswd) Rosy
|
set INI(usPasswd) Rosy
|
||||||
|
Reference in New Issue
Block a user