- 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:
koennecke
2005-12-22 22:16:10 +00:00
parent 603a4fc14b
commit b3138f1197
67 changed files with 4650 additions and 682 deletions

305
SCinter.c
View File

@ -2,8 +2,6 @@
Implementation file for the SICS-interpreter.
Mark Koennecke, November 1996
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
Mark Koennecke, August 2001, modified SicsWriteStatus to write motor
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 <stdlib.h>
@ -61,6 +69,15 @@
/* M.Z. */
#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)
@ -219,22 +236,11 @@
return 1;
}
/*------------------------------------------------------------------------*/
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;
}
}
/*------------------------------------------------------------------------*/
#define MAXLEN 256
#define MAXCOM 50
extern char *stptok(char *s, char *tok, unsigned int toklen, char *brk);
extern char *SkipSpace(char *pPtr);
/*-----------------------------------------------------------------------*/
int InterpExecute(SicsInterp *self,SConnection *pCon, char *pText)
{
int iCount = 0;
@ -275,6 +281,7 @@
iRet = 1;
goto deleteArgv;
}
if(argv[0] == NULL)
{
SCWrite(pCon,"ERROR: failed to parse command",eError);
@ -298,7 +305,13 @@
self->eOut = eStatus;
Tcl_ResetResult((Tcl_Interp *)self->pTcl);
MacroPush(pCon);
SCWrite(pCon, "", eStart);
pCon->conStatus = 0;
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();
deleteArgv:
@ -519,6 +532,74 @@ static void printAll(SicsInterp *pSics, SConnection *pCon)
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
as specified bi the id given
@ -625,9 +706,9 @@ static void printMatch(SicsInterp *pSics, SConnection *pCon, char *mask)
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;
Tcl_DString txt;
@ -644,7 +725,7 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
{
if(pCurrent->pData != NULL)
{
if(iHasType(pCurrent->pData,type))
if(iHasType(pCurrent->pData,typeName))
{
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 argc, char *argv[])
{
char pType[256];
int i;
if(argc < 2)
{
@ -701,6 +784,13 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
printType(pSics,pCon,"Motor");
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]);
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;
}
/*---------------------------------------------------------------------------*/
@ -848,3 +965,149 @@ void *FindDrivable(SicsInterp *pSics, char *name){
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;
}

View File

@ -87,7 +87,6 @@ typedef struct __SINTER
If the command is found, 1 is returned on success, 0 on failure in
the command.
----------------------------------------------------------------------------*/
CommandList *FindCommand(SicsInterp *pInterp, char *name);
/*
Searches the Interpreters pInterp command list for a command

View File

@ -46,6 +46,9 @@ typedef enum {
eInError,
eStatus,
eValue,
eStart,
eFinish,
eEvent,
eWarning,
eError
} OutCode;

View File

@ -64,6 +64,7 @@
void *pUserData;
KillFuncIT pKill;
int iEvent;
commandContext comCon;
} CallBackItem, *pCallBackItem;
/*------------------------------------------------------------------------*/
static int CheckPointer(pICallBack self)
@ -140,7 +141,7 @@
LLDnodeDataTo(self->iList,&sItem);
if(sItem.iEvent == iEvent)
{
iRet = sItem.pFunc(iEvent, pEventData,sItem.pUserData);
iRet = sItem.pFunc(iEvent, pEventData,sItem.pUserData,sItem.comCon);
if(!iRet)
{
iResult = 0;
@ -153,7 +154,7 @@
/*--------------------------------------------------------------------------*/
static long lCount = 1L;
long RegisterCallback(pICallBack self, int iEvent,
long RegisterCallback(pICallBack self, commandContext comCon, int iEvent,
SICSCallBack pFunc,
void *pUserData, KillFunc pKFunc)
{
@ -170,7 +171,8 @@
sItem.iEvent = iEvent;
sItem.pUserData = pUserData;
sItem.pKill = pKFunc;
sItem.comCon = comCon;
LLDnodeAppendFrom(self->iList,&sItem);
return sItem.iID;
}
@ -244,7 +246,8 @@ static int CallbackWrite(SConnection *pCon,char *message, int outCode)
/*-----------------------------------------------------------------------
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;
Tcl_Interp *pTcl;
@ -332,7 +335,8 @@ int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0;
}
Arg2Text(argc-4,&argv[4],pBuffer,131);
lID = RegisterCallback(pCall,iEvent,ScriptCallback,
lID = RegisterCallback(pCall,SCGetContext(pCon),
iEvent,ScriptCallback,
strdup(pBuffer),free);
sprintf(pBuffer,"callback = %ld", lID);
SCWrite(pCon,pBuffer,eValue);

16
commandcontext.h Normal file
View 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

View File

@ -19,8 +19,12 @@
int ListObjects(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*
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

166
conman.c
View File

@ -88,7 +88,6 @@ extern pServer pServ;
/*------------- a number for generating automatic names --------------------*/
static int iName = 0;
static int SCNormalWrite(SConnection *self, char *buffer, int iOut);
static SConnection *freeConnections = NULL;
static long lastIdent = 0;
/*===========================================================================*/
@ -167,25 +166,31 @@ extern pServer pServ;
return NULL;
}
pRes->iOutput = eInError; /* gets everything except internal messages */
pRes->iFiles = 0; /* default: no logfiles */
pRes->inUse = 0;
pRes->iMacro = 0;
pRes->iTelnet = 0;
pRes->eInterrupt = eContinue;
pRes->lMagic = CONMAGIC;
pRes->iLogin = 0;
pRes->listening = 0;
pRes->conStart = time(NULL);
pRes->write = SCNormalWrite;
for(i = 0; i < 10; i++)
{
pRes->pFiles[i] = NULL;
}
/* install command */
AddCommand(pSics, ConName(pRes->ident), ConSicsAction, NULL,pRes);
return pRes;
pRes->iOutput = eInError; /* gets everything except internal messages */
pRes->iFiles = 0; /* default: no logfiles */
pRes->inUse = 0;
pRes->iMacro = 0;
pRes->iTelnet = 0;
pRes->eInterrupt = eContinue;
pRes->lMagic = CONMAGIC;
pRes->iLogin = 0;
pRes->listening = 0;
pRes->conStart = time(NULL);
pRes->write = SCNormalWrite;
for(i = 0; i < 10; i++)
{
pRes->pFiles[i] = NULL;
}
/* initialise context variables */
pRes->iCmdCtr = 0;
pRes->conEventType=-1;
pRes->conStatus=-1;
pRes->contextStack = LLDcreate(sizeof(commandContext));
/* install command */
AddCommand(pSics, ConName(pRes->ident), ConSicsAction, NULL,pRes);
return pRes;
}
/*--------------------------------------------------------------------------*/
@ -436,8 +441,11 @@ extern pServer pServ;
{
DeleteCommandStack(pVictim->pStack);
}
pVictim->lMagic=0; /* make a write to a freed connection harmless */
/* finally free pVictim*/
LLDdelete(pVictim->contextStack);
FreeConnection(pVictim);
}
/*---------------------------------------------------------------------------*/
@ -531,6 +539,15 @@ extern pServer pServ;
}
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, ...)
{
@ -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;
char pBueffel[80];
@ -686,7 +703,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
return 1;
}
/*--------------------------------------------------------------------------*/
static int SCWriteWithOutcode(SConnection *self, char *buffer, int iOut)
int SCWriteWithOutcode(SConnection *self, char *buffer, int iOut)
{
int i, iPtr, iRet, length;
char pBueffel[80];
@ -1343,7 +1360,14 @@ static void writeToLogFiles(SConnection *self, char *buffer)
self->inUse++;
self->eInterrupt = eContinue;
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);
SCPopContext(self);
if(self->parameterChange == 1)
{
/*
@ -1658,7 +1682,8 @@ static void writeToLogFiles(SConnection *self, char *buffer)
The callback function for connection callbacks. Invokes command
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;
@ -1667,7 +1692,9 @@ static void writeToLogFiles(SConnection *self, char *buffer)
if(self->pAction)
{
SCPushContext2(self->pCon,cc);
InterpExecute(pServ->pSics,self->pCon,self->pAction);
SCPopContext(self->pCon);
}
return 1;
}
@ -1755,7 +1782,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
pCB->pSics = pSics;
pCB->pAction = strdup(pBueffel);
sItem.pInterface = pInterface;
sItem.lID = RegisterCallback(pInterface, iEvent, ConCallBack,
sItem.lID = RegisterCallback(pInterface, SCGetContext(pCB->pCon), iEvent, ConCallBack,
pCB, CBKill);
LLDnodeAppendFrom(self->iList,&sItem);
SCSendOK(pCon);
@ -1961,6 +1988,48 @@ SConnection *SCLoad(SCStore *con) {
}
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) {
SConnection *next;
@ -1970,3 +2039,52 @@ void KillFreeConnections(void) {
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;
}

View File

@ -23,6 +23,7 @@
#include "SCinter.h"
#include "network.h"
#include "obdes.h"
#include "commandcontext.h"
#define MAXLOGFILES 10
@ -59,6 +60,16 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int parameterChange;
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 */
pCosta pStack;
@ -103,6 +114,8 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int SCOnlySockWrite(SConnection *self, char *buffer, int iOut);
int SCFileWrite(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 *********************************** */
int SCRegister(SConnection *pCon, SicsInterp *pSics,
void *pInter, long lID);
@ -158,4 +171,17 @@ SConnection *SCLoad(SCStore *con);
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

View File

@ -708,7 +708,8 @@
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;
pMonEvent pMon = NULL;
@ -731,7 +732,7 @@
*/
rights = SCGetRights(pCon);
SCSetRights(pCon,usSpy);
SCWrite(pCon,pBueffel,eWarning);
SCWriteInContext(pCon,pBueffel,eWarning,cc);
SCSetRights(pCon,rights);
return 1;
}
@ -896,7 +897,7 @@
SCWrite(pCon,pBueffel,eValue);
return 1;
case 9: /* interest */
lID = RegisterCallback(self->pCall, MONITOR, CounterInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon), MONITOR, CounterInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);

