improvements:
- added is_running to driveable ease objects - ighdriv.c: try <maxtry> times when status reply failes - ipsdriv.c: fix trainedTo parameter - reduced SEA version of SICS
This commit is contained in:
6
arrobj.c
6
arrobj.c
@ -164,6 +164,7 @@ static int ArrayMakeItem(void *object, void *delete, int argc,
|
||||
*last = item->next; /* remove item from list */
|
||||
item->next = arr->freeItems;
|
||||
arr->freeItems = item;
|
||||
ParKillPar(arr, item->name);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@ -230,7 +231,7 @@ static int ArrayMakeItem(void *object, void *delete, int argc,
|
||||
item->unit = strdup(item->unit);
|
||||
if (item->value)
|
||||
item->value = strdup(item->value);
|
||||
ParInitPar(object, item->name);
|
||||
ParInitPar(object, item->name, arr->logged);
|
||||
SCparChange(arr->p.conn);
|
||||
|
||||
return 1;
|
||||
@ -318,6 +319,7 @@ static void ArrayObjParDef(void *object)
|
||||
if (ParActionIs(PAR_KILL)) {
|
||||
for (item = arr->items; item != NULL; item = next) {
|
||||
next = item->next;
|
||||
ParKillPar(arr, item->name);
|
||||
if (item->name)
|
||||
free(item->name);
|
||||
if (item->unit)
|
||||
@ -350,7 +352,7 @@ static int ArrayObjInit(SConnection * con, int argc, char *argv[],
|
||||
creationCmd = Arg2Tcl(argc, argv, NULL, 0);
|
||||
}
|
||||
arr = ParMake(con, argv[1], &arrayObjClass, ArrayObjParDef, creationCmd);
|
||||
if (argc > 2 && strcasecmp(argv[2], "logged") == 0) {
|
||||
if (argc > 3 && strcasecmp(argv[3], "logged") == 0) {
|
||||
arr->logged = 1;
|
||||
} else {
|
||||
arr->logged = 0;
|
||||
|
46
ease.c
46
ease.c
@ -19,6 +19,7 @@ Markus Zolliker, March 2005
|
||||
#include "sics.h"
|
||||
#include "splitter.h"
|
||||
#include "ease.h"
|
||||
#include "sicshipadaba.h"
|
||||
|
||||
#define EASE_FLAGBITS (8*sizeof(long))
|
||||
|
||||
@ -242,16 +243,29 @@ static int EaseRestart(EaseBase * eab)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void EaseUpdateHwstate(void *object, int drivStatus) {
|
||||
EaseDriv *ead = EaseDrivCast(object);
|
||||
int is_running = drivStatus == HWBusy;
|
||||
|
||||
ead->hwstate = drivStatus;
|
||||
|
||||
if (ead->is_running != is_running) {
|
||||
ead->is_running = is_running;
|
||||
ParUpdateAll(ead);
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int EaseHandler(EaseBase * eab)
|
||||
{
|
||||
EaseDriv *ead = EaseDrivCast(eab);;
|
||||
EaseDriv *ead = EaseDrivCast(eab);
|
||||
int iret;
|
||||
|
||||
EaseSavePars();
|
||||
if (ead && ead->stopped && ead->hwstate == HWBusy) {
|
||||
ead->stopped = 0;
|
||||
ead->hwstate = HWIdle;
|
||||
EaseUpdateHwstate(ead, HWIdle);
|
||||
if (FsmStop(eab->task, eab->doit)) {
|
||||
ParPrintf(eab, eWarning, "%s stopped", eab->p.name);
|
||||
return 0;
|
||||
@ -314,7 +328,7 @@ int EaseHandler(EaseBase * eab)
|
||||
}
|
||||
eab->errCode = 0;
|
||||
if (ead) {
|
||||
ead->hwstate = HWFault;
|
||||
EaseUpdateHwstate(ead, HWFault);
|
||||
FsmStop(eab->task, eab->doit);
|
||||
}
|
||||
return 0;
|
||||
@ -563,7 +577,8 @@ static long EaseRun(void *obj, SConnection * pCon, float fVal)
|
||||
ead->stopped = 0;
|
||||
/* eab->todo = eab->doit; */
|
||||
EaseSetUpdate(eab, EASE_RUN, 1);
|
||||
ead->hwstate = HWBusy;
|
||||
ead->is_running = -1; /* force update of is_running even when not changed */
|
||||
EaseUpdateHwstate(ead, HWBusy);
|
||||
if (ead->maxwait >= 0) {
|
||||
ead->timeout = time(NULL) + ead->maxwait;
|
||||
} else {
|
||||
@ -633,12 +648,15 @@ static int EaseCheckStatus(void *obj, SConnection * pCon)
|
||||
ParSaveConn(ead, pCon);
|
||||
if (ead->stopped) {
|
||||
return HWIdle;
|
||||
} else if (!ead->is_running) {
|
||||
ead->stopped = 1;
|
||||
return HWIdle;
|
||||
}
|
||||
now = time(NULL);
|
||||
if (now > ead->timeout) {
|
||||
ParPrintf(obj, eWarning, "maxwait expired when driving %s",
|
||||
ead->b.p.name);
|
||||
ead->hwstate = HWIdle;
|
||||
EaseUpdateHwstate(ead, HWIdle);
|
||||
} else if (EaseIsInTol(obj)) {
|
||||
if (ead->finish == 0) {
|
||||
ead->finish = now - ead->usedSettle;
|
||||
@ -649,7 +667,7 @@ static int EaseCheckStatus(void *obj, SConnection * pCon)
|
||||
}
|
||||
if (now > ead->finish + ead->settle && ead->hwstate != HWIdle) {
|
||||
ParPrintf(obj, eWarning, "%s has reached target", ead->b.p.name);
|
||||
ead->hwstate = HWIdle;
|
||||
EaseUpdateHwstate(ead, HWIdle);
|
||||
}
|
||||
} else if (ead->finish != 0) {
|
||||
ead->usedSettle = now - ead->finish;
|
||||
@ -930,7 +948,6 @@ void *EaseMakeDriv(SConnection * con, void *class, int argc, char *argv[],
|
||||
ead->evInt->IsInTolerance = EaseIsInTol;
|
||||
ead->evInt->HandleError = EaseErrHandler;
|
||||
|
||||
ead->hwstate = HWIdle;
|
||||
ead->drivInt->Halt = EaseHalt;
|
||||
ead->drivInt->CheckLimits = EaseCheckLimits;
|
||||
ead->drivInt->SetValue = EaseRun;
|
||||
@ -943,7 +960,9 @@ void *EaseMakeDriv(SConnection * con, void *class, int argc, char *argv[],
|
||||
ead->settle = 0;
|
||||
ead->tolerance = 1;
|
||||
ead->targetValue = 0;
|
||||
ead->is_running = 0;
|
||||
|
||||
EaseUpdateHwstate(ead, HWIdle);
|
||||
/* EMon interface to be implemented */
|
||||
return ead;
|
||||
}
|
||||
@ -1113,6 +1132,17 @@ void EaseKillDriv(EaseDriv * ead)
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void EaseRunPar(void *object)
|
||||
{
|
||||
EaseDriv *ead;
|
||||
|
||||
assert(ead = EaseDrivCast(object));
|
||||
|
||||
ParName("is_running");
|
||||
ParInt(&ead->is_running, 0);
|
||||
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void EaseDrivPar(void *object, char *fmt, char *unit)
|
||||
{
|
||||
@ -1164,6 +1194,8 @@ void EaseDrivPar(void *object, char *fmt, char *unit)
|
||||
ParTail(unit);
|
||||
ParFloat(&ead->targetValue, PAR_NAN);
|
||||
|
||||
EaseRunPar(ead);
|
||||
|
||||
if (ParActionIs(PAR_KILL)) {
|
||||
EaseKillDriv(ead);
|
||||
}
|
||||
|
3
ease.h
3
ease.h
@ -71,6 +71,7 @@ typedef struct {
|
||||
float targetValue;
|
||||
time_t timeout, finish;
|
||||
int usedSettle;
|
||||
int is_running;
|
||||
} EaseDriv;
|
||||
|
||||
ParClass *EaseBaseClass(void);
|
||||
@ -87,6 +88,7 @@ void EaseBasePar(void *object);
|
||||
void EaseSendPar(void *object);
|
||||
void EaseMsgPar(void *object);
|
||||
void EaseKillDriv(EaseDriv * ead);
|
||||
void EaseRunPar(void *object); /* is_running parameter */
|
||||
void EaseDrivPar(void *object, char *fmt, char *unit);
|
||||
void EasePchk(void *drv);
|
||||
void EaseParHasChanged(void);
|
||||
@ -112,6 +114,7 @@ int EaseGetUpdate(void *object, int flag);
|
||||
void EaseSetUpdate(void *object, int flag, int state);
|
||||
/* set an update flag */
|
||||
|
||||
void EaseUpdateHwstate(void *object, int drivStatus);
|
||||
void *EaseMakeBase(SConnection * con, void *class, int argc, char *argv[],
|
||||
int dynamic, int maxflag,
|
||||
ParDef pardef,
|
||||
|
@ -148,7 +148,7 @@ static int Euro2kMakePar(void *object, void *userarg, int argc,
|
||||
par->unit = strdup(par->unit);
|
||||
if (par->fmt)
|
||||
par->fmt = strdup(par->fmt);
|
||||
ParInitPar(object, par->name);
|
||||
ParInitPar(object, par->name, 1);
|
||||
EaseParHasChanged();
|
||||
drv->readPar = NULL;
|
||||
return 1;
|
||||
|
81
ighdriv.c
81
ighdriv.c
@ -89,6 +89,10 @@ typedef struct {
|
||||
int pumpoff; /* pump signal after overpressure switch */
|
||||
float upperN2; /* LN2 trap sensor */
|
||||
float lowerN2;
|
||||
char lastans[64];
|
||||
int badcnt;
|
||||
int maxtry;
|
||||
int pumpoffcnt;
|
||||
} Igh;
|
||||
|
||||
static ParClass ighClass = { "IGH", sizeof(Igh) };
|
||||
@ -308,6 +312,11 @@ static void IghParDef(void *object)
|
||||
if (drv->extVersion != 0) ParTail("K");
|
||||
ParFloat(&drv->lowerN2, PAR_NAN);
|
||||
|
||||
ParName("maxtry");
|
||||
ParAccess(usUser);
|
||||
ParSave(1);
|
||||
ParInt(&drv->maxtry, 0);
|
||||
|
||||
EaseBasePar(drv);
|
||||
EaseSendPar(drv);
|
||||
if (eab->syntax != OLDIGH) {
|
||||
@ -318,7 +327,7 @@ static void IghParDef(void *object)
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void IghStatus(Igh * drv)
|
||||
int IghStatus(Igh * drv)
|
||||
{
|
||||
char *ans;
|
||||
int *code;
|
||||
@ -326,7 +335,7 @@ void IghStatus(Igh * drv)
|
||||
int i;
|
||||
|
||||
if (drv->d.b.state != EASE_read)
|
||||
return;
|
||||
return 1;
|
||||
|
||||
if (drv->opentime > 0 &&
|
||||
DoubleTime() > drv->opentime + (double)drv->closedelay - 1) {
|
||||
@ -334,22 +343,46 @@ void IghStatus(Igh * drv)
|
||||
drv->d.b.todo = drv->d.b.doit;
|
||||
}
|
||||
|
||||
ans = drv->d.b.ans;
|
||||
code = &drv->d.b.errCode;
|
||||
ans = drv->d.b.ans;
|
||||
if (drv->maxtry > 0 && strcmp(ans, drv->lastans) != 0) {
|
||||
strlcpy(drv->lastans, ans, sizeof(drv->lastans));
|
||||
drv->badcnt++;
|
||||
if (drv->badcnt >= drv->maxtry) {
|
||||
drv->badcnt = 0;
|
||||
ParPrintf(drv, eError, "inconsistent status response: %s", ans);
|
||||
*code = EASE_FAULT;
|
||||
return 1;
|
||||
}
|
||||
return 0; /* try again */
|
||||
}
|
||||
strlcpy(drv->lastans, ans, sizeof(drv->lastans));
|
||||
if (ans[0] != 'X' ||
|
||||
ans[2] != 'A' ||
|
||||
ans[4] != 'C' ||
|
||||
ans[6] != 'P' ||
|
||||
ans[15] != 'S' || ans[17] != 'O' || ans[19] != 'E') {
|
||||
ParPrintf(drv, eError, "illegal status response: %s", ans);
|
||||
drv->badcnt++;
|
||||
if (drv->badcnt < drv->maxtry) {
|
||||
return 0; /* try again */
|
||||
}
|
||||
ParPrintf(drv, eError, "illegal status response (dil maxtry 10 might help): %s", ans);
|
||||
*code = EASE_FAULT;
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
if (sscanf(ans + 7, "%lx", &mask) <= 0) {
|
||||
drv->badcnt++;
|
||||
if (drv->badcnt < drv->maxtry) {
|
||||
return 0; /* try again */
|
||||
}
|
||||
ParPrintf(drv, eError, "illegal valve status response");
|
||||
*code = EASE_FAULT;
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
if (drv->badcnt > drv->maxtry / 2) {
|
||||
ParPrintf(drv, eError, "needed %d retries for getting dil status", drv->badcnt);
|
||||
}
|
||||
drv->badcnt = 0;
|
||||
p = 1;
|
||||
for (i = 0; i < n_VALVES; i++) {
|
||||
if (!EaseGetUpdate(drv, VALVE_FLAGS + i)) {
|
||||
@ -376,9 +409,10 @@ void IghStatus(Igh * drv)
|
||||
ParPrintf(drv, eError, "IGH switched to local");
|
||||
*code = EASE_FAULT;
|
||||
drv->remote = 1;
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -401,10 +435,11 @@ static long IghRead(long pc, void *object)
|
||||
switch (pc) {
|
||||
default: /* FSM BEGIN ****************************** */
|
||||
EasePchk(drv);
|
||||
redo1:
|
||||
EaseWrite(eab, "X");
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
IghStatus(drv);
|
||||
if (!IghStatus(drv)) goto redo1;
|
||||
if (!drv->remote)
|
||||
goto skiprmt;
|
||||
EaseWrite(eab, "C0");
|
||||
@ -532,8 +567,14 @@ static long IghRead(long pc, void *object)
|
||||
delta = (now - drv->v6time) / 2.64; /* speed: 1/2.64 %/sec */
|
||||
drv->v6time = now;
|
||||
if (drv->v6pos > drv->mv[V6] + delta) {
|
||||
if (drv->v6pos > 99.9) {
|
||||
drv->v6pos = 99.9;
|
||||
}
|
||||
drv->v6pos -= delta;
|
||||
} else if (drv->v6pos < drv->mv[V6] - delta) {
|
||||
if (drv->v6pos < 0) {
|
||||
drv->v6pos = 0;
|
||||
}
|
||||
drv->v6pos += delta;
|
||||
} else {
|
||||
drv->v6pos = drv->mv[V6];
|
||||
@ -609,6 +650,8 @@ static long IghRead(long pc, void *object)
|
||||
if (EaseCheckDoit(eab) || drv->extVersion == 0)
|
||||
goto quit;
|
||||
|
||||
drv->pumpoffcnt = 0;
|
||||
redo2:
|
||||
EaseWrite(eab, "{r}");
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
@ -625,11 +668,18 @@ static long IghRead(long pc, void *object)
|
||||
drv->lowerN2 = PAR_NAN;
|
||||
}
|
||||
if (!switched_off) goto quit;
|
||||
/* veryfy pump control */
|
||||
if (drv->extVersion == 2) {
|
||||
ParPrintf(eab, eLogError,
|
||||
"ERROR: overpressure after 3He pump (IGNORED!)");
|
||||
goto quit;
|
||||
}
|
||||
/* verify pump control */
|
||||
EaseWrite(eab, "X");
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
IghStatus(drv);
|
||||
if (!IghStatus(drv)) goto redo2;
|
||||
drv->pumpoffcnt++;
|
||||
if (drv->pumpoffcnt < 3) goto redo2;
|
||||
if (drv->v[HE3] == 0) goto quit; /* switched off intentionally */
|
||||
/* overpressure switch activated: we switch pump control off */
|
||||
EaseWrite(eab, "C3");
|
||||
@ -740,10 +790,11 @@ static long IghSet(long pc, void *object)
|
||||
OxiSet(eab, "K", drv->sorbS, 1);
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
redo1:
|
||||
EaseWrite(eab, "X");
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
IghStatus(drv);
|
||||
if (!IghStatus(drv)) goto redo1;
|
||||
if (drv->o == 2 || drv->o == 3)
|
||||
goto loop;
|
||||
if (drv->o % 2) {
|
||||
@ -756,10 +807,11 @@ static long IghSet(long pc, void *object)
|
||||
goto loop;
|
||||
|
||||
set_sorb_pow:
|
||||
redo2:
|
||||
EaseWrite(eab, "X");
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
IghStatus(drv);
|
||||
if (!IghStatus(drv)) goto redo2;
|
||||
if (drv->o <= 1)
|
||||
goto skipSetO;
|
||||
if (drv->o % 2) {
|
||||
@ -790,10 +842,11 @@ static long IghSet(long pc, void *object)
|
||||
OxiSet(eab, "S", drv->stillP, 1);
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
redo3:
|
||||
EaseWrite(eab, "X");
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
IghStatus(drv);
|
||||
if (!IghStatus(drv)) goto redo3;
|
||||
snprintf(buf, sizeof buf, "O%d", drv->o | 1);
|
||||
EaseWrite(eab, buf);
|
||||
return __LINE__;
|
||||
@ -941,6 +994,8 @@ static int IghInit(SConnection * con, int argc, char *argv[], int dynamic)
|
||||
if (drv == NULL)
|
||||
return 0;
|
||||
drv->opentime = 0;
|
||||
drv->badcnt = 0;
|
||||
drv->pumpoffcnt = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
18
ipsdriv.c
18
ipsdriv.c
@ -287,6 +287,7 @@ void IpsParDef(void *object)
|
||||
ParCmd(IpsConfirm, NULL);
|
||||
|
||||
EaseBasePar(drv);
|
||||
EaseRunPar(drv);
|
||||
EaseSendPar(drv);
|
||||
ParStdDef();
|
||||
|
||||
@ -369,7 +370,7 @@ static void IpsStatus(Ips * drv)
|
||||
drv->remote = 3; /* signal to switch back to C0 local locked */
|
||||
}
|
||||
if (drv->d.hwstate == HWBusy && drv->d.b.doit == NULL) {
|
||||
drv->d.hwstate = HWIdle;
|
||||
EaseUpdateHwstate(drv, HWIdle);
|
||||
drv->d.stopped = 0;
|
||||
}
|
||||
}
|
||||
@ -604,7 +605,7 @@ static long IpsStart(long pc, void *object)
|
||||
Tcl_Interp *pTcl = NULL;
|
||||
int iRet;
|
||||
char msg[256];
|
||||
|
||||
char *script;
|
||||
|
||||
switch (pc) {
|
||||
default: /* FSM BEGIN ****************************** */
|
||||
@ -682,7 +683,10 @@ static long IpsStart(long pc, void *object)
|
||||
if (drv->startScript && drv->startScript[0] != '\0'
|
||||
&& 0 != strcmp(drv->startScript, "0")) {
|
||||
pTcl = InterpGetTcl(pServ->pSics);
|
||||
iRet = Tcl_Eval(pTcl, drv->startScript);
|
||||
|
||||
script = strdup(drv->startScript);
|
||||
iRet = Tcl_Eval(pTcl, script);
|
||||
free(script);
|
||||
if (iRet != TCL_OK) {
|
||||
snprintf(msg, sizeof msg, "%s", pTcl->result);
|
||||
EaseStop(eab, msg);
|
||||
@ -725,7 +729,7 @@ static long IpsChangeField(long pc, void *object)
|
||||
}
|
||||
EaseSetUpdate(eab, EASE_RUN, 0);
|
||||
if (drv->nowait) {
|
||||
drv->d.hwstate = HWIdle;
|
||||
EaseUpdateHwstate(drv, HWIdle);
|
||||
drv->d.eMode = EVMonitor; /* finish drive, continue in background */
|
||||
}
|
||||
EaseWrite(eab, "F7"); /* switch to tesla on display */
|
||||
@ -924,7 +928,7 @@ static long IpsChangeField(long pc, void *object)
|
||||
if (drv->trainMode == 0) {
|
||||
drv->trainMode = 3; /* remember that we must go to train mode */
|
||||
}
|
||||
drv->trainedTo = fabs(fld);
|
||||
drv->trainedTo = fabs(drv->current);
|
||||
} else {
|
||||
if (drv->trainMode == 1) {
|
||||
drv->trainMode = 2; /* remember that we must go to fast mode */
|
||||
@ -946,7 +950,7 @@ static long IpsChangeField(long pc, void *object)
|
||||
goto ramping;
|
||||
|
||||
target_reached:
|
||||
drv->d.hwstate = HWIdle;
|
||||
EaseUpdateHwstate(drv, HWIdle);
|
||||
drv->d.eMode = EVMonitor; /* we are at field, drive has finished */
|
||||
if (drv->persmode != 1)
|
||||
goto hold_finish;
|
||||
@ -987,7 +991,7 @@ static long IpsChangeField(long pc, void *object)
|
||||
finish:
|
||||
EaseWrite(eab, "C0");
|
||||
drv->remote = 0; /* local state */
|
||||
drv->d.hwstate = HWIdle;
|
||||
EaseUpdateHwstate(drv, HWIdle);
|
||||
drv->tim = time(NULL); /* time of last field change */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
|
23
make_gen
23
make_gen
@ -9,6 +9,12 @@
|
||||
.tc.c:
|
||||
tjxp $*.tc $*.c
|
||||
|
||||
MZOBJ=fsm.o sugar.o pardef.o ease.o strobj.o oxinst.o \
|
||||
ipsdriv.o ilmdriv.o itcdriv.o ighdriv.o euro2kdriv.o modbus.o arrobj.o \
|
||||
linadriv.o haakedriv.o seaclientprot.o dumprot.o
|
||||
|
||||
COREOBJ=phytron.o pfeifferprot.o
|
||||
|
||||
OBJ=psi.o buffer.o ruli.o sps.o pimotor.o \
|
||||
pipiezo.o sanswave.o faverage.o spss7.o\
|
||||
amorstat.o tasinit.o ptasdrive.o tasutil.o tasscan.o swmotor.o \
|
||||
@ -23,24 +29,27 @@ OBJ=psi.o buffer.o ruli.o sps.o pimotor.o \
|
||||
dgrambroadcast.o sinq.o tabledrive.o sinqhttpopt.o\
|
||||
ritastorage.o el737hpdrivsps.o \
|
||||
rebin.o sanslirebin.o lmd200.o slsvme.o julprot.o sinqhttpprot.o \
|
||||
pfeifferprot.o termprot.o phytron.o autowin.o eigera2.o \
|
||||
jvlprot.o \
|
||||
termprot.o autowin.o eigera2.o jvlprot.o \
|
||||
eigermono.o sputterprot.o zwickroll.o astriumnet.o poldifold.o \
|
||||
zebraswap.o
|
||||
zebraswap.o \
|
||||
$(COREOBJ)
|
||||
|
||||
SEAOBJ=sea_psi.o $(MZOBJ) $(COREOBJ)
|
||||
|
||||
#epicsadapter.o
|
||||
|
||||
.SECONDARY.: sanslirebin.c
|
||||
|
||||
MZOBJ=fsm.o sugar.o pardef.o ease.o strobj.o oxinst.o \
|
||||
ipsdriv.o ilmdriv.o itcdriv.o ighdriv.o euro2kdriv.o modbus.o arrobj.o \
|
||||
linadriv.o haakedriv.o seaclientprot.o dumprot.o
|
||||
|
||||
libpsi.a: $(OBJ)
|
||||
rm -f libpsi.a
|
||||
ar cr libpsi.a $(OBJ)
|
||||
ranlib libpsi.a
|
||||
|
||||
libseapsi.a: $(SEAOBJ)
|
||||
rm -f libseapsi.a
|
||||
ar cr libseapsi.a $(SEAOBJ)
|
||||
ranlib libseapsi.a
|
||||
|
||||
clean:
|
||||
rm -f *.a *.o *.d
|
||||
|
||||
|
312
pardef.c
312
pardef.c
@ -15,9 +15,12 @@ Markus Zolliker, March 2005
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include "logger.h"
|
||||
#include "logsetup.h"
|
||||
#include "pardef.h"
|
||||
#include "sugar.h"
|
||||
#include "dynstring.h"
|
||||
#include "sicshipadaba.h"
|
||||
#include "ease.h"
|
||||
|
||||
#define ILLNUM -2
|
||||
#define ILLARGC -3
|
||||
@ -28,7 +31,10 @@ Markus Zolliker, March 2005
|
||||
#define PARUNDEF -8
|
||||
#define ERRCMD -9
|
||||
|
||||
typedef enum { NO_OP, FMT_OP, SET_OP, GET_OP, INIT_OP } ParOp;
|
||||
Logger dummy_logger;
|
||||
Logger *secop_logger = &dummy_logger; /* disable parlog, and do it with hdb logger */
|
||||
|
||||
typedef enum { NO_OP, FMT_OP, SET_OP, GET_OP, INIT_OP, UPD_OP } ParOp;
|
||||
|
||||
/* Context holds all the information needed during the pardef function */
|
||||
typedef struct Context {
|
||||
@ -58,6 +64,7 @@ typedef struct Context {
|
||||
int exact;
|
||||
char *callName; /* the called name of the object (different from obj->name in case of an alias) */
|
||||
int enumText; /* show enum text */
|
||||
hdbValue *hvalue;
|
||||
} Context;
|
||||
|
||||
static char *loggerDir = NULL;
|
||||
@ -293,6 +300,7 @@ static int ParSaveAll(void *object, char *name, FILE * fil)
|
||||
ParDo(0, o, PAR_SAVE, NULL);
|
||||
if (o->creationCmd) {
|
||||
fprintf(fil, "%s endinit\n\n", name);
|
||||
/* fprintf(fil, "put_secop_info %s\n\n", name); */
|
||||
}
|
||||
ctx->saveFile = NULL;
|
||||
ret = ctx->returnValue;
|
||||
@ -308,7 +316,15 @@ FILE *ParSaveFile(void)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void ParUpdateAll(void *object)
|
||||
{
|
||||
ParData *o = ParCheck(&parClass, object);
|
||||
|
||||
ParBegin();
|
||||
ParDo(0, o, PAR_UPDATE, NULL);
|
||||
ParEnd();
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int ParLog(void *object)
|
||||
{
|
||||
@ -327,14 +343,16 @@ int ParLog(void *object)
|
||||
ctx->now = time(NULL);
|
||||
next = ctx->now - (o->logTime / o->period + 1) * o->period;
|
||||
if (next < 0) {
|
||||
ParEnd();
|
||||
return 1;
|
||||
}
|
||||
showTime = 1;
|
||||
ParDo(0, o, PAR_LOG, NULL);
|
||||
o->logTime = ctx->now;
|
||||
o->logPending = 0;
|
||||
ParEnd();
|
||||
if (!secop_logger) {
|
||||
ParDo(0, o, PAR_LOG, NULL);
|
||||
o->logTime = ctx->now;
|
||||
o->logPending = 0;
|
||||
ParEnd();
|
||||
}
|
||||
ParUpdateAll(o);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -347,12 +365,15 @@ void ParLogForced(void *object)
|
||||
ParBegin();
|
||||
ctx->now = time(NULL);
|
||||
showTime = 1;
|
||||
ParDo(0, o, PAR_LOG, NULL);
|
||||
o->logTime = ctx->now;
|
||||
if (o->logPending) {
|
||||
o->logPending = 2; /* tell ParLog that we are done already, but task is still pending */
|
||||
if (!secop_logger) {
|
||||
ParDo(0, o, PAR_LOG, NULL);
|
||||
o->logTime = ctx->now;
|
||||
if (o->logPending) {
|
||||
o->logPending = 2; /* tell ParLog that we are done already, but task is still pending */
|
||||
}
|
||||
ParEnd();
|
||||
}
|
||||
ParEnd();
|
||||
ParUpdateAll(o);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@ -474,7 +495,7 @@ static int ParExecute(SConnection * con, SicsInterp * sics, void *object,
|
||||
ParData *o = ParCheck(&parClass, object);
|
||||
char *setArgv[2];
|
||||
ParInfo *info;
|
||||
|
||||
|
||||
/* debugging
|
||||
int i;
|
||||
printf("ParExecute");
|
||||
@ -519,29 +540,27 @@ static int ParExecute(SConnection * con, SicsInterp * sics, void *object,
|
||||
SCSendOK(con);
|
||||
ctx->returnValue = 1;
|
||||
}
|
||||
} else
|
||||
if ((0 == strcasecmp(argv[1], "log")
|
||||
} else if ((0 == strcasecmp(argv[1], "log")
|
||||
|| 0 == strcasecmp(argv[1], "unlog"))) {
|
||||
if (argc < 3) {
|
||||
ctx->returnValue = ILLARGC;
|
||||
ctx->thisPar = argv[1];
|
||||
} else {
|
||||
} else if (!secop_logger) {
|
||||
ctx->argc = argc - 3;
|
||||
ctx->argv = argv + 3;
|
||||
ctx->doit = toupper(argv[1][0]) != 'U';
|
||||
ctx->exact = 0;
|
||||
ParDo(con, o, PAR_LOGSWITCH, argv[2]);
|
||||
}
|
||||
} else
|
||||
if ((0 == strcasecmp(argv[1], "save")
|
||||
} else if ((0 == strcasecmp(argv[1], "save")
|
||||
|| 0 == strcasecmp(argv[1], "unsave"))) {
|
||||
if (argc != 3) {
|
||||
ctx->returnValue = ILLARGC;
|
||||
} else {
|
||||
} else if (!secop_logger) {
|
||||
ctx->doit = toupper(argv[1][0]) != 'U';
|
||||
ParDo(con, o, PAR_SAVESWITCH, argv[2]);
|
||||
SCparChange(con);
|
||||
}
|
||||
SCparChange(con);
|
||||
} else if (strcmp(argv[1], "interest") == 0) {
|
||||
if (!o->pCall) {
|
||||
o->pCall = CreateCallBackInterface();
|
||||
@ -620,7 +639,7 @@ static int ParExecute(SConnection * con, SicsInterp * sics, void *object,
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void KillLogger(ParInfo * par)
|
||||
{
|
||||
if (par->log != NULL) {
|
||||
if (par->log != NULL && par->log != secop_logger) {
|
||||
LoggerKill(par->log);
|
||||
if (par->sugarStatus == 1) {
|
||||
RemoveCommand(pServ->pSics, LoggerName(par->log));
|
||||
@ -651,9 +670,11 @@ int ParSwitchLog(int on, char *name)
|
||||
loggerDir = "./";
|
||||
LoggerSetDir(loggerDir);
|
||||
}
|
||||
ctx->par->log = LoggerMake(name, ctx->obj->period, ctx->exact);
|
||||
if (ctx->par->log == NULL) {
|
||||
return BADLOG;
|
||||
if (!secop_logger) {
|
||||
ctx->par->log = LoggerMake(name, ctx->obj->period, ctx->exact);
|
||||
if (ctx->par->log == NULL) {
|
||||
return BADLOG;
|
||||
}
|
||||
}
|
||||
if (ctx->par->sugarStatus == 0 && name != buf
|
||||
&& strcmp(name, buf) != 0) {
|
||||
@ -704,6 +725,7 @@ void ParFind(void)
|
||||
p->saveIt = 0;
|
||||
p->saveLog = 0;
|
||||
p->state = PAR_ALWAYS_READY;
|
||||
p->node = NULL;
|
||||
p->next = *last;
|
||||
*last = p;
|
||||
}
|
||||
@ -773,6 +795,7 @@ void ParName(char *name)
|
||||
switch (ctx->act) {
|
||||
case PAR_SHOW:
|
||||
case PAR_SET:
|
||||
case PAR_HDBSET:
|
||||
ctx->enumList = NULL;
|
||||
if (0 == strcasecmp(name, ctx->thisPar)) {
|
||||
ctx->access = -1;
|
||||
@ -813,6 +836,9 @@ void ParName(char *name)
|
||||
ctx->action = PAR_NOOP;
|
||||
}
|
||||
return;
|
||||
case PAR_UPDATE:
|
||||
ctx->doit = 0; /* affects visibility */
|
||||
break;
|
||||
case PAR_SAVE:
|
||||
case PAR_KILL:
|
||||
case PAR_NOOP:
|
||||
@ -922,8 +948,12 @@ ParOp ParWhat(int numeric)
|
||||
} else {
|
||||
lname = NULL;
|
||||
}
|
||||
ParSwitchLog(1, lname);
|
||||
LoggerSetNumeric(ctx->par->log, numeric);
|
||||
if (secop_logger) {
|
||||
ctx->par->log = secop_logger;
|
||||
} else {
|
||||
ParSwitchLog(1, lname);
|
||||
LoggerSetNumeric(ctx->par->log, numeric);
|
||||
}
|
||||
}
|
||||
}
|
||||
return INIT_OP;
|
||||
@ -934,6 +964,7 @@ ParOp ParWhat(int numeric)
|
||||
}
|
||||
ctx->returnValue = 1;
|
||||
return FMT_OP;
|
||||
case PAR_HDBSET:
|
||||
case PAR_SET:
|
||||
if (ctx->returnValue) {
|
||||
ctx->returnValue = AMBIGUOS;
|
||||
@ -971,6 +1002,8 @@ ParOp ParWhat(int numeric)
|
||||
break;
|
||||
}
|
||||
return GET_OP;
|
||||
case PAR_UPDATE:
|
||||
return UPD_OP;
|
||||
default:
|
||||
return NO_OP;
|
||||
}
|
||||
@ -1078,6 +1111,7 @@ void ParOut(char *buf)
|
||||
ParPrintf(NULL, eValue, "%s%s%s = %s", ctx->callName,
|
||||
p, ctx->parName, buf);
|
||||
break;
|
||||
case PAR_HDBSET:
|
||||
case PAR_SET:
|
||||
if (ctx->parName[0]) {
|
||||
p = " ";
|
||||
@ -1178,6 +1212,8 @@ void ParList(char *group)
|
||||
} else if (ctx->doit < 0) {
|
||||
ctx->doit = 0;
|
||||
}
|
||||
} else if (ctx->action == PAR_UPDATE) {
|
||||
ctx->doit = group == NULL || group[0] != '\0';
|
||||
}
|
||||
}
|
||||
|
||||
@ -1186,6 +1222,8 @@ void ParTail(char *tail)
|
||||
{
|
||||
if (ctx->action == PAR_LIST) {
|
||||
ctx->listTail = tail;
|
||||
} else if (ctx->action == PAR_UPDATE) {
|
||||
ctx->doit = 1; /* always visible */
|
||||
}
|
||||
}
|
||||
|
||||
@ -1215,6 +1253,117 @@ void ParHasChanged(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static hdbCallbackReturn ParUpdateCB(pHdb node, void *userData, pHdbMessage msg) {
|
||||
hdbDataMessage *setMsg;
|
||||
|
||||
if ((setMsg = GetHdbSetMessage(msg))){
|
||||
ParBegin();
|
||||
ctx->hvalue = setMsg->v;
|
||||
ParDo(NULL, userData, PAR_HDBSET, node->name);
|
||||
ParEnd();
|
||||
}
|
||||
return hdbContinue;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void ParUpdateNode(hdbValue value) {
|
||||
pHdb node;
|
||||
char sicscommand[128];
|
||||
char path[128];
|
||||
char secop_id[128];
|
||||
int skip_unchanged = 1;
|
||||
|
||||
if (!ctx->obj->node) {
|
||||
ctx->obj->secop_module = ctx->obj->name;
|
||||
if (ctx->parName[0]) {
|
||||
/* main node is not yet created -> assume it is of type NONE */
|
||||
node = MakeHipadabaNode(ctx->obj->name, HIPNONE, 0);
|
||||
if (ctx->obj->secop_module) {
|
||||
SetHdbProperty(node, "secop_module", ctx->obj->secop_module);
|
||||
}
|
||||
} else {
|
||||
node = MakeSICSHdbPar(ctx->obj->name, ctx->access, value);
|
||||
if (ctx->par->log && ctx->obj->secop_module) {
|
||||
snprintf(secop_id, sizeof secop_id, "%s:value", ctx->obj->secop_module);
|
||||
SetHdbProperty(node, "secop_id", secop_id);
|
||||
snprintf(path, sizeof path, "/%s", ctx->obj->name);
|
||||
LogMakeInternal(node, path, 0); /* secop_module */
|
||||
skip_unchanged = 0;
|
||||
}
|
||||
}
|
||||
ctx->obj->node = node;
|
||||
AddHipadabaChild(GetHipadabaRoot(), node, NULL);
|
||||
SetHdbProperty(node, "sicscommand", ctx->obj->name);
|
||||
SetHdbProperty(node, "group", "_pardef_");
|
||||
}
|
||||
node = ctx->par->node;
|
||||
if (node == NULL) { /* node is not yet set */
|
||||
if (ctx->parName[0]) {
|
||||
if (strchr(ctx->parName, '/') != NULL) {
|
||||
return; /* do not allow parameter names containing '/' */
|
||||
}
|
||||
node = AddSICSHdbPar(ctx->obj->node, ctx->parName, ctx->access, value);
|
||||
if (ctx->par->log && ctx->obj->secop_module) {
|
||||
snprintf(secop_id, sizeof secop_id, "%s:%s", ctx->obj->secop_module, ctx->parName);
|
||||
SetHdbProperty(node, "secop_id", secop_id);
|
||||
snprintf(path, sizeof path, "/%s/%s", ctx->obj->name, ctx->parName);
|
||||
LogMakeInternal(node, path, 0);
|
||||
skip_unchanged = 0;
|
||||
}
|
||||
ctx->par->node = node;
|
||||
snprintf(sicscommand, sizeof sicscommand, "%s %s", ctx->obj->name, ctx->parName);
|
||||
} else {
|
||||
/* bare object (parameter "") */
|
||||
node = ctx->obj->node;
|
||||
snprintf(sicscommand, sizeof sicscommand, "%s = ", ctx->obj->name);
|
||||
}
|
||||
SetHdbProperty(node, "sicscommand", sicscommand);
|
||||
AppendHipadabaCallback(node, MakeHipadabaCallback(ParUpdateCB, ctx->obj, NULL));
|
||||
}
|
||||
if (ctx->action == PAR_UPDATE) {
|
||||
char *visible = GetHdbProp(node, "visible");
|
||||
if (ctx->doit) {
|
||||
if (visible) {
|
||||
SetHdbProperty(node, "visible", NULL);
|
||||
}
|
||||
} else {
|
||||
if (!visible || strcasecmp(visible, "false") != 0) {
|
||||
SetHdbProperty(node, "visible", "false");
|
||||
}
|
||||
}
|
||||
switch (value.dataType) {
|
||||
case HIPFLOAT:
|
||||
if (value.v.doubleValue == PAR_NAN) {
|
||||
if (GetHdbProp(node, "geterror") == NULL) {
|
||||
SetHdbProperty(node, "geterror", "undefined");
|
||||
value.v.doubleValue = 0;
|
||||
UpdateHipadabaPar(node, value, ctx->con);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (skip_unchanged && node->value.v.doubleValue == value.v.doubleValue) return;
|
||||
break;
|
||||
case HIPINT:
|
||||
if (value.v.intValue == PAR_LNAN) {
|
||||
if (GetHdbProp(node, "geterror") == NULL) {
|
||||
SetHdbProperty(node, "geterror", "undefined");
|
||||
value.v.intValue = 0;
|
||||
UpdateHipadabaPar(node, value, ctx->con);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (skip_unchanged && node->value.v.intValue == value.v.intValue) return;
|
||||
break;
|
||||
case HIPTEXT:
|
||||
if (strcmp(node->value.v.text, value.v.text) == 0) return;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
SetHdbProperty(node, "geterror", NULL);
|
||||
UpdateHipadabaPar(node, value, ctx->con);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void ParFloat(float *value, float defValue)
|
||||
@ -1225,6 +1374,10 @@ void ParFloat(float *value, float defValue)
|
||||
|
||||
switch (ParWhat(1)) {
|
||||
case SET_OP:
|
||||
if (ctx->action == PAR_HDBSET) {
|
||||
*value = ctx->hvalue->v.doubleValue;
|
||||
break;
|
||||
}
|
||||
if (ctx->argc > 1) {
|
||||
ctx->returnValue = ILLARGC;
|
||||
return;
|
||||
@ -1262,6 +1415,10 @@ void ParFloat(float *value, float defValue)
|
||||
break;
|
||||
case INIT_OP:
|
||||
*value = defValue;
|
||||
ParUpdateNode(MakeHdbFloat(*value));
|
||||
break;
|
||||
case UPD_OP:
|
||||
ParUpdateNode(MakeHdbFloat(*value));
|
||||
break;
|
||||
case NO_OP:
|
||||
break;
|
||||
@ -1277,6 +1434,10 @@ void ParInt(int *value, int defValue)
|
||||
|
||||
switch (ParWhat(1)) {
|
||||
case SET_OP:
|
||||
if (ctx->action == PAR_HDBSET) {
|
||||
*value = ctx->hvalue->v.intValue;
|
||||
break;
|
||||
}
|
||||
if (ctx->argc > 1) {
|
||||
ctx->returnValue = ILLARGC;
|
||||
return;
|
||||
@ -1309,6 +1470,10 @@ void ParInt(int *value, int defValue)
|
||||
break;
|
||||
case INIT_OP:
|
||||
*value = defValue;
|
||||
ParUpdateNode(MakeHdbInt(defValue));
|
||||
break;
|
||||
case UPD_OP:
|
||||
ParUpdateNode(MakeHdbInt(*value));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1319,11 +1484,17 @@ void ParInt(int *value, int defValue)
|
||||
void ParStr(char **value, char *defValue)
|
||||
{
|
||||
static char *empty = "";
|
||||
char *to_free;
|
||||
|
||||
switch (ParWhat(0)) {
|
||||
case SET_OP:
|
||||
if (*value != NULL)
|
||||
free(*value);
|
||||
to_free = *value;
|
||||
if (ctx->action == PAR_HDBSET) {
|
||||
if (to_free) free(to_free);
|
||||
*value = strdup(ctx->hvalue->v.text);
|
||||
break;
|
||||
}
|
||||
if (to_free) free(to_free);
|
||||
if (ctx->argc > 0 && strcmp(ctx->argv[0], "=") == 0) {
|
||||
*value = ParArg2Str(ctx->argc - 1, ctx->argv + 1, NULL, 0);
|
||||
} else {
|
||||
@ -1332,14 +1503,26 @@ void ParStr(char **value, char *defValue)
|
||||
ParHasChanged();
|
||||
/* fall through */
|
||||
case FMT_OP:
|
||||
if (*value == NULL)
|
||||
value = ∅
|
||||
ParOut(*value);
|
||||
if (*value == NULL) {
|
||||
ParOut(empty);
|
||||
} else {
|
||||
ParOut(*value);
|
||||
}
|
||||
break;
|
||||
case INIT_OP:
|
||||
ctx->exact = 1;
|
||||
if (defValue != NULL) {
|
||||
if (defValue == NULL) {
|
||||
ParUpdateNode(MakeHdbText(""));
|
||||
} else{
|
||||
*value = strdup(defValue);
|
||||
ParUpdateNode(MakeHdbText(*value));
|
||||
}
|
||||
break;
|
||||
case UPD_OP:
|
||||
if (*value == NULL) {
|
||||
ParUpdateNode(MakeHdbText(""));
|
||||
} else {
|
||||
ParUpdateNode(MakeHdbText(*value));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1357,6 +1540,10 @@ void ParFixedStr(char *value, int maxsize, char *defValue)
|
||||
|
||||
switch (ParWhat(0)) {
|
||||
case SET_OP:
|
||||
if (ctx->action == PAR_HDBSET) {
|
||||
snprintf(value, maxsize, "%s", ctx->hvalue->v.text);
|
||||
break;
|
||||
}
|
||||
ParArg2Str(ctx->argc, ctx->argv, value, maxsize);
|
||||
ParHasChanged();
|
||||
/* fall through */
|
||||
@ -1367,10 +1554,16 @@ void ParFixedStr(char *value, int maxsize, char *defValue)
|
||||
break;
|
||||
case INIT_OP:
|
||||
ctx->exact = 1;
|
||||
if (defValue != NULL) {
|
||||
if (defValue == NULL) {
|
||||
ParUpdateNode(MakeHdbText(""));
|
||||
} else{
|
||||
snprintf(value, maxsize, "%s", defValue);
|
||||
ParUpdateNode(MakeHdbText(value));
|
||||
}
|
||||
break;
|
||||
case UPD_OP:
|
||||
ParUpdateNode(MakeHdbText(value));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1464,6 +1657,36 @@ void ParGetFloat(SConnection * con, void *object, char *name, float *value)
|
||||
ParEnd();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void ParKillThisPar(ParInfo *p)
|
||||
{
|
||||
p->next = NULL;
|
||||
if (p->node) {
|
||||
RemoveSICSPar(p->node, NULL);
|
||||
}
|
||||
KillLogger(p);
|
||||
if (p->name) {
|
||||
free(p->name);
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void ParKillPar(void *object, char *name)
|
||||
{
|
||||
ParData *o = object;
|
||||
ParInfo *p, **last;
|
||||
|
||||
last = &o->infoList;
|
||||
for (p=o->infoList; p!=NULL; last=&p->next, p=p->next) {
|
||||
if (strcasecmp(name, p->name) == 0) {
|
||||
*last = p->next;
|
||||
ParKillThisPar(p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void ParKill(void *object)
|
||||
{
|
||||
@ -1485,14 +1708,13 @@ void ParKill(void *object)
|
||||
p = o->infoList;
|
||||
while (p) {
|
||||
q = p->next;
|
||||
p->next = NULL;
|
||||
KillLogger(p);
|
||||
if (p->name) {
|
||||
free(p->name);
|
||||
}
|
||||
free(p);
|
||||
ParKillThisPar(p);
|
||||
p = q;
|
||||
}
|
||||
if (o->node) {
|
||||
RemoveSICSPar(o->node, NULL); /* this deletes also all children */
|
||||
o->node = NULL;
|
||||
}
|
||||
if (o->logPending) { /* will be free in scheduled ParLog function */
|
||||
o->desc = NULL;
|
||||
} else {
|
||||
@ -1510,15 +1732,22 @@ void ParKill(void *object)
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void ParInitPar(void *object, char *name)
|
||||
void ParInitPar(void *object, char *name, int logged)
|
||||
{
|
||||
|
||||
ParBegin();
|
||||
ctx->obj = object;
|
||||
ctx->parName = name;
|
||||
ctx->par = NULL;
|
||||
ParFind();
|
||||
ParSwitchLog(1, NULL);
|
||||
if (logged) {
|
||||
if (secop_logger) {
|
||||
if (ctx->par) {
|
||||
ctx->par->log = secop_logger;
|
||||
}
|
||||
} else {
|
||||
ParSwitchLog(1, NULL);
|
||||
}
|
||||
}
|
||||
ParEnd();
|
||||
}
|
||||
|
||||
@ -1558,6 +1787,7 @@ void *ParMake(SConnection * con, char *name, ParClass * class,
|
||||
o->verbose = 0;
|
||||
o->logPending = 0;
|
||||
o->conn = NULL;
|
||||
o->node = NULL;
|
||||
ParSaveConn(o, con);
|
||||
o->pardef = pardef;
|
||||
ParBegin();
|
||||
|
14
pardef.h
14
pardef.h
@ -12,6 +12,7 @@ Markus Zolliker, March 2005
|
||||
|
||||
#include "sics.h"
|
||||
#include "logger.h"
|
||||
#include "hipadaba.h"
|
||||
|
||||
int ParPrintf(void *object, int iOut, const char *fmt, ...);
|
||||
|
||||
@ -25,6 +26,7 @@ typedef struct ParInfo {
|
||||
int saveLog; /* bool */
|
||||
ReadyState state; /* enum ReadyState */
|
||||
int sugarStatus; /* =1: sugar object made */
|
||||
pHdb node; /* node for update */
|
||||
} ParInfo;
|
||||
|
||||
#define PAR_LEVELS 8
|
||||
@ -53,6 +55,8 @@ typedef struct ParData {
|
||||
pICallBack pCall; /* sics callback function */
|
||||
SConnection *conn; /* last connection with user or manager priv. */
|
||||
int verbose; /* verbosity, mainly for tests */
|
||||
pHdb node; /* node for update */
|
||||
char *secop_module; /* secop module name, if enabled */
|
||||
} ParData;
|
||||
|
||||
/*
|
||||
@ -174,7 +178,9 @@ typedef enum {
|
||||
PAR_LOGSWITCH, /* (de)activate single parameter for logging (1) */
|
||||
PAR_SAVE, /* save all parameters activated for saving (2) */
|
||||
PAR_SAVESWITCH, /* (de)activate single parameter for saving (1) */
|
||||
PAR_KILL /* kill content (called before remove) */
|
||||
PAR_KILL, /* kill content (called before remove) */
|
||||
PAR_UPDATE, /* update hipadaba node */
|
||||
PAR_HDBSET /* set from hipadaba node */
|
||||
} ParAct;
|
||||
|
||||
int ParActionIs(ParAct action);
|
||||
@ -203,6 +209,7 @@ char *ParGetValueArg(); /* get the set argument for floats and ints. If
|
||||
/*
|
||||
functions to be used outside pardef:
|
||||
*/
|
||||
void ParUpdateAll(void *object); /* update all hdb nodes */
|
||||
int ParLog(void *object); /* log all parameters of this object, but only if not
|
||||
already logged in the interval, returns >= 0 when done,
|
||||
or < 0, when not done (execute PAR_LOG action) */
|
||||
@ -241,7 +248,10 @@ char *ParArg2Str(int argc, char *argv[], char *res, int maxsize);
|
||||
void ParSaveConn(void *object, SConnection * con);
|
||||
/* save connection for further use */
|
||||
|
||||
void ParInitPar(void *object, char *name);
|
||||
void ParInitPar(void *object, char *name, int logged);
|
||||
/* inititalize dynamic parameter */
|
||||
|
||||
void ParKillPar(void *object, char *name);
|
||||
/* delete dynamic parameter */
|
||||
|
||||
#endif
|
||||
|
182
sea_psi.c
Normal file
182
sea_psi.c
Normal file
@ -0,0 +1,182 @@
|
||||
/*------------------------------------------------------------------------
|
||||
P S I
|
||||
|
||||
This is the site specific interface to SICS for PSI. This file implements
|
||||
the interface defined in ../site.h
|
||||
|
||||
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, June 2003 - May 2007
|
||||
|
||||
Modules initialized with an installation sics command are added to
|
||||
AddPsiCommands with SCMD.
|
||||
Modules initialized with a startup C command are added to SiteInit with
|
||||
INIT.
|
||||
There is no need to add include statements or prototype declarations for
|
||||
above items.
|
||||
However, for drivers added, we still need to declare the prototypes or
|
||||
include the header file.
|
||||
Markus Zolliker, Jan 2010
|
||||
-----------------------------------------------------------------------*/
|
||||
#include <tcl.h>
|
||||
#include "sics.h"
|
||||
#include "site.h"
|
||||
#include <motor.h>
|
||||
#include <site.h>
|
||||
#include "sinqhmdriv.i"
|
||||
#include "tdchm.h"
|
||||
#include "itc4.h"
|
||||
#include "bruker.h"
|
||||
#include "ltc11.h"
|
||||
#include "eurodriv.h"
|
||||
#include "el755driv.h"
|
||||
#include <evdriver.i>
|
||||
#include "serial.h"
|
||||
#include "sinqhttp.h"
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void SiteInit(void)
|
||||
{
|
||||
|
||||
#define INIT(F) { void F(void); F(); }
|
||||
|
||||
/* insert here initialization routines ... */
|
||||
|
||||
INIT(IlmStartup);
|
||||
INIT(IpsStartup);
|
||||
INIT(ItcStartup);
|
||||
INIT(IghStartup);
|
||||
INIT(Euro2kStartup);
|
||||
INIT(StrObjStartup);
|
||||
INIT(ArrayObjStartup);
|
||||
INIT(LinaStartup);
|
||||
INIT(HaakeStartup);
|
||||
/* INIT(MongoLogInit); */
|
||||
|
||||
/*
|
||||
* SICS specific Asynchronous I/O protocols
|
||||
*/
|
||||
INIT(AddSeaClientProtocol);
|
||||
INIT(AddDumProtocol);
|
||||
INIT(AddPhytronProtocoll);
|
||||
INIT(AddPfeifferProtocoll);
|
||||
}
|
||||
|
||||
|
||||
static pSite sitePSI = NULL;
|
||||
|
||||
/*
|
||||
* from tclClock.c
|
||||
*/
|
||||
int Tcl_ClockObjCmd (ClientData client, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
static void AddPsiCommands(SicsInterp * pInter)
|
||||
{
|
||||
/* declare and add permanent command */
|
||||
#define PCMD(NAME, FUN) { \
|
||||
int FUN(SConnection * pCon, SicsInterp * pSics, void *pData, \
|
||||
int argc, char *argv[]); \
|
||||
AddCommandWithFlag(pInter, NAME, FUN, NULL, NULL, 0); \
|
||||
}
|
||||
|
||||
/* declare and add startup command */
|
||||
#define SCMD(NAME, FUN) { \
|
||||
int FUN(SConnection * pCon, SicsInterp * pSics, void *pData, \
|
||||
int argc, char *argv[]); \
|
||||
AddCommandWithFlag(pInter, NAME, FUN, NULL, NULL, 1); \
|
||||
}
|
||||
|
||||
/* alphabetic order */
|
||||
/* SCMD("SerialInit", SerialInit); */
|
||||
PCMD("cnvrt", CnvrtAction);
|
||||
/*
|
||||
* Tcl 8.5 has implemented the clock command in tcl rather then C.
|
||||
* This includes the same command, backported from Tcl 8.4
|
||||
*/
|
||||
Tcl_CreateObjCommand(InterpGetTcl(pServ->pSics), "clock", Tcl_ClockObjCmd, NULL, NULL);
|
||||
|
||||
/*
|
||||
SCMD("MakeDifrac",MakeDifrac);
|
||||
*/
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
static pMotor CreatePsiMotor(SConnection * pCon, int argc, char *argv[])
|
||||
{
|
||||
pMotor pNew = NULL;
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
static pCounterDriver CreatePsiCounterDriver(SConnection * pCon,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
pCounterDriver pNew = NULL;
|
||||
return pNew;
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
static pCodri CreatePsiController(SConnection * pCon, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
pCodri pNew = NULL;
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
|
||||
static pEVControl InstallPsiEnvironmentController(SicsInterp * pSics,
|
||||
SConnection * pCon,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*/
|
||||
static int ConfigurePsiScan(pScanData self, char *option)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
static HistDriver *CreatePsiHistMem(char *name, pStringDict pOptions)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static void KillPsi(void *site)
|
||||
{
|
||||
free(site);
|
||||
sitePSI = NULL;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
The scheme here goes along the lines of the singleton design pattern
|
||||
---------------------------------------------------------------------*/
|
||||
pSite getSite(void)
|
||||
{
|
||||
if (sitePSI == NULL) {
|
||||
sitePSI = (pSite) malloc(sizeof(Site));
|
||||
/*
|
||||
we cannot go on if we do not even have enough memory to allocate
|
||||
the site data structure
|
||||
*/
|
||||
assert(sitePSI);
|
||||
/*
|
||||
initializing function pointers
|
||||
*/
|
||||
sitePSI->AddSiteCommands = AddPsiCommands;
|
||||
sitePSI->RemoveSiteCommands = NULL;
|
||||
sitePSI->CreateMotor = CreatePsiMotor;
|
||||
sitePSI->CreateCounterDriver = CreatePsiCounterDriver;
|
||||
sitePSI->CreateHistogramMemoryDriver = CreatePsiHistMem;
|
||||
sitePSI->CreateVelocitySelector = NULL;
|
||||
sitePSI->CreateControllerDriver = CreatePsiController;
|
||||
sitePSI->InstallEnvironmentController =
|
||||
InstallPsiEnvironmentController;
|
||||
sitePSI->ConfigureScan = ConfigurePsiScan;
|
||||
sitePSI->KillSite = KillPsi;
|
||||
}
|
||||
return sitePSI;
|
||||
}
|
Reference in New Issue
Block a user