PSI sics-cvs-psi-2006

This commit is contained in:
2006-05-08 02:00:00 +00:00
committed by Douglas Clowes
parent ae77364de2
commit 6e926b813f
388 changed files with 445529 additions and 14109 deletions

View File

@@ -1,7 +1,7 @@
/*---------------------------------------------------------------------------
E N V I R O N M E N T C O N T R O L L E R
This is the implementation file for a base class for all environement
This is the implementation file for a base class for all environment
control devices in SICS.
Mark Koennecke, Juli 1997
@@ -66,6 +66,7 @@
#include "chadapter.h"
#include "status.h"
#include "site.h"
#include "commandlog.h"
/*--------------------- Functions needed to implement interfaces -----------*/
static long EVIDrive(void *pData, SConnection *pCon, float fVal)
{
@@ -83,7 +84,8 @@
self->start = time(NULL);
self->lastt = 0;
self->iWarned = 0;
SCSave(&self->conn, pCon);
/* try at least three times to do it */
for(i = 0; i < 3; i++)
{
@@ -171,16 +173,27 @@
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)
{
pEVControl self = NULL;
float fPos, fDelta;
float fPos, fDelta = .0;
int iRet, iCode, iFix;
char pBueffel[256], pError[132];
static int callCount, iCount=0;
static int callCount;
time_t now, tmo;
float tol;
self = (pEVControl)pData;
assert(self);
assert(pCon);
@@ -188,13 +201,13 @@
/* go to idle when stopped */
if(self->iStop)
{
notifyStatus(self, pCon, HWIdle);
return HWIdle;
}
/* get the current position */
iRet = self->pDriv->GetValues(self->pDriv,&self->fTarget,&fPos,&fDelta);
if(iRet == 0)
{
self->pDriv->GetError(self->pDriv,&iCode, pError,131);
@@ -207,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;
}
@@ -226,6 +242,7 @@
self->pName);
SCWrite(pCon,pBueffel,eError);
self->eMode = EVIdle;
notifyStatus(self, pCon, HWFault);
return HWFault;
}
@@ -239,7 +256,7 @@
if(callCount >= 10)
{
sprintf(pBueffel,"%s = %g", self->pName, fPos);
InvokeCallBack(self->pCall, VALUECHANGE,pBueffel);
InvokeCallBack(self->pCall, VALUECHANGE,pBueffel);
callCount = 0;
}
@@ -252,46 +269,46 @@
self->pName);
SCWrite(pCon,pBueffel,eError);
self->eMode = EVMonitor;
notifyStatus(self, pCon, HWIdle);
return HWIdle;
}
if(fDelta <= ObVal(self->pParam, TOLERANCE)) /* done */
tol = ObVal(self->pParam, TOLERANCE);
if (self->lastt > 0) { /* increase tol for hysteresis */
tol=tol*1.1001;
}
if(fDelta <= tol) /* inside tolerance */
{
if (iCount < 3)
{
iCount++;
return HWBusy;
}
tmo = (int)(ObVal(self->pParam, SETTLE));
if (self->lastt <= 0) /* lastt negative: -seconds already waited */
{
self->lastt += now;
if (tmo>0)
{
sprintf(pBueffel,"%s inside tolerance, wait %.2f sec. to settle",
sprintf(pBueffel,"%s inside tolerance, wait %.2f sec to settle",
self->pName, (self->lastt + tmo - now)*1.0);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eWarning);
}
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
{
if (iCount > 0) {
iCount--;
return HWBusy;
}
if (self->lastt > 0) { /* save time already waited */
sprintf(pBueffel,"%s outside tolerance, settling time suspended",
self->pName);
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,pBueffel,eWarning);
self->lastt -= now;
}
notifyStatus(self, pCon, HWBusy);
return HWBusy;
}
}
@@ -341,7 +358,7 @@
}
/*---------------------------- Error Handlers --------------------------------*/
static void ErrWrite(char *txt)
static void ErrWrite(char *txt, SCStore *conn)
{
pExeList pExe;
SConnection *pCon = NULL;
@@ -349,6 +366,10 @@ static void ErrWrite(char *txt)
pExe = GetExecutor();
pCon = GetExeOwner(pExe);
if (!pCon)
{
pCon = SCLoad(conn);
}
if(pCon)
{
SCWrite(pCon,txt,eWarning);
@@ -361,13 +382,17 @@ static void ErrWrite(char *txt)
/*-----------------------------------------------------------------------*/
static void ErrReport(pEVControl self)
{
float fPos, fDelta;
float fPos =.0, fDelta =.0;
char pBueffel[256];
self->pDriv->GetValues(self->pDriv,&self->fTarget,&fPos,&fDelta);
sprintf(pBueffel,"WARNING: %s is out of range by %g",self->pName,fDelta);
ErrWrite(pBueffel);
self->iWarned = 1;
if(self->iWarned == 0)
{
sprintf(pBueffel,"WARNING: %s is out of range by %g",
self->pName,fDelta);
ErrWrite(pBueffel, &self->conn);
self->iWarned = 1;
}
}
/*-------------------------------------------------------------------------*/
static int ErrLazy(void *pData)
@@ -408,6 +433,7 @@ static void ErrReport(pEVControl self)
/* OK now, continue */
SetStatus(eEager);
self->iWarned = 0;
ContinueExecution(pExe);
return 1;
}
@@ -437,20 +463,21 @@ static void ErrReport(pEVControl self)
snprintf(pBueffel,255,
"ERROR: %s while processing errorscript for %s",
pTcl->result,self->pName);
ErrWrite(pBueffel);
ErrWrite(pBueffel, &self->conn);
}
/*
assume that everything is fine again after the script
returns
*/
self->eMode = EVMonitor;
self->iWarned = 0;
}
else
{
snprintf(pBueffel,255,
"ERROR: script error handling requested for %s, but no script given",
self->pName);
ErrWrite(pBueffel);
ErrWrite(pBueffel, &self->conn);
}
return 1;
@@ -467,6 +494,7 @@ static void ErrReport(pEVControl self)
/* interrupt */
SetInterrupt((int)ObVal(self->pParam,INTERRUPT));
self->iWarned = 0;
return 1;
}
/*---------------------------------------------------------------------------*/
@@ -479,9 +507,10 @@ static void ErrReport(pEVControl self)
ErrReport(self);
ErrWrite("Running to safe value");
ErrWrite("Running to safe value", &self->conn);
self->pDriv->SetValue(self->pDriv, ObVal(self->pParam,SAFEVALUE));
self->eMode = EVIdle;
self->iWarned = 0;
return 1;
}
/*---------------------------------------------------------------------------*/
@@ -541,10 +570,11 @@ static void ErrReport(pEVControl self)
pEVControl self = NULL;
float fPos, fDelta;
int iRet, iCode, iStat;
char pError[10], pBueffel[512];
char pError[132], pBueffel[512];
pExeList pExe = NULL;
SConnection *pCon = NULL;
float tol;
self = (pEVControl)pData;
assert(self);
@@ -560,23 +590,16 @@ static void ErrReport(pEVControl self)
{
fDelta = -fDelta;
}
if(fDelta < ObVal(self->pParam,TOLERANCE))
tol = ObVal(self->pParam,TOLERANCE);
if (self->iWarned == 0) tol=tol*1.1001;
if(fDelta <= tol)
{
self->eMode = EVMonitor;
if(self->iWarned)
{
pExe = GetExecutor();
pCon = GetExeOwner(pExe);
sprintf(pBueffel,"Environment device %s back in tolerances again",
self->pName);
if(pCon)
{
SCWrite(pCon,pBueffel,eWarning);
}
else
{
ServerWriteGlobal(pBueffel,eWarning);
}
ErrWrite(pBueffel, &self->conn);
self->iWarned = 0;
}
return 1;
@@ -604,7 +627,9 @@ static void ErrReport(pEVControl self)
/* break down of connection to a environment device has to be
considered a problem as well
*/
self->pDriv->GetError(self->pDriv, &iCode,pError,9);
memset(pError,0,132*sizeof(char));
self->pDriv->GetError(self->pDriv, &iCode,pError,131);
WriteToCommandLog("emon>> ",pError);
iStat = self->pDriv->TryFixIt(self->pDriv, iCode);
if( (iStat == DEVOK) || (iStat == DEVREDO) )
{
@@ -730,23 +755,20 @@ static void ErrReport(pEVControl self)
ObParInit(pRes->pParam, ERRORHANDLER, "errorhandler", 0.0, usUser);
ObParInit(pRes->pParam, INTERRUPT, "interrupt", eContinue, usUser);
ObParInit(pRes->pParam, UPLIMIT, "upperlimit", 300.0, usUser);
ObParInit(pRes->pParam, LOWLIMIT, "lowerlimit", 2., usUser);
ObParInit(pRes->pParam, LOWLIMIT, "lowerlimit", 1.0, usUser);
ObParInit(pRes->pParam, SAFEVALUE, "safevalue", 0., usUser);
ObParInit(pRes->pParam, MAXWAIT, "maxwait", 0., usUser);
ObParInit(pRes->pParam, SETTLE, "settle", 0., usUser);
/* local initialisations */
pRes->pDriv = pDriv;
if (pDriv->GetValues==NULL) /* if GetValues is undefined, set to default */
{
pDriv->GetValues=StdGetValues;
}
iRet = pDriv->Init(pDriv);
if(iRet >= 0)
{
*iErr = iRet;
}
*iErr = iRet;
/* new var log for logging values */
pRes->iLog = 1;
if(!VarlogInit(&pRes->pLog))
@@ -758,14 +780,14 @@ static void ErrReport(pEVControl self)
pRes->pName = strdup(pName);
pRes->eMode = EVIdle;
pRes->iWarned = 0;
/* a terminal error gives a -1 in iRet */
if(iRet < 0)
{
DeleteEVController(pRes);
return NULL;
}
pRes->pDriv = pDriv; /* moved here to avoid double freeing on evfactory del */
return pRes;
}
/*---------------------------------------------------------------------------*/
@@ -779,6 +801,7 @@ static void ErrReport(pEVControl self)
if(self->pDes)
{
DeleteDescriptor(self->pDes);
self->pDes = NULL;
}
if(self->pDrivInt)
{
@@ -821,6 +844,10 @@ static void ErrReport(pEVControl self)
{
free(self->errorScript);
}
if (self->creationArgs != NULL)
{
free(self->creationArgs);
}
free(self);
}
/*--------------------------------------------------------------------------*/
@@ -1002,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;
@@ -1010,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;
@@ -1068,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);
@@ -1089,10 +1119,6 @@ static void ErrReport(pEVControl self)
}
iRet = VarlogWrapper(self->pLog,pCon,
argv[2],argv[3],argv[0]);
if(iRet)
{
SCSendOK(pCon);
}
return iRet;
}
else if( argc < 3) /* either parameter or drive */
@@ -1188,13 +1214,13 @@ static void ErrReport(pEVControl self)
strtolower(argv[1]);
if(strcmp(argv[1],"errorscript") == 0)
{
Arg2Text(argc-2,&argv[2],pBueffel,255);
if(self->errorScript != NULL)
{
free(self->errorScript);
}
self->errorScript = strdup(pBueffel);
self->errorScript = Arg2Tcl(argc-2,&argv[2],NULL,0);
SCSendOK(pCon);
SCparChange(pCon);
return 1;
}
iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&dVal);
@@ -1208,15 +1234,87 @@ static void ErrReport(pEVControl self)
if(iRet)
{
SCSendOK(pCon);
SCparChange(pCon);
}
return iRet;
}
return 0; /* not reached */
}
}
/*-----------------------------------------------------------------------*/
static int EVSaveStatus(void *pData, char *name, FILE *fil)
{
pEVControl evc = pData;
pEVDriver pD = evc->pDriv;
assert(evc);
assert(pD);
if (evc->creationArgs && pD->SavePars) {
fprintf(fil, "if {[catch { evfactory replace %s %s }] == 0} {\n", name, evc->creationArgs);
if (pD->SavePars(pD, fil) == 1) {
fprintf(fil, " %s %s %g\n",evc->pName, "tolerance", ObVal(evc->pParam,TOLERANCE));
fprintf(fil, " %s %s %g\n",evc->pName, "access", ObVal(evc->pParam,ACCESS));
fprintf(fil, " %s %s %g\n",evc->pName, "ErrorHandler", ObVal(evc->pParam,ERRORHANDLER));
fprintf(fil, " %s %s %g\n",evc->pName, "interrupt", ObVal(evc->pParam,INTERRUPT));
fprintf(fil, " %s %s %g\n",evc->pName, "UpperLimit", ObVal(evc->pParam,UPLIMIT));
fprintf(fil, " %s %s %g\n",evc->pName, "LowerLimit", ObVal(evc->pParam,LOWLIMIT));
fprintf(fil, " %s %s %g\n",evc->pName, "SafeValue", ObVal(evc->pParam,SAFEVALUE));
fprintf(fil, " %s %s %g\n",evc->pName, "MaxWait", ObVal(evc->pParam,MAXWAIT));
fprintf(fil, " %s %s %g\n",evc->pName, "Settle", ObVal(evc->pParam,SETTLE));
if(evc->errorScript != NULL) {
fprintf(fil, " %s errorScript %s\n", evc->pName, evc->errorScript);
}
}
fprintf(fil, "}\n");
}
return 1;
}
/*--------------------------------------------------------------------------*/
/* standard method for saving parameters */
static int EVCSaveStd(void *pData, char *name, FILE *fil)
{
return 1;
}
/*-----------------------------------------------------------------------*/
pEVControl MakeEVController(pEVDriver pDriv, SConnection *pCon,
ObjectFunc wrapper, int argc, char *argv[])
{
pEVControl pNew;
int status = 1;
char pBueffel[512];
char pError[132];
if (pDriv == NULL) {
SCWrite(pCon,"ERROR: failed to create driver",eError);
return NULL;
}
pNew = CreateEVController(pDriv,argv[0],&status);
if (status != 1) {
printf("CEVC error\n");
SCWrite(pCon,"ERROR: failed to initialize device", eError);
pDriv->GetError(pDriv,&status,pError,sizeof pError -1);
printf("HW %s\n", pError);
sprintf(pBueffel,"HW reported: %s",pError);
SCWrite(pCon,pBueffel,eError);
}
if (pNew == NULL) {
printf("CEVC failed\n");
SCWrite(pCon,"ERROR: failed to create environment device object",
eError);
DeleteEVDriver(pDriv);
return NULL;
}
if (wrapper == NULL) {
AddCommand(pServ->pSics,argv[0],EVControlWrapper,DeleteEVController,pNew);
} else {
AddCommand(pServ->pSics,argv[0],wrapper,DeleteEVController,pNew);
}
return pNew;
}
/*-----------------------------------------------------------------------*/
static pEVControl InstallCommonControllers(SicsInterp *pSics,
SConnection *pCon,
int argc, char *argv[])
int argc, char *argv[],
int *found)
{
pEVControl pNew = NULL;
pEVDriver pDriv = NULL;
@@ -1225,6 +1323,7 @@ static pEVControl InstallCommonControllers(SicsInterp *pSics,
int (*Wrapper)(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]) = EVControlWrapper;
*found=1;
if(strcmp(argv[3],"sim") == 0) /* SIM driver */
{
/* Create a Sim Driver */
@@ -1284,7 +1383,9 @@ static pEVControl InstallCommonControllers(SicsInterp *pSics,
return NULL;
}
} else {
return NULL; /* not recognized */
/* not recognized */
*found=0;
return NULL;
}
@@ -1321,6 +1422,30 @@ static pEVControl InstallCommonControllers(SicsInterp *pSics,
}
return pNew;
}
int RemoveEVController(SConnection *pCon, char *name) {
char pBueffel[512];
int iRet;
if(!pServ->pExecutor)
{
return 1;
}
if(isInRunMode(pServ->pExecutor))
{
SCWrite(pCon,"ERROR: cannot delete while running",eError);
return 0;
}
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;
}
return 1;
}
/*-------------------------------------------------------------------------
EVControlFactory implements a SICS command which creates and deletes
Controllers at run-time. Syntax:
@@ -1335,7 +1460,7 @@ static pEVControl InstallCommonControllers(SicsInterp *pSics,
{
pEVControl pNew = NULL;
char pBueffel[512],pError[132];
int iRet;
int iRet, found;
CommandList *pCom = NULL;
pSite site = NULL;
@@ -1358,28 +1483,15 @@ static pEVControl InstallCommonControllers(SicsInterp *pSics,
strtolower(argv[1]);
if(strcmp(argv[1],"del") == 0) /* delete */
{
if(!pServ->pExecutor)
{
if (RemoveEVController(pCon, argv[2])) {
SCSendOK(pCon);
return 1;
}
if(isInRunMode(pServ->pExecutor))
{
SCWrite(pCon,"ERROR: cannot delete while running",eError);
return 0;
}
EVUnregister(FindEMON(pSics),argv[2]);
iRet = RemoveCommand(pSics,argv[2]);
if(!iRet)
{
sprintf(pBueffel,"ERROR: %s not found, NOT deleted",argv[2]);
SCWrite(pCon,pBueffel,eError);
} else {
return 0;
}
SCSendOK(pCon);
return 1;
}
else if(strcmp(argv[1],"new") == 0) /*make a new one */
else if(strcmp(argv[1],"new") == 0 || strcmp(argv[1], "replace") == 0)
/* make a new one */
{
/* argv[2] = name */
/* argv[3] must be type */
@@ -1391,31 +1503,50 @@ static pEVControl InstallCommonControllers(SicsInterp *pSics,
}
strtolower(argv[2]);
strtolower(argv[3]);
if (FindCommandData(pSics, argv[2], "Environment Controller")) {
if (strcmp(argv[1], "replace") == 0) {
if (!RemoveEVController(pCon, argv[2])) {
return 0;
}
} else {
sprintf(pBueffel,
"ERROR: environment device %s already installed, delete first",
argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
}
pCom = FindCommand(pSics,argv[2]);
if(pCom)
{
sprintf(pBueffel,
"ERROR: environment device %s already installed, delete first",
argv[2]);
sprintf(pBueffel, "ERROR: command %s already exists", argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
pNew = InstallCommonControllers(pSics,pCon,argc,argv);
if(pNew == NULL)
{
pNew = InstallCommonControllers(pSics,pCon,argc,argv,&found);
if (!found) {
site = getSite();
if(site != NULL){
pNew = site->InstallEnvironmentController(pSics,pCon,argc,argv);
} else {
sprintf(pBueffel,
"ERROR: %s not recognized as a valid driver type",
argv[3]);
SCWrite(pCon,pBueffel,eError);
pNew = NULL;
}
if(pNew == NULL){
sprintf(pBueffel,"ERROR: %s not recognized as a valid driver type",
argv[3]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
}
if(pNew == NULL){
/* error message is already written */
return 0;
}
if (pNew->pDriv->SavePars) {
pNew->creationArgs = Arg2Tcl(argc-3, argv+3, NULL, 0);
pNew->pDes->SaveStatus = EVSaveStatus;
} else {
pNew->creationArgs = NULL;
}
EVRegisterController(FindEMON(pSics),argv[2],pNew, pCon);
pNew->driverName = strdup(argv[3]);
SCSendOK(pCon);