8
danu.c
View File

@ -95,7 +95,8 @@ static int writeDataNumber(pDataNumber self, int iNum)
return 1;
}
/*------------------- 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;
SConnection *pCon = NULL;
@ -120,7 +121,7 @@ static int writeDataNumber(pDataNumber self, int iNum)
if(iNum > 0)
{
snprintf(pBueffel,131,"sicsdatanumber = %d", iNum);
SCWrite(pCon,pBueffel,eValue);
SCWriteInContext(pCon,pBueffel,eValue,cc);
}
return 1;
}
@ -330,7 +331,8 @@ int NewThousand(pDataNumber self)
}
if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, VALUECHANGE, InterestCallback,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
VALUECHANGE, InterestCallback,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);

View File

@ -62,6 +62,7 @@
pObjectDescriptor pDescriptor;
float fVal;
char *name;
commandContext comCon;
} DevEntry, *pDevEntry;
/*-------------------------------------------------------------------------*/
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, void *pData,
@ -80,6 +81,7 @@
pNew->pData = pData;
pNew->name = strdup(name);
pNew->fVal = fVal;
memset(&pNew->comCon,0,sizeof(commandContext));
return pNew;
}
/*-------------------------------------------------------------------------*/
@ -228,7 +230,9 @@
SCWrite(pCon,"ERROR: memory exhausted in Device Executor ",eError);
return 0;
}
pNew->comCon = SCGetContext(pCon);
strncpy(pNew->comCon.deviceID,name,SCDEVIDLEN);
/* start it */
pDrivInt = pDes->GetInterface(pData,DRIVEID);
pCountInt = pDes->GetInterface(pData,COUNTID);
@ -250,7 +254,12 @@
if(iRet == OKOK)
{
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->iStatus = DEVDONE;
/* if no task: start it */
@ -263,6 +272,7 @@
self,
1);
self->iEnd = 0;
pCon->conStatus = HWBusy;
}
return 1;
}
@ -373,7 +383,10 @@
pIDrivable pDrivInt = NULL;
int eCode;
int isCounting=0, isDriving=0;
char pBueffel[512];
SConnection *pCon;
pCon = self->pOwner;
assert(self);
/* Sometimes this gets called, though nothing is running. There are
@ -397,6 +410,11 @@
LLDnodeDataTo(self->iList,&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);
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
@ -423,10 +441,12 @@
ExeInterest(self, pDev, "finished");
DeleteDevEntry(pDev);
LLDnodeDelete(self->iList);
SCWrite(pCon, "", eFinish);
iRet = LLDnodePtr2Prev(self->iList);
if(SCGetInterrupt(self->pOwner) != eContinue)
{
self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1;
}
self->iStatus = DEVDONE;
@ -435,6 +455,7 @@
ExeInterest(self, pDev, "finished with problem");
DeleteDevEntry(pDev);
pDev = NULL;
SCWrite(pCon, "", eFinish);
LLDnodeDataTo(self->iList,&pDev);
LLDnodeDelete(self->iList);
iRet = LLDnodePtr2Prev(self->iList);
@ -446,6 +467,7 @@
if(SCGetInterrupt(self->pOwner) != eContinue)
{
self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1;
}
break;
@ -455,6 +477,7 @@
{
SetStatus(eEager);
self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1;
}
break;
@ -464,6 +487,7 @@
{
ContinueExecution(self);
self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1;
}
break;
@ -482,6 +506,7 @@
ExeInterest(self, pDev, "finished with problem");
DeleteDevEntry(pDev);
LLDnodeDelete(self->iList);
SCWrite(pCon, "", eFinish);
self->iStatus = DEVERROR;
if(pDrivInt)
{
@ -490,10 +515,12 @@
if(SCGetInterrupt(self->pOwner) != eContinue)
{
self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1;
}
break;
}
SCPopContext(self->pOwner);
}
iRet = LLDnodePtr2Next(self->iList);
}
@ -641,7 +668,9 @@
}
iRet = LLDnodePtr2Next(self->iList);
}
SCPushContext(self->pOwner,0,"system");
SCWrite(self->pOwner,"ERROR: Full Stop called!!",eError);
SCPopContext(self->pOwner);
if(SCGetInterrupt(self->pOwner) > eContinue)
{
self->iStatus = DEVINT;
@ -666,7 +695,7 @@
}
else if(pCountInt)
{
pDrivInt->Halt(pDev->pData);
pCountInt->Halt(pDev->pData);
}
return 1;
}
@ -699,6 +728,8 @@
pDev = (pDevEntry)LLDnodePtr(self->iList);
if(pDev)
{
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
if(pCountInt)
{
@ -709,7 +740,8 @@
}
}
}
}
SCPopContext(self->pOwner);
iRet = LLDnodePtr2Next(self->iList);
}
SetStatus(ePaused);
@ -735,7 +767,6 @@
{
return 1;
}
}
iRet = LLDnodePtr2Next(self->iList);
}
@ -760,11 +791,13 @@
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
if(pCountInt)
{
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
iRet = pCountInt->Continue(pDev->pData,self->pOwner);
if(!iRet)
{
iRes = 0;
}
SCPopContext(self->pOwner);
}
}
@ -842,12 +875,15 @@
return iRet;
}
/*------------------- 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(text);
SCPushContext2(pCon,cc);
SCWrite(pCon, text, eValue);
SCPopContext(pCon);
return 1;
}
/*--------------------------------------------------------------------------*/
@ -866,7 +902,8 @@
if (argc == 2) {
if (strcmp(argv[1], "interest") == 0)
{
list = RegisterCallback(self->pCall, DRIVSTAT, DrivStatCallback,
list = RegisterCallback(self->pCall, SCGetContext(pCon),
DRIVSTAT, DrivStatCallback,
pCon, NULL);
SCRegister(pCon, pSics, self->pCall,list);
SCSendOK(pCon);
@ -1025,15 +1062,6 @@
{
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");
}
#ifdef DEBUG
@ -1077,10 +1105,12 @@
{
if(self->pOwner)
{
SCPushContext(self->pOwner,0,"system");
SCWrite(self->pOwner,
"ERROR: Interrupting Current Hardware Operation",
eError);
SCSetInterrupt(self->pOwner,*iInt);
SCSetInterrupt(self->pOwner,*iInt);
SCPopContext(self->pOwner);
}
StopExe(self,"all");
}

View File

@ -51,6 +51,8 @@ is set, without the current value is printed.
<DT> nvs loss
<DD> Starts a loss current measurement on the velocity selector and prints the
result.
<DT>nvs forbidden
<DD>Prints a list of forbidden speed regions for this selector.
<DT>nvs status
<DD>Prints a status summary of the velocity selector.
</DL>

View File

@ -173,6 +173,16 @@
eError);
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)
{
@ -191,6 +201,7 @@
/* go to idle when stopped */
if(self->iStop)
{
notifyStatus(self, pCon, HWIdle);
return HWIdle;
}
@ -209,16 +220,19 @@
case DEVFAULT:
sprintf(pBueffel,"ERROR: %s",pError);
SCWrite(pCon,pBueffel,eError);
notifyStatus(self, pCon, HWFault);
return HWFault;
case DEVREDO:
sprintf(pBueffel,"WARNING: Fixing problem %s",pError);
SCWrite(pCon,pBueffel,eWarning);
notifyStatus(self, pCon, HWBusy);
return HWBusy;
break;
}
}
else if(iRet == -1 ) /* pending */
{
notifyStatus(self, pCon, HWBusy);
return HWBusy;
}
@ -228,6 +242,7 @@
self->pName);
SCWrite(pCon,pBueffel,eError);
self->eMode = EVIdle;
notifyStatus(self, pCon, HWFault);
return HWFault;
}
@ -254,6 +269,7 @@
self->pName);
SCWrite(pCon,pBueffel,eError);
self->eMode = EVMonitor;
notifyStatus(self, pCon, HWIdle);
return HWIdle;
}
tol = ObVal(self->pParam, TOLERANCE);
@ -272,13 +288,16 @@
self->pName, (self->lastt + tmo - now)*1.0);
SCWrite(pCon,pBueffel,eStatus);
}
notifyStatus(self, pCon, HWBusy);
return HWBusy;
}
if (now > self->lastt + tmo)
{
self->eMode = EVMonitor;
notifyStatus(self, pCon, HWIdle);
return HWIdle;
}
notifyStatus(self, pCon, HWBusy);
return HWBusy;
}
else
@ -289,6 +308,7 @@
SCWrite(pCon,pBueffel,eStatus);
self->lastt -= now;
}
notifyStatus(self, pCon, HWBusy);
return HWBusy;
}
}
@ -1009,7 +1029,8 @@ static void ErrReport(pEVControl self)
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;
SConnection *pCon = (SConnection *)pUserData;
@ -1017,7 +1038,8 @@ static void ErrReport(pEVControl self)
if(iEvent == VALUECHANGE)
{
SCWrite(pCon,pBuf,eValue);
pCon->conEventType=POSITION;
SCWriteInContext(pCon,pBuf,eEvent,cc);
return 1;
}
return 1;
@ -1075,7 +1097,8 @@ static void ErrReport(pEVControl self)
/* install automatic notification */
else if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, VALUECHANGE, EVCallBack,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
VALUECHANGE, EVCallBack,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);
@ -1414,13 +1437,14 @@ int RemoveEVController(SConnection *pCon, char *name) {
SCWrite(pCon,"ERROR: cannot delete while running",eError);
return 0;
}
if (!FindCommandData(pServ->pSics, name, "Environment Controller")) {
SCPrintf(pCon,eError,"ERROR: no environment controller %s found",name);
EVUnregister(FindEMON(pServ->pSics),name);
iRet = RemoveCommand(pServ->pSics,name);
if(!iRet)
{
sprintf(pBueffel,"ERROR: %s not found, NOT deleted",name);
SCWrite(pCon,pBueffel,eError);
return 0;
}
EVUnregister(FindEMON(pServ->pSics),name);
RemoveCommand(pServ->pSics,name);
return 1;
}
/*-------------------------------------------------------------------------

View File

@ -42,7 +42,8 @@
#define BATCHAREA 15
#define BATCHEND 16
#define DRIVSTAT 17
#define STATUS 18
#define POSITION 19 /* Position event for motors - ffr */
#line 104 "event.w"

View File

@ -284,25 +284,27 @@ static pExeInfo makeExeInfo(SConnection *pCon, pExeMan self){
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;
char *name = (char *)pEvent;
char pBueffel[132];
if(iEvent == BATCHSTART){
snprintf(pBueffel,131,"BATCHSTART=%s",name);
SCWrite(self->pCon,pBueffel,eWarning);
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
return 1;
}
if(iEvent == BATCHEND){
snprintf(pBueffel,131,"BATCHEND=%s",name);
SCWrite(self->pCon,pBueffel,eWarning);
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
return 1;
}
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;
char pBueffel[256];
int start, end, lineno;
@ -317,7 +319,7 @@ static int LineCallBack(int iEvent, void *pEvent, void *pUser){
exeBufRange(buf,&start,&end,&lineno);
snprintf(pBueffel,255,"%s.range = %d = %d",exeBufName(buf),
start,end);
SCWrite(self->pCon,pBueffel,eWarning);
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
return 1;
}
return 0;
@ -332,13 +334,13 @@ static void registerCallbacks(SConnection *pCon, SicsInterp *pSics,
if(info == NULL){
return;
}
lID = RegisterCallback(self->pCall, BATCHSTART, BufferCallback,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHSTART, BufferCallback,
info, killExeInfo);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, BATCHEND, BufferCallback,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHEND, BufferCallback,
info, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, BATCHAREA, LineCallBack,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHAREA, LineCallBack,
info, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
}

View File

@ -450,6 +450,59 @@ double sign(double a, double b){
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,
double *omeganb, double *gamma, double *nu){

View File

@ -70,7 +70,7 @@ void pol2det(psdDescription *psd, double gamma, double nu, int *x, int *y);
Z1 = UB *h
------------------------------------------------------------------------*/
/**
* calculate stt, om, chi and phi in order to put z1 into the bissecting
* calculate stt, om, chi and phi in order to put z1 into the bissecting
* diffraction condition. Returns 1 on success and 0 if z1 and lambda
* were invalid. The m version acts upon a matrix.
*/
@ -122,6 +122,10 @@ void z1FromAngles(double lambda, double stt, double om,
*/
int bisToNormalBeam(double twotheta, double omega, double chi, double phi,
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.

104
histmem.c
View File

@ -439,6 +439,7 @@
free(pNew);
return NULL;
}
StringDictAddPair(pNew->pOption,"driver",driver);
StringDictAddPair(pNew->pOption,"update","0");
/* initialise driver */
@ -531,6 +532,8 @@
SCWrite(pCon,pBueffel,eError);
return 0;
}
StringDictAddPair(pNew->pOption,"name",argv[1]);
/* install HM as command */
iRet = AddCommand(pSics,argv[1],HistAction,DeleteHistMemory,(void *)pNew);
@ -918,7 +921,8 @@ void HistDirty(pHistMem self)
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;
char pBueffel[512];
@ -927,14 +931,14 @@ void HistDirty(pHistMem self)
{
pCon = (SConnection *)pUser;
assert(pCon);
SCWrite(pCon,"HMCOUNTSTART",eWarning);
SCWriteInContext(pCon,"HMCOUNTSTART",eWarning,cc);
return 1;
}
else if(iEvent == COUNTEND)
{
pCon = (SConnection *)pUser;
assert(pCon);
SCWrite(pCon,"HMCOUNTEND",eWarning);
SCWriteInContext(pCon,"HMCOUNTEND",eWarning,cc);
return 1;
}
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 argc, char *argv[])
@ -998,10 +1085,12 @@ static int checkHMEnd(pHistMem self, char *text){
strtolower(argv[1]);
if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, COUNTSTART, HMCountInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
COUNTSTART, HMCountInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, COUNTEND, HMCountInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
COUNTEND, HMCountInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);
@ -1165,6 +1254,11 @@ static int checkHMEnd(pHistMem self, char *text){
return 0;
}
}
else if(strcmp(argv[1],"list") == 0)
{
HMListOption(self,pCon);
return 1;
}
/* normal counting*/
else if(strcmp(argv[1],"count") == 0)
{

35
hkl.c
View File

@ -205,7 +205,8 @@
#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;
pSelVar pVar = NULL;
@ -236,6 +237,7 @@
pICallBack pCall = NULL, pCall2 = NULL;
pDummy pDum = NULL;
float fVal;
commandContext comCon;
assert(pCon);
assert(self);
@ -264,7 +266,10 @@
}
/* install new callback */
comCon.transID = 0;
strncpy(comCon.deviceID,"internal",SCDEVIDLEN);
self->lID = RegisterCallback(pCall2,
comCon,
WLCHANGE,
HKLCallback,
self,
@ -673,7 +678,7 @@ static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
float fSet[4], double myPsi, int iRetry)
{
int i, iTest;
double stt, om, chi, phi, gamma, nu, psi;
double stt, om, chi, phi, gamma, nu, psi, omnb;
float currentPhi, currentChi;
double ompsi, chipsi, phipsi;
MATRIX chim, phim, z4, z3;
@ -694,6 +699,7 @@ static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
{
return 0;
}
/*
phim = mat_creat(3,3,ZERO_MATRIX);
phimat(phim,(double)currentPhi);
z4 = mat_mul(phim,z1);
@ -703,6 +709,31 @@ static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
mat_free(phim);
mat_free(chim);
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

22
ifile.c
View File

@ -153,6 +153,28 @@
{
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)

View File

@ -25,6 +25,8 @@ typedef struct __IFileE
/* returns a value for a name
*/
IPair *IFAddOption(IPair *pList,char *name, char *value);
IPair *IFSetOption(IPair *pList,char *name, char *value);
int IFSaveOptions(IPair *pList,FILE *fp);
void IFDeleteOptions(IPair *pList);

View File

@ -83,6 +83,7 @@ static float EmptyGet(void *self, SConnection *pCon){
pRes->SetValue = EmptyValue;
pRes->CheckStatus = EmptyStatus;
pRes->GetValue = EmptyGet;
pRes->drivableStatus=HWIdle;
return pRes;
}
/*-------------------------------------------------------------------------*/

View File

@ -1,8 +1,8 @@
#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
Any object in SICS has to adhere to the object descriptor interface (see
file obdes.h). Furthermore SICS objects may choose to support other
@ -17,6 +17,7 @@
#ifndef SICSINTERFACES
#define SICSINTERFACES
#include "commandcontext.h"
/* interface ID's used to recognize an interface */
#define DRIVEID 513
@ -26,7 +27,7 @@
/* ----------------------- The drivable interface -----------------------*/
#line 117 "interface.w"
#line 121 "interface.w"
typedef struct {
@ -39,21 +40,22 @@
int (*CheckStatus)(void *self, SConnection *pCon);
float (*GetValue)(void *self, SConnection *pCon);
int iErrorCount;
int drivableStatus;
} IDrivable, *pIDrivable;
pIDrivable GetDrivableInterface(void *pObject);
int GetDrivablePosition(void *pObject, SConnection *pCon,
float *fPos);
int GetDrivablePosition(void *pObject, SConnection *pCon,
float *fPos);
#line 390 "interface.w"
#line 407 "interface.w"
pIDrivable CreateDrivableInterface(void);
/* ------------------------ The countable interface ---------------------*/
#line 183 "interface.w"
#line 188 "interface.w"
typedef struct {
int ID;
@ -70,23 +72,23 @@
pICountable GetCountableInterface(void *pObject);
#line 395 "interface.w"
#line 412 "interface.w"
pICountable CreateCountableInterface(void);
/* ------------------------- The CallBack Interface --------------------*/
#line 236 "interface.w"
#line 241 "interface.w"
typedef void (*KillFuncIT)(void *pData);
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;
@ -96,21 +98,22 @@
int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData);
/* 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);
int RemoveCallback(pICallBack pInterface, long iID);
int RemoveCallback2(pICallBack pInterface, void *pUserData);
int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int argc, char *argv[]);
pICallBack GetCallbackInterface(void *pData);
#line 401 "interface.w"
#line 418 "interface.w"
/*---------------------- The Environment Interface --------------------*/
#line 329 "interface.w"
#line 335 "interface.w"
typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;
typedef struct {
@ -120,13 +123,13 @@
int (*HandleError)(void *self);
} EVInterface, *pEVInterface;
#line 403 "interface.w"
#line 420 "interface.w"
#line 355 "interface.w"
#line 361 "interface.w"
pEVInterface CreateEVInterface(void);
#line 404 "interface.w"
#line 421 "interface.w"
#endif

View File

@ -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}
In order to present themselves to the system SICS objects need to adhere to
certyain interfaces. These interfaces are described in this
@ -28,33 +38,37 @@ Let's start with the objectdescriptor:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$obdes {\footnotesize ?}$\rangle\equiv$
$\langle\,$obdes\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
\mbox{}\verb@ In SICS there is the to find out what an@\\
\mbox{}\verb@ object is capable of at runtime. If this has been done a general@\\
\mbox{}\verb@ way to access those capabilities is needed. In order to do all@\\
\mbox{}\verb@ this each SICS-object is required to carry an object descriptor@\\
\mbox{}\verb@ struct as first parameter in its class/object struct. Additionslly@\\
\mbox{}\verb@ it is required to initialize this struct to something sensible.@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ This file defines this struct. Additionally a few functions of@\\
\mbox{}\verb@ general use are prototyped.@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ Mark Koennecke, June, 1997@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ copyrigth: see implementation file @\\
\mbox{}\verb@ In SICS there is the to find out what an@\\
\mbox{}\verb@ object is capable of at runtime. If this has been done a general@\\
\mbox{}\verb@ way to access those capabilities is needed. In order to do all@\\
\mbox{}\verb@ this each SICS-object is required to carry an object descriptor@\\
\mbox{}\verb@ struct as first parameter in its class/object struct. Additionslly@\\
\mbox{}\verb@ it is required to initialize this struct to something sensible.@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ This file defines this struct. Additionally a few functions of@\\
\mbox{}\verb@ general use are prototyped.@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ Mark Koennecke, June, 1997@\\
\mbox{}\verb@ @\\
\mbox{}\verb@ copyrigth: see implementation file @\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSDESCRIPTOR@\\
\mbox{}\verb@#define SICSDESCRIPTOR@\\
\mbox{}\verb@#include <stdio.h>@\\
\mbox{}\verb@#include <ifile.h>@\\
\mbox{}\verb@@\\
\mbox{}\verb@ typedef struct {@\\
\mbox{}\verb@ char *name;@\\
\mbox{}\verb@ int (*SaveStatus)(void *self, char *name,FILE *fd);@\\
\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@@\\
\mbox{}\verb@ /*---------------------------------------------------------------------------*/@\\
@ -63,9 +77,9 @@ $\langle$obdes {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ pObjectDescriptor FindDescriptor(void *pData);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@/*============================================================================@\\
\mbox{}\verb@ Objects which do not carry data need a dummy descriptor. Otherwise@\\
\mbox{}\verb@ drive or scan will protection fault when trying to drive something@\\
\mbox{}\verb@ which should not be driven. This is defined below.@\\
\mbox{}\verb@ Objects which do not carry data need a dummy descriptor. Otherwise@\\
\mbox{}\verb@ drive or scan will protection fault when trying to drive something@\\
\mbox{}\verb@ which should not be driven. This is defined below.@\\
\mbox{}\verb@*/@\\
\mbox{}\verb@@\\
\mbox{}\verb@typedef struct {@\\
@ -74,17 +88,17 @@ $\langle$obdes {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ @\\
\mbox{}\verb@@\\
\mbox{}\verb@ pDummy CreateDummy(char *name);@\\
\mbox{}\verb@ void KillDummy(void *pData); @\\
\mbox{}\verb@ void KillDummy(void *pData); @\\
\mbox{}\verb@@\\
\mbox{}\verb@ int iHasType(void *pData, char *Type);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@#endif @\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@{\NWsep}
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
@ -128,7 +142,7 @@ environment controllers fit this bill as well.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$driv {\footnotesize ?}$\rangle\equiv$
$\langle\,$driv\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
@ -143,18 +157,19 @@ $\langle$driv {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int (*CheckStatus)(void *self, SConnection *pCon);@\\
\mbox{}\verb@ float (*GetValue)(void *self, SConnection *pCon); @\\
\mbox{}\verb@ int iErrorCount;@\\
\mbox{}\verb@ int drivableStatus;@\\
\mbox{}\verb@ } IDrivable, *pIDrivable;@\\
\mbox{}\verb@@\\
\mbox{}\verb@ pIDrivable GetDrivableInterface(void *pObject); @\\
\mbox{}\verb@ int GetDrivablePosition(void *pObject, SConnection *pCon,@\\
\mbox{}\verb@ float *fPos);@\\
\mbox{}\verb@ int GetDrivablePosition(void *pObject, SConnection *pCon,@\\
\mbox{}\verb@ float *fPos);@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@{\NWsep}
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
@ -207,7 +222,7 @@ This is an interface for interacting with anything which counts.
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
$\langle$count {\footnotesize ?}$\rangle\equiv$
$\langle\,$count\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
@ -225,12 +240,12 @@ $\langle$count {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@@\\
\mbox{}\verb@ pICountable GetCountableInterface(void *pObject); @\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@{\NWsep}
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
@ -272,19 +287,19 @@ The first thing to define for such an interface is the type of the callback
function:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
$\langle$callfunc {\footnotesize ?}$\rangle\equiv$
$\langle\,$callfunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ typedef void (*KillFuncIT)(void *pData);@\\
\mbox{}\verb@ typedef int (*SICSCallBack)(int iEvent, void *pEventData, @\\
\mbox{}\verb@ void *pUserData);@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@ void *pUserData, commandContext cc);@\\
\mbox{}\verb@@{\NWsep}
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
@ -306,7 +321,7 @@ interface:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap5}
$\langle$cifunc {\footnotesize ?}$\rangle\equiv$
$\langle\,$cifunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
@ -318,21 +333,22 @@ $\langle$cifunc {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData); @\\
\mbox{}\verb@@\\
\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@ int RemoveCallback(pICallBack pInterface, long iID);@\\
\mbox{}\verb@ int RemoveCallback2(pICallBack pInterface, void *pUserData);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]); @\\
\mbox{}\verb@ int argc, char *argv[]); @\\
\mbox{}\verb@@\\
\mbox{}\verb@ pICallBack GetCallbackInterface(void *pData); @\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@{\NWsep}
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
\end{list}
\end{minipage}\\[4ex]
\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:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap6}
$\langle$envir {\footnotesize ?}$\rangle\equiv$
$\langle\,$envir\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
@ -400,12 +416,12 @@ $\langle$envir {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int (*IsInTolerance)(void *self);@\\
\mbox{}\verb@ int (*HandleError)(void *self);@\\
\mbox{}\verb@ } EVInterface, *pEVInterface;@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@{\NWsep}
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
@ -428,17 +444,17 @@ in question.
The environment interface has just one function associated with it:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap7}
$\langle$envfunc {\footnotesize ?}$\rangle\equiv$
$\langle\,$envfunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ pEVInterface CreateEVInterface(void);@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@{\NWsep}
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
@ -446,24 +462,34 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap8}
\verb@"obdes.h"@ {\footnotesize ? }$\equiv$
\verb@"obdes.h"@\nobreak\ {\footnotesize \NWtarget{nuweb?}{?} }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@@$\langle$obdes {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@\hbox{$\langle\,$obdes\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
\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}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap9}
\verb@"interface.h"@ {\footnotesize ? }$\equiv$
\verb@"interface.h"@\nobreak\ {\footnotesize \NWtarget{nuweb?}{?} }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
\mbox{}\verb@ I N T E R F A C E S@\\
\mbox{}\verb@ I N T E R F A C E S@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Any object in SICS has to adhere to the object descriptor interface (see@\\
\mbox{}\verb@ file obdes.h). Furthermore SICS objects may choose to support other@\\
@ -478,6 +504,7 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@@\\
\mbox{}\verb@#ifndef SICSINTERFACES@\\
\mbox{}\verb@#define SICSINTERFACES@\\
\mbox{}\verb@#include "commandcontext.h"@\\
\mbox{}\verb@@\\
\mbox{}\verb@/* interface ID's used to recognize an interface */@\\
\mbox{}\verb@#define DRIVEID 513@\\
@ -486,23 +513,23 @@ $\langle$envfunc {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@#define ENVIRINTERFACE 949@\\
\mbox{}\verb@@\\
\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@ pIDrivable CreateDrivableInterface(void);@\\
\mbox{}\verb@@\\
\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@ pICountable CreateCountableInterface(void);@\\
\mbox{}\verb@@\\
\mbox{}\verb@/* ------------------------- The CallBack Interface --------------------*/@\\
\mbox{}\verb@@$\langle$callfunc {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\langle$cifunc {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\hbox{$\langle\,$callfunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
\mbox{}\verb@@\hbox{$\langle\,$cifunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
\mbox{}\verb@/*---------------------- The Environment Interface --------------------*/@\\
\mbox{}\verb@@$\langle$envir {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\langle$envfunc {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\hbox{$\langle\,$envir\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
\mbox{}\verb@@\hbox{$\langle\,$envfunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$
\mbox{}\verb@@{\NWsep}
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]

View File

@ -45,11 +45,15 @@ Let's start with the objectdescriptor:
#ifndef SICSDESCRIPTOR
#define SICSDESCRIPTOR
#include <stdio.h>
#include <ifile.h>
typedef struct {
char *name;
int (*SaveStatus)(void *self, char *name,FILE *fd);
void *(*GetInterface)(void *self, int iInterfaceID);
char *description;
char *group;
IPair *pKeys;
} ObjectDescriptor, *pObjectDescriptor;
/*---------------------------------------------------------------------------*/
@ -126,6 +130,7 @@ environment controllers fit this bill as well.
int (*CheckStatus)(void *self, SConnection *pCon);
float (*GetValue)(void *self, SConnection *pCon);
int iErrorCount;
int drivableStatus;
} IDrivable, *pIDrivable;
pIDrivable GetDrivableInterface(void *pObject);
@ -236,7 +241,7 @@ function:
@d callfunc @{
typedef void (*KillFuncIT)(void *pData);
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.
@ -264,7 +269,8 @@ interface:
int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData);
/* 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);
int RemoveCallback(pICallBack pInterface, long iID);
int RemoveCallback2(pICallBack pInterface, void *pUserData);
@ -360,6 +366,16 @@ The environment interface has just one function associated with it:
@o obdes.h -d @{
@<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 @{
@ -379,6 +395,7 @@ The environment interface has just one function associated with it:
#ifndef SICSINTERFACES
#define SICSINTERFACES
#include "commandcontext.h"
/* interface ID's used to recognize an interface */
#define DRIVEID 513

View File

@ -8,6 +8,9 @@
copyright: see copyright.h
Mark Koennecke, February 2000
added zero point handling for the Jochen
Mark Koennecke, December 2005
---------------------------------------------------------------------------*/
#include <stdlib.h>
#include <math.h>
@ -25,12 +28,13 @@
pIDrivable pDriv;
pMotor lin;
float length;
float zero;
}Lin2Ang, *pLin2Ang;
/*-------------------------- conversion routines -------------------------*/
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)
@ -40,7 +44,7 @@
assert(self->length > 0.);
dt = fX/self->length;
return RD*asin(dt);
return RD*asin(dt) - self->zero;
}
/*============== functions in the interface ============================*/
static void *Lin2AngGetInterface(void *pData, int iID)
@ -65,7 +69,8 @@
if(!self)
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;
}
@ -99,9 +104,7 @@
self = (pLin2Ang)pData;
assert(self);
fX = self->lin->pDrivInt->GetValue(self->lin,pCon);
MotorGetPar(self->lin,"softzero",&zero);
fX -= zero;
MotorGetSoftPosition(self->lin,pCon,&fX);
return x2ang(self,fX);
}
/*------------------------------------------------------------------------*/
@ -271,6 +274,35 @@
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 */
if(strstr(argv[1],"lim") != NULL)
{

View File

@ -13,6 +13,7 @@ lin2ang's datastructure is quite simple:
pIDrivable pDriv;
pMotor lin;
float length;
float zero;
}Lin2Ang;
\end{verbatim}
The fields are:
@ -22,6 +23,7 @@ The fields are:
functionality of this object.
\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[zero] The angular zero point of this virtual motor.
\end{description}
The interface to this is quite simple, most of the functionality is

View File

@ -9,4 +9,4 @@
MFLAGS=-f makefile_linux$(DUMMY)
HDFROOT=/afs/psi.ch/project/sinq/linux
HDFROOT=/usr/local

13
macro.c
View File

@ -707,6 +707,15 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
eOut = eWarning;
break;
case 7:
eOut = eFinish;
break;
case 8:
eOut = eEvent;
break;
case 9:
eOut = eWarning;
break;
case 10:
eOut = eError;
break;
default:
@ -868,7 +877,9 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
length += 10;
pPtr = (char *)malloc(length*sizeof(char));
if(pPtr == NULL){
SCWrite(pCon,"ERROR: out of memory in TclAction",eError);
SCWrite(pCon,
"ERROR: out of memory in TclAction",
eError);
return 0;
}
memset(pPtr,0,length*sizeof(char));

View File

@ -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 \
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) mcreader.o mccontrol.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
COUNTEROBJ = countdriv.o simcter.o counter.o

View File

@ -7,14 +7,15 @@
#==========================================================================
# assign if the National Instrument GPIB driver is available
SINQDIR=/afs/psi.ch/project/sinq
NI= -DHAVENI
NIOBJ= nigpib.o
NILIB=$(SINQDIR)/linux/lib/cib.o
NI=
#NI= -DHAVENI
#NIOBJ= nigpib.o
#NILIB=$(SINQDIR)/linux/lib/cib.o
include linux_def
CC = gcc
CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 $(NI) \
CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 -DNXXML $(NI) \
-Ipsi/hardsup -I. \
-fwritable-strings -DCYGNUS -DNONINTF -g $(DFORTIFY)
@ -22,10 +23,10 @@ BINTARGET = bin
EXTRA=nintf.o
SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \
psi/tecs/libtecsl.a
LIBS = -static -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\
-ltcl8.3 $(HDFROOT)/lib/libhdf5.a \
LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\
-ltcl8.4 -lmxml $(HDFROOT)/lib/libhdf5.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

View File

@ -1,3 +1,3 @@
106
119
NEVER, EVER modify or delete this file
You'll risk eternal damnation and a reincarnation as a cockroach!|n

View File

@ -38,7 +38,8 @@ proc mcstasdump {pid} {
error "Trying to dump invalid PID: $pid"
}
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
}
#-----------------------------------------------------------------------
@ -49,7 +50,9 @@ proc mcstasdump {pid} {
# the Unix FAQ this is the best solution......
#----------------------------------------------------------------------
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]
close $f
return $pstxt
@ -57,12 +60,14 @@ proc readPID {pid} {
#----------------------------------------------------------------------
proc mcstasisrunning {pid} {
global runningCount runningLast
# clientput "Checking McStas PID $pid"
if { $pid <= 0} {
return 0
}
set pstxt " "
set ret [catch {set pstxt [readPID $pid]} msg]
# clientput "pstext = $pstxt"
set pslist [split $pstxt "\n"]
if { [llength $pslist] < 2} {
return 0
@ -84,13 +89,17 @@ proc mcstaskill {pid} {
error "Trying to kill invalid PID $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}
wait 10
}
#-----------------------------------------------------------------------
proc mcinstall {} {
allowexec /usr/bin/kill
allowexec /bin/kill
allowexec /bin/ps
Publish mcstasdump User
Publish mcstasisrunning User

View File

@ -1,4 +1,4 @@
# --------------------------------------------------------------------------
# --------------------------------------------------------------------------
# Initialization script for a virtual DMC instrument using a McStas
# simulationas a data source
#
@ -6,12 +6,12 @@
#---------------------------------------------------------------------------
# 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
#ServerOption RedirectFile $home/stdcdmc
ServerOption ReadTimeOut 1
ServerOption AcceptTimeOut 1
ServerOption ReadTimeOut 10
ServerOption AcceptTimeOut 10
ServerOption ReadUserPasswdTimeout 500000
ServerOption LogFileBaseName "$home/vdmclog"
ServerOption LogFileDir $home/
@ -137,3 +137,13 @@ source $home/vdmccom.tcl
#-------------------- configure commandlog
commandlog auto
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

View File

@ -6,7 +6,7 @@
source $home/mcsupport.tcl
if { [info exists vdmcinit] == 0 } {
set vdmcinit 1
set vdmcinit 1f
Publish LogBook Spy
Publish count User
Publish Repeat User
@ -187,10 +187,9 @@ proc copydmcdata { } {
mcreader insertmon \
"/$mcversion/DMC_diff/dmc.xml/PSD_sample/values" \
counter 1 [expr 1./350]
mcreader insertmon \
"/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values" \
counter 4
set hmScale [SplitReply [counter getmonitor 4]]
# mcreader insertmon \
# "/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values" \
# counter 4
set val [mcreader getfield\
"/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values"]
set l [split $val]
@ -212,7 +211,6 @@ proc dmcdump {pid} {
#--do nothing: progress is doing it for us
}
#--------------------------------------------------------------------------
#mccontrol configure mcstart rundmcsim
mccontrol configure mcstart rundmcoptsim
mccontrol configure mccopydata copydmcdata
mccontrol configure update 30

View File

@ -201,13 +201,13 @@ a9 precision 0.010000
a9 ignorefault 0.000000
a9 AccessCode 2.000000
a9 movecount 10.000000
title UNKNOWN
title D3C
title setAccess 2
user UNKNOWN
user setAccess 2
collimation UNKNOWN
collimation setAccess 2
sampleintern na2ca3al2f14
sampleintern D3C
sampleintern setAccess 2
comment1 UNKNOWN
comment1 setAccess 2
@ -215,7 +215,7 @@ comment2 UNKNOWN
comment2 setAccess 2
comment3 UNKNOWN
comment3 setAccess 2
starttime 2005-10-19 11:11:44
starttime 2005-12-20 05:13:05
starttime setAccess 2
adress UNKNOWN
adress setAccess 2

61
motor.c
View File

@ -52,6 +52,7 @@
#include "splitter.h"
#include "status.h"
#include "servlog.h"
#include "tclmotdriv.h"
#include "site.h"
/*-------------------------------------------------------------------------
some lokal defines
@ -385,6 +386,12 @@ static void handleMoveCallback(pMotor self, SConnection *pCon)
self = (pMotor)sulf;
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)
{
handleMoveCallback(self,pCon);
@ -741,7 +748,7 @@ extern void KillPiPiezo(void *pData);
iRet = MotorCheckBoundary(self,fNew,&fHard,pBueffel,511);
if(!iRet)
{
SCWrite(pCon,pBueffel,eWarning);
SCWrite(pCon,pBueffel,eStatus);
SCSetInterrupt(pCon,eAbortOperation);
return 0;
}
@ -1000,6 +1007,21 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
SCWrite(pCon,pBueffel,eError);
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
{
@ -1034,8 +1056,8 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
int i, iLen;
iLen = ObParLength(self->ParArray);
sprintf(pBueffel,"Parameter Listing for motor %s\n",self->name);
SCWrite(pCon,pBueffel,eStatus);
sprintf(pBueffel,"Parameter Listing for motor %s",self->name);
SCWrite(pCon,pBueffel,eValue);
snprintf(pBueffel,511,"%s.hardupperlim = %f",self->name,
self->pDriver->fUpper);
SCWrite(pCon,pBueffel,eValue);
@ -1073,6 +1095,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
typedef struct {
char *pName;
SConnection *pCon;
float lastValue;
} MotInfo, *pMotInfo;
/*-----------------------------------------------------------------------*/
static void KillInfo(void *pData)
@ -1088,7 +1111,8 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
free(self);
}
/*------------------- 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;
char pBueffel[80];
@ -1099,9 +1123,13 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
psCall = (MotCallback *)pEvent;
pInfo = (MotInfo *)pUser;
sprintf(pBueffel,"%s.position = %f ", pInfo->pName, psCall->fVal);
SCWrite(pInfo->pCon,pBueffel,eValue);
if (pInfo->lastValue != psCall->fVal) {
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;
}
/*------------------------------------------------------------------------*/
@ -1113,7 +1141,8 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
}
}
/*------------------------ 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;
MotCallback *psCall;
@ -1178,7 +1207,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
if(!iRet)
{
sprintf(pBueffel,"Error obtaining position for %s",argv[0]);
SCWrite(pCon,pBueffel,eValue);
SCWrite(pCon,pBueffel,eError);
DeleteTokenList(pList);
return 0;
}
@ -1220,7 +1249,17 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
}
pMoti->pName = strdup(argv[0]);
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);
SCRegister(pCon,pSics, self->pCall,lID);
DeleteTokenList(pList);
@ -1252,7 +1291,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
return 0;
}
self->endScriptID =
RegisterCallback(self->pCall, MOTEND, EndScriptCallback,
RegisterCallback(self->pCall, SCGetContext(pCon),MOTEND, EndScriptCallback,
strdup(pCurrent->text), KillScript);
SCRegister(pCon,pSics, self->pCall,self->endScriptID);
DeleteTokenList(pList);

View File

@ -6,11 +6,9 @@
Mark Koennecke, October 1996
Revised for use with tasker: Mark Koennecke, September 1997
Added code to redirect stdout/sterr to file, Mark Koennecke, May 2000
Define handler in InitServer to ignore SIGPIPE. Paul Hathaway, May 2004
Added code to redirect stdout/sterr to file.
Mark Koennecke, May 2000
Copyright: see copyright.h
----------------------------------------------------------------------------*/
#define NEEDDINTINIT
@ -19,6 +17,7 @@
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include "sics.h"
@ -93,6 +92,8 @@
memset(self,0,sizeof(SicsServer));
*pServ = self;
/* define any signal handlers */
signal(SIGPIPE,SIG_IGN);
/* configure fortify */
iFortifyScope = Fortify_EnterScope();
@ -458,7 +459,7 @@
/*--------------------------------------------------------------------------
UserWait: the user command for waiting, expects one arg:
time to wait in seconds
*/
---------------------------------------------------------------------------*/
int UserWait(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
@ -517,7 +518,7 @@
}
}
/*------------------------------------------------------------------------*/
int SicsWait(long lTime)
int SicsWaitOld(long lTime)
{
WaitStruct sWait;
pTaskMan pTasker = NULL;
@ -537,7 +538,28 @@
TaskWait(pTasker,lID);
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)
{

View File

@ -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;
SConnection *pCon = NULL;
@ -257,6 +258,7 @@ int UpdateFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
char pBueffel[256];
pNXupdate self = NULL;
CommandList *pCom = NULL;
commandContext comCon;
if(argc < 3){
SCWrite(pCon,"ERROR: insuffcient number of argument to UpdateFactory",
@ -309,9 +311,11 @@ int UpdateFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
/*
register callbacks
*/
RegisterCallback(pCall,COUNTSTART,CountCallback,
comCon.transID = 0;
strncpy(comCon.deviceID,"internal",SCDEVIDLEN);
RegisterCallback(pCall,comCon,COUNTSTART,CountCallback,
self,NULL);
RegisterCallback(pCall,COUNTEND,CountCallback,
RegisterCallback(pCall,comCon,COUNTEND,CountCallback,
self,NULL);
AddCommand(pSics,argv[1],UpdateAction,KillUpdate,self);

88
obdes.c
View File

@ -66,6 +66,9 @@
return NULL;
}
pRes->name = strdup(name);
pRes->pKeys = NULL;
pRes->description = NULL;
pRes->group = NULL;
pRes->SaveStatus = DefaultSave;
pRes->GetInterface = DefaultGetInterface;
return pRes;
@ -74,10 +77,10 @@
void DeleteDescriptor(pObjectDescriptor self)
{
assert(self);
if(self->name)
free(self->name);
if(self->name) free(self->name);
if(self->description) free(self->description);
if(self->group) free(self->group);
if(self->pKeys) IFDeleteOptions(self->pKeys);
free(self);
}
@ -134,11 +137,72 @@
return 0;
}
/*------------------------------------------------------------------------*/
pObjectDescriptor FindDescriptor(void *pData)
{
pDummy pDum = NULL;
assert(pData);
pDum = (pDummy)pData;
return pDum->pDescriptor;
}
pObjectDescriptor FindDescriptor(void *pData)
{
pDummy pDum = NULL;
assert(pData);
pDum = (pDummy)pData;
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;
}

52
obdes.h
View File

@ -1,32 +1,36 @@
#line 361 "interface.w"
#line 367 "interface.w"
#line 29 "interface.w"
/*--------------------------------------------------------------------------
In SICS there is the to find out what an
object is capable of at runtime. If this has been done a general
way to access those capabilities is needed. In order to do all
this each SICS-object is required to carry an object descriptor
struct as first parameter in its class/object struct. Additionslly
it is required to initialize this struct to something sensible.
This file defines this struct. Additionally a few functions of
general use are prototyped.
Mark Koennecke, June, 1997
copyrigth: see implementation file
In SICS there is the to find out what an
object is capable of at runtime. If this has been done a general
way to access those capabilities is needed. In order to do all
this each SICS-object is required to carry an object descriptor
struct as first parameter in its class/object struct. Additionslly
it is required to initialize this struct to something sensible.
This file defines this struct. Additionally a few functions of
general use are prototyped.
Mark Koennecke, June, 1997
copyrigth: see implementation file
----------------------------------------------------------------------------*/
#ifndef SICSDESCRIPTOR
#define SICSDESCRIPTOR
#include <stdio.h>
#include <ifile.h>
typedef struct {
char *name;
int (*SaveStatus)(void *self, char *name,FILE *fd);
void *(*GetInterface)(void *self, int iInterfaceID);
char *description;
char *group;
IPair *pKeys;
} ObjectDescriptor, *pObjectDescriptor;
/*---------------------------------------------------------------------------*/
@ -35,9 +39,9 @@
pObjectDescriptor FindDescriptor(void *pData);
/*============================================================================
Objects which do not carry data need a dummy descriptor. Otherwise
drive or scan will protection fault when trying to drive something
which should not be driven. This is defined below.
Objects which do not carry data need a dummy descriptor. Otherwise
drive or scan will protection fault when trying to drive something
which should not be driven. This is defined below.
*/
typedef struct {
@ -46,11 +50,21 @@ typedef struct {
pDummy CreateDummy(char *name);
void KillDummy(void *pData);
void KillDummy(void *pData);
int iHasType(void *pData, char *Type);
#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
View File

@ -114,6 +114,8 @@
#include "tasscanub.h"
#include "mcreader.h"
#include "mccontrol.h"
#include "protocol.h"
#include "sinfox.h"
/*----------------------- Server options creation -------------------------*/
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
@ -237,6 +239,7 @@
AddCommand(pInter,"sicsdatafactory",SICSDataFactory,NULL,NULL);
AddCommand(pInter,"scriptcallback",CallbackScript,NULL,NULL);
AddCommand(pInter,"help",SicsHelp,KillHelp,NULL);
AddCommand(pInter,"sicsatt",SicsAtt,NULL,NULL);
/* commands to do with the executor. Only StopExe carries the
DeleteFunction in order to avoid double deletion. All the
@ -311,6 +314,10 @@
McStasReaderFactory,NULL,NULL);
AddCommand(pInter,"MakeMcStasController",
McStasControllerFactory,NULL,NULL);
AddCommand(pInter,"InstallProtocolHandler",
InstallProtocol,NULL,NULL);
AddCommand(pInter,"InstallSinfox",
InstallSinfox,NULL,NULL);
/*
install site specific commands
@ -376,7 +383,8 @@
RemoveCommand(pSics,"MakeTasUB");
RemoveCommand(pSics,"MakeTasScan");
RemoveCommand(pSics,"MakemcStasReader");
RemoveCommand(pSics,"InstallProtocolHandler");
RemoveCommand(pSics,"InstallSinfox");
/*
remove site specific installation commands
*/

View File

@ -15,8 +15,11 @@
"inerror",
"status",
"value",
"start",
"finish",
"event",
"warning",
"error",
NULL };
static int iNoCodes = 7;
static int iNoCodes = 10;
#endif

View File

@ -147,7 +147,8 @@
return self->fCPS;
}
/*------------------- 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;
SConnection *pCon;
@ -160,7 +161,7 @@
pCon = (SConnection *)pUser;
sprintf(pBueffel,"Performance = %f", *fPos);
SCWrite(pCon,pBueffel,eValue);
SCWriteInContext(pCon,pBueffel,eValue,cc);
return 1;
}
/*----------------------------------------------------------------------------
@ -206,7 +207,8 @@
if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, VALUECHANGE, InterestCallback,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
VALUECHANGE, InterestCallback,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);

616
protocol.c Normal file
View 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
View 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

View File

@ -250,6 +250,32 @@ int readRS232TillTerm(prs232 self, void *data, int *datalen){
}
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)
{
@ -736,6 +762,31 @@ int RS232Action(SConnection *pCon, SicsInterp *pSics,
SCWrite(pCon,pBuffer,eValue);
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)
{
iRet = availableRS232(self);

View File

@ -56,6 +56,8 @@
int writeRS232(prs232 self, void *data, int dataLen);
int readRS232(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 availableNetRS232(prs232 self);
int transactRS232(prs232 self, void *send, int sendLen,

43
scan.c
View File

@ -1236,7 +1236,8 @@ int isScanVarSoft(pScanData self){
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;
SConnection *pCon = NULL;
@ -1253,12 +1254,12 @@ int isScanVarSoft(pScanData self){
if(iEvent == SCANSTART)
{
SCWrite(pCon,"NewScan",eWarning);
SCWriteInContext(pCon,"NewScan",eWarning,cc);
return 1;
}
else if(iEvent == SCANEND)
{
SCWrite(pCon,"ScanEnd",eWarning);
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
return 1;
}
else if(iEvent == SCANPOINT)
@ -1299,7 +1300,8 @@ int isScanVarSoft(pScanData self){
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;
SConnection *pCon = NULL;
@ -1319,12 +1321,12 @@ int isScanVarSoft(pScanData self){
if(iEvent == SCANSTART)
{
SCWrite(pCon,"NewScan",eWarning);
SCWriteInContext(pCon,"NewScan",eWarning,cc);
return 1;
}
else if(iEvent == SCANEND)
{
SCWrite(pCon,"ScanEnd",eWarning);
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
return 1;
}
else if(iEvent == SCANPOINT)
@ -1346,12 +1348,13 @@ int isScanVarSoft(pScanData self){
}
snprintf(pBueffel,255,"%s.scanpoint = {%d %f %ld}",
self->objectName,i,fVal,lVal);
SCWrite(pCon,pBueffel,eValue);
SCWriteInContext(pCon,pBueffel,eValue,cc);
}
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;
SConnection *pCon = NULL;
@ -1368,12 +1371,12 @@ int isScanVarSoft(pScanData self){
if(iEvent == SCANSTART)
{
SCWrite(pCon,"NewScan",eWarning);
SCWriteInContext(pCon,"NewScan",eWarning,cc);
return 1;
}
else if(iEvent == SCANEND)
{
SCWrite(pCon,"ScanEnd",eWarning);
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
return 1;
}
else if(iEvent == SCANPOINT)
@ -1395,7 +1398,9 @@ int isScanVarSoft(pScanData self){
{
iData[i] = htonl((int)lData[i]);
}
SCPushContext2(pCon,cc);
SCWriteUUencoded(pCon,"ScanData",iData,self->iNP*sizeof(int));
SCPopContext(pCon);
free(lData);
free(iData);
return 1;
@ -1896,13 +1901,13 @@ static int DumpScan(pScanData self, SConnection *pCon)
/*-------- interest */
else if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, SCANSTART, ScanInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANEND, ScanInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANEND, ScanInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANPOINT, ScanInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);
@ -1911,13 +1916,13 @@ static int DumpScan(pScanData self, SConnection *pCon)
/*-------- interest */
else if(strcmp(argv[1],"dyninterest") == 0)
{
lID = RegisterCallback(self->pCall, SCANSTART, ScanDynInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanDynInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANEND, ScanDynInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon), SCANEND, ScanDynInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANPOINT, ScanDynInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanDynInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);
@ -1926,13 +1931,13 @@ static int DumpScan(pScanData self, SConnection *pCon)
/*-------- uuinterest */
else if(strcmp(argv[1],"uuinterest") == 0)
{
lID = RegisterCallback(self->pCall, SCANSTART, ScanUUInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanUUInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANEND, ScanUUInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANEND, ScanUUInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANPOINT, ScanUUInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanUUInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);

View File

@ -474,7 +474,8 @@
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;
pSelVar self = NULL;
@ -488,7 +489,7 @@
fVal = GetSelValue(self,pCon);
sprintf(pBueffel,"%s.value = %f", self->name, fVal);
SCWrite(pCon,pBueffel,eValue);
SCWriteInContext(pCon,pBueffel,eValue,cc);
return 1;
}
/*--------------------------------------------------------------------------
@ -520,7 +521,8 @@
strtolower(argv[1]);
if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, WLCHANGE, WaveLengthCallBack,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
WLCHANGE, WaveLengthCallBack,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);
@ -589,8 +591,9 @@
strtolower(argv[1]);
if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, WLCHANGE, WaveLengthCallBack,
pCon, NULL);
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
WLCHANGE, WaveLengthCallBack,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);
return 1;

110
servlog.c
View File

@ -39,6 +39,13 @@
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
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 <stdio.h>
@ -223,7 +230,38 @@
static FILE *fLogFile = NULL;
static int iFile = 0;
static int iLineCount = 0;
static int iLogUsable = 1;
/*---------------------------------------------------------------------------*/
int OpenVerifyLogFile()
{
char pFile[256];
char *pChar = NULL;
pChar = IFindOption(pSICSOptions,"LogFileBaseName");
if(!pChar)
{ /* Try to write to file "server" in*/
strcpy(pFile,"server");
}
else
{
strcpy(pFile,pChar);
}
sprintf(pFile,"%s%2.2d.log",pFile, iFile);
fLogFile = fopen(pFile,"w");
if(!fLogFile)
{
fprintf(stderr,"ERROR: Cannot open logfile %s for writing\n",pFile);
fLogFile = NULL;
return 0;
}
else
{
return 1;
}
}
/*---------------------------------------------------------------------------*/
void SICSLogWrite(char *pText, OutCode eOut)
{
char pFile[256];
@ -234,67 +272,47 @@
#ifdef NOLOG
return ;
#endif
if(fLogFile == NULL) /* first time of */
/* 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(" %s \n",pText);
printf("WARNING: Cannot log(%s)\n",pText);
return;
}
/* get the filename */
pChar = IFindOption(pSICSOptions,"LogFileBaseName");
if(!pChar)
{
strcpy(pFile,"server");
}
else
{
strcpy(pFile,pChar);
}
sprintf(pFile,"%s%2.2d.log",pFile, iFile);
fLogFile = fopen(pFile,"w");
if(!fLogFile)
{
printf("ERROR: cannot open logfile %s for writing\n",
pFile);
fLogFile = NULL;
return;
}
}
iLogUsable = OpenVerifyLogFile();
}
/* switch file if to many lines */
if(iLineCount == MAXLOG)
/* switch file if too many lines */
if(iLineCount >= MAXLOG)
{
fclose(fLogFile);
fLogFile = NULL;
iFile++;
iLineCount = 0;
if(iFile >= MAXFILES)
{
iFile = 0;
}
pChar = IFindOption(pSICSOptions,"LogFileBaseName");
if(!pChar)
{
strcpy(pFile,"server");
iLogUsable = OpenVerifyLogFile();
}
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);
fflush(fLogFile);
iLineCount++;
@ -309,5 +327,5 @@
}
pCurrent = pCurrent->pNext;
}
}
}

View File

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

View File

@ -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;
char pBueffel[512];
pSicsVariable pVar = NULL;
int iVal;
int iVal, status;
float fVal;
char *pText;
@ -388,18 +389,21 @@
pVar = (pSicsVariable)pEvent;
pCon = (SConnection *)pUser;
SCPushContext2(pCon,cc);
switch(pVar->eType)
{
case veInt:
VarGetInt(pVar,&iVal);
sprintf(pBueffel,"%s = %d",pVar->name,iVal);
SCWrite(pCon,pBueffel,eValue);
return 1;
status = 1;
break;
case veFloat:
VarGetFloat(pVar,&fVal);
sprintf(pBueffel,"%s = %f",pVar->name,fVal);
SCWrite(pCon,pBueffel,eValue);
return 1;
status = 1;
break;
case veText:
VarGetText(pVar,&pText);
sprintf(pBueffel,"%s = %s", pVar->name,pText);
@ -408,9 +412,11 @@
{
free(pText);
}
return 1;
status = 1;
break;
}
return 1;
SCPopContext(pCon);
return status;
}
/*----------------------------------------------------------------------*/
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 */
{
lID = RegisterCallback(pVar->pCall, VALUECHANGE, VarInterestCallback,
lID = RegisterCallback(pVar->pCall, SCGetContext(pCon),
VALUECHANGE, VarInterestCallback,
pCon, NULL);
SCRegister(pCon,pInterp, pVar->pCall,lID);
DeleteTokenList(pList);

387
sinfo.tcl Normal file
View 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"
}
}

1221
sinfox.c Normal file

File diff suppressed because it is too large Load Diff

115
sinfox.h Normal file
View 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 */

View File

@ -181,7 +181,8 @@
return 1;
}
/*------------------- 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;
char pBueffel[80];
@ -191,7 +192,9 @@
pCon = (SConnection *)pUser;
sprintf(pBueffel,"status = %s", pText[(int)eCode]);
SCPushContext2(pCon,cc);
SCWrite(pCon,pBueffel,eWarning);
SCPopContext(pCon);
return 1;
}
@ -217,7 +220,8 @@
strtolower(argv[1]);
if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(pCall, VALUECHANGE, StatusCallback,
lID = RegisterCallback(pCall, SCGetContext(pCon),
VALUECHANGE, StatusCallback,
pCon, NULL);
SCRegister(pCon,pSics, pCall,lID);
SCSendOK(pCon);

18
stptok.h Normal file
View 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
View 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
View 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
View File

@ -293,7 +293,7 @@ ente:
assert(self);
assert(self->iID == TASKERID);
/* Cycle until back at our selves killed. */
/* Cycle until back at ourselves */
pEnd = self->pCurrent;
pEnd->iStatus = WAITING;
IncrTaskPointer(self);

2
task.h
View File

@ -106,7 +106,7 @@
int TaskYield(pTaskMan self);
/*
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);

395
tclmotdriv.c Normal file
View 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
View 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

207
velo.c
View File

@ -1,4 +1,4 @@
/*---------------------------------------------------------------------------
/*---------------------------------------------------------------------------
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
@ -116,6 +116,37 @@
/* Success ! */
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)
{
@ -701,7 +732,7 @@
return 1;
}
/*-------------------------------------------------------------------------*/
static pEVDriver MakeDummyVel(pVelSel pVel)
pEVDriver MakeDummyVel(pVelSel pVel)
{
pEVDriver pNew = NULL;
pVelPrivate ich = NULL;
@ -869,51 +900,6 @@
EVRegisterController(FindEMON(pSics),pBueffel,pNew->pMonitor,pCon);
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 {
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;
float *fVal = NULL;
@ -949,12 +936,12 @@
if(iEvent == ROTSTART)
{
sprintf(pBueffel,"%s Starting",pDat->pName);
SCWrite(pDat->pCon,pBueffel,eWarning);
SCWriteInContext(pDat->pCon,pBueffel,eWarning,cc);
}
else if(iEvent == ROTMOVE)
{
sprintf(pBueffel,"%s.rpm = %f",pDat->pName, *fVal);
SCWrite(pDat->pCon,pBueffel,eWarning);
SCWriteInContext(pDat->pCon,pBueffel,eWarning,cc);
}
return 1;
}
@ -980,10 +967,6 @@
assert(pCon);
assert(pSics);
/* convert to text for parsing */
Arg2Text(argc,argv,pCommand, 511);
strtolower(pCommand);
if(argc < 2)
{
sprintf(pBueffel,"ERROR: %s expects at least one parameter",argv[0]);
@ -1026,10 +1009,10 @@
}
pCB->pCon = pCon;
pCB->pName = strdup(argv[0]);
lID = RegisterCallback(self->pCall, ROTSTART, RotationInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon), ROTSTART, RotationInterest,
pCB, KillCB);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, ROTMOVE, RotationInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon), ROTMOVE, RotationInterest,
pCB, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);
@ -1081,6 +1064,13 @@
SCSendOK(pCon);
return 1;
}
/* list forbidden regions */
if(strcmp(argv[1],"forbidden") == 0)
{
VSListForbidden(self,pCon);
return 1;
}
/* status, prints a status message */
if(strcmp(argv[1],"status") == 0)
@ -1132,6 +1122,30 @@
return 0;
}
}
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 */
iRet = VSGetRotation(self,&fRot);
@ -1143,61 +1157,50 @@
iRet = MotorGetSoftPosition(self->pTilt,pCon,&fTilt);
if(!iRet)
{
SCWrite(pCon,"ERROR: velocity selector operation aborted",eError);
SCWrite(pCon,"ERROR: failed to read tilt angle",eError);
return 0;
}
/* search for Tilt */
pPtr = strstr(pCommand,"tilt");
if(pPtr) /* analyse tilt */
{
iDrive = 1;
iRet = TTFindNumber(pSics->pTcl,pPtr+strlen("tilt"),&fTilt);
if(!iRet)
{
/* no new value, just print the current one */
MotorGetSoftPosition(self->pTilt,pCon,&fTilt);
sprintf(pBueffel,"%s tilt = %f",argv[0],fTilt);
SCWrite(pCon,pBueffel,eError);
return 0;
}
if(strcmp(argv[1],"tilt") == 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;
}
fTilt = dVal;
iDrive = 1;
} else {
sprintf(pBueffel,"%s tilt = %f",argv[0],fTilt);
SCWrite(pCon,pBueffel,eError);
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 */
pPtr = strstr(pCommand,"rot");
if(pPtr) /* analyse tilt */
{
iDrive = 1;
iRet = TTFindNumber(pSics->pTcl,pPtr+strlen("rot"),&fVal);
if(!iRet)
{
sprintf(pBueffel,"%s rot = %f",argv[0],fRot);
SCWrite(pCon,pBueffel,eError);
return 0;
}
fRot = fVal;
if(strcmp(argv[1],"rot") == 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;
}
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 */

1
velo.h
View File

@ -46,7 +46,6 @@
#line 264 "velo.w"
#line 164 "velo.w"
int VSGetLossCurrent(pVelSel self, SConnection *pCon, float *fLoss);

View File

@ -11,7 +11,7 @@ lappend auto_path /data/koenneck/bin/tcl
set INI(DefUser) Spy
set INI(DefPasswd) 007
set INI(ServerPort) 3006
set INI(ServerPort) 2911
set INI(InterruptPort) 2913
set INI(box) localhost
set INI(usPasswd) Rosy