PSI sics-cvs-psi-2006
This commit is contained in:
257
devexec.c
257
devexec.c
@@ -41,6 +41,7 @@
|
||||
-----------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include "fortify.h"
|
||||
#include "sics.h"
|
||||
@@ -61,6 +62,7 @@
|
||||
pObjectDescriptor pDescriptor;
|
||||
float fVal;
|
||||
char *name;
|
||||
commandContext comCon;
|
||||
} DevEntry, *pDevEntry;
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, void *pData,
|
||||
@@ -79,6 +81,7 @@
|
||||
pNew->pData = pData;
|
||||
pNew->name = strdup(name);
|
||||
pNew->fVal = fVal;
|
||||
memset(&pNew->comCon,0,sizeof(commandContext));
|
||||
return pNew;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@@ -102,9 +105,12 @@
|
||||
int iStop;
|
||||
int iStatus;
|
||||
int iEnd;
|
||||
int drivePrint;
|
||||
long lTask;
|
||||
pTaskMan pTask;
|
||||
int iLock;
|
||||
pICallBack pCall;
|
||||
time_t lastRun;
|
||||
} ExeList;
|
||||
|
||||
static pExeList pExecutor = NULL;
|
||||
@@ -139,6 +145,9 @@
|
||||
pRes->pTask = pTask;
|
||||
pRes->lTask = -1;
|
||||
pRes->iLock = 0;
|
||||
pRes->drivePrint = 0;
|
||||
pRes->pCall = CreateCallBackInterface();
|
||||
pRes->lastRun = time(NULL);
|
||||
return pRes;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@@ -153,8 +162,21 @@
|
||||
DeleteDescriptor(self->pDes);
|
||||
ClearExecutor(self);
|
||||
LLDdelete(self->iList);
|
||||
if(self->pCall)
|
||||
DeleteCallBackInterface(self->pCall);
|
||||
|
||||
free(self);
|
||||
pServ->pExecutor = NULL;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void ExeInterest(pExeList self, pDevEntry pDev, char *text) {
|
||||
char buf[128];
|
||||
|
||||
if(pDev)
|
||||
{
|
||||
snprintf(buf, sizeof(buf),"%s %s",pDev->name,text);
|
||||
InvokeCallBack(self->pCall, DRIVSTAT, buf);
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
|
||||
@@ -165,6 +187,9 @@
|
||||
char pBueffel[132], pError[80];
|
||||
pIDrivable pDrivInt = NULL;
|
||||
pICountable pCountInt = NULL;
|
||||
static int overwriteOwner = -1;
|
||||
char *overwriteOption;
|
||||
float oldVal;
|
||||
|
||||
assert(self);
|
||||
assert(pDes);
|
||||
@@ -175,9 +200,19 @@
|
||||
{
|
||||
if(pCon != self->pOwner)
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"ERROR: somebody else is still driving, Request rejected",eError);
|
||||
return 0;
|
||||
/* this hack helps on rita2, when using the sendsics script
|
||||
which opens a client for every command */
|
||||
if (overwriteOwner < 0) {
|
||||
overwriteOption = IFindOption(pSICSOptions, "overwriteOwner");
|
||||
overwriteOwner = overwriteOption && *overwriteOption != '0';
|
||||
}
|
||||
if (overwriteOwner) {
|
||||
self->pOwner = pCon;
|
||||
} else {
|
||||
SCWrite(pCon,
|
||||
"ERROR: somebody else is still driving, Request rejected",eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -198,13 +233,22 @@
|
||||
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);
|
||||
if(pDrivInt)
|
||||
{
|
||||
iRet = pDrivInt->SetValue(pData,pCon,fNew);
|
||||
if(iRet == OKOK && self->drivePrint == 1)
|
||||
{
|
||||
oldVal = pDrivInt->GetValue(pData,pCon);
|
||||
snprintf(pBueffel,131,"Driving %s from %8.3f to %8.3f",
|
||||
name, oldVal, fNew);
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
}
|
||||
}
|
||||
else if(pCountInt)
|
||||
{
|
||||
@@ -220,6 +264,12 @@
|
||||
if(iRet == OKOK)
|
||||
{
|
||||
LLDnodeAppendFrom(self->iList,&pNew);
|
||||
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 */
|
||||
@@ -232,6 +282,7 @@
|
||||
self,
|
||||
1);
|
||||
self->iEnd = 0;
|
||||
pCon->conStatus = HWBusy;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -248,6 +299,7 @@
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int StartMotor(pExeList self, SicsInterp *pSics, SConnection *pCon,
|
||||
char *name, float fVal)
|
||||
@@ -341,7 +393,11 @@
|
||||
pICountable pCountInt = NULL;
|
||||
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
|
||||
@@ -365,6 +421,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);
|
||||
|
||||
@@ -388,19 +449,27 @@
|
||||
{
|
||||
pDrivInt->iErrorCount = 0;
|
||||
}
|
||||
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;
|
||||
break;
|
||||
case HWFault: /* real HW error: burning, no net etc.. */
|
||||
ExeInterest(self, pDev, "finished with problem");
|
||||
DeleteDevEntry(pDev);
|
||||
pDev = NULL;
|
||||
SCWrite(pCon, "", eFinish);
|
||||
LLDnodeDataTo(self->iList,&pDev);
|
||||
LLDnodeDelete(self->iList);
|
||||
iRet = LLDnodePtr2Prev(self->iList);
|
||||
self->iStatus = DEVERROR;
|
||||
if(pDrivInt)
|
||||
{
|
||||
@@ -409,6 +478,7 @@
|
||||
if(SCGetInterrupt(self->pOwner) != eContinue)
|
||||
{
|
||||
self->iStatus = DEVINT;
|
||||
SCPopContext(self->pOwner);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
@@ -418,6 +488,7 @@
|
||||
{
|
||||
SetStatus(eEager);
|
||||
self->iStatus = DEVINT;
|
||||
SCPopContext(self->pOwner);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
@@ -427,27 +498,26 @@
|
||||
{
|
||||
ContinueExecution(self);
|
||||
self->iStatus = DEVINT;
|
||||
SCPopContext(self->pOwner);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case HWBusy:
|
||||
if(pCountInt != NULL && pDrivInt != NULL)
|
||||
if(pDrivInt != NULL)
|
||||
{
|
||||
SetStatus(eCountDrive);
|
||||
isDriving = 1;
|
||||
}
|
||||
else if(pCountInt != NULL && pDrivInt == NULL)
|
||||
{
|
||||
SetStatus(eCounting);
|
||||
}
|
||||
else if(pDrivInt != NULL && pCountInt == NULL)
|
||||
else if(pCountInt != NULL)
|
||||
{
|
||||
SetStatus(eDriving);
|
||||
isCounting = 1;
|
||||
}
|
||||
self->iStatus = DEVBUSY;
|
||||
break;
|
||||
case HWPosFault: /* cannot get somewhere... */
|
||||
ExeInterest(self, pDev, "finished with problem");
|
||||
DeleteDevEntry(pDev);
|
||||
LLDnodeDelete(self->iList);
|
||||
SCWrite(pCon, "", eFinish);
|
||||
self->iStatus = DEVERROR;
|
||||
if(pDrivInt)
|
||||
{
|
||||
@@ -456,14 +526,26 @@
|
||||
if(SCGetInterrupt(self->pOwner) != eContinue)
|
||||
{
|
||||
self->iStatus = DEVINT;
|
||||
SCPopContext(self->pOwner);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
SCPopContext(self->pOwner);
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self->iList);
|
||||
}
|
||||
|
||||
if (isCounting) {
|
||||
if (isDriving) {
|
||||
SetStatus(eCountDrive);
|
||||
} else {
|
||||
SetStatus(eCounting);
|
||||
}
|
||||
} else if (isDriving) {
|
||||
SetStatus(eDriving);
|
||||
}
|
||||
|
||||
iRet = LLDnodePtr2First(self->iList);
|
||||
if(LLDcheck(self->iList) == LIST_EMPTY)
|
||||
{
|
||||
@@ -484,12 +566,11 @@
|
||||
int iRet;
|
||||
assert(self);
|
||||
|
||||
self->iRun = 0;
|
||||
|
||||
/* do nothing if not running */
|
||||
if(self->lTask < 0)
|
||||
{
|
||||
printf("Nothing to wait for....\n");
|
||||
printf("Nothing to wait for.... \n");
|
||||
self->iRun = 0; /* not sure if this is needed here, but does not harm */
|
||||
return self->iStatus;
|
||||
}
|
||||
|
||||
@@ -498,6 +579,7 @@
|
||||
#ifdef DEBUG
|
||||
printf("Wait4Success finished\n");
|
||||
#endif
|
||||
self->iRun = 0;
|
||||
return self->iStatus;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -561,23 +643,23 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
check for stop flag. This is to stop unnecessary calls to StopExe.
|
||||
There may be way to many, but each call is reasonable under certain
|
||||
circumstances.
|
||||
*/
|
||||
if(self->iStop == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->iStop = 1;
|
||||
}
|
||||
|
||||
/* first the ALL case */
|
||||
if(strcmp(name,"all") == 0)
|
||||
{
|
||||
/*
|
||||
check for stop flag. This is to stop unnecessary calls to StopExe.
|
||||
There may be way to many, but each call is reasonable under certain
|
||||
circumstances.
|
||||
*/
|
||||
if(self->iStop == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->iStop = 1;
|
||||
}
|
||||
|
||||
iRet = LLDnodePtr2First(self->iList);
|
||||
while(iRet != 0)
|
||||
{
|
||||
@@ -597,7 +679,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;
|
||||
@@ -622,7 +706,7 @@
|
||||
}
|
||||
else if(pCountInt)
|
||||
{
|
||||
pDrivInt->Halt(pDev->pData);
|
||||
pCountInt->Halt(pDev->pData);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -655,6 +739,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)
|
||||
{
|
||||
@@ -665,7 +751,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
SCPopContext(self->pOwner);
|
||||
iRet = LLDnodePtr2Next(self->iList);
|
||||
}
|
||||
SetStatus(ePaused);
|
||||
@@ -691,7 +778,6 @@
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self->iList);
|
||||
}
|
||||
@@ -716,11 +802,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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -796,13 +884,68 @@
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
}
|
||||
/*------------------- The CallBack function for interest ------------------*/
|
||||
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;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int ListExe(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
return ListPending((pExeList)pData,pCon);
|
||||
pExeList self = NULL;
|
||||
int list;
|
||||
|
||||
if (argc == 1) {
|
||||
return ListPending((pExeList)pData,pCon);
|
||||
}
|
||||
argtolower(argc,argv);
|
||||
self = (pExeList)pData;
|
||||
assert(self);
|
||||
if (argc == 2) {
|
||||
if (strcmp(argv[1], "interest") == 0)
|
||||
{
|
||||
list = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||
DRIVSTAT, DrivStatCallback,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon, pSics, self->pCall,list);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(argv[1], "uninterest") == 0)
|
||||
{
|
||||
RemoveCallback2(self->pCall, pCon);
|
||||
SCUnregister(pCon, self->pCall);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
SCWrite(pCon, "ERROR: illegal arguments for ListExe", eError);
|
||||
return 0;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int SicsIdle(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
pExeList self = NULL;
|
||||
int idle;
|
||||
char pBueffel[80];
|
||||
|
||||
self = (pExeList)pData;
|
||||
assert(self);
|
||||
idle = time(NULL) - self->lastRun;
|
||||
snprintf(pBueffel,79,"sicsidle = %d",idle);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------
|
||||
Usage:
|
||||
Success
|
||||
@@ -830,7 +973,7 @@
|
||||
SCWrite(pCon,"All done",eStatus);
|
||||
iRet = 1;
|
||||
}
|
||||
else if(iRet = DEVERROR)
|
||||
else if(iRet == DEVERROR)
|
||||
{
|
||||
SCWrite(pCon,"Finished with Problems",eStatus);
|
||||
iRet = 1;
|
||||
@@ -856,6 +999,39 @@
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
int val;
|
||||
char pBueffel[256];
|
||||
|
||||
pExeList self = (pExeList)pData;
|
||||
if(argc < 2)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: not enough argumentd to devexec command",eError);
|
||||
return 0;
|
||||
}
|
||||
strtolower(argv[1]);
|
||||
if(strcmp(argv[1],"driveprint") == 0)
|
||||
{
|
||||
if(argc > 2 && SCMatchRights(pCon,usUser))
|
||||
{
|
||||
val = atoi(argv[2]);
|
||||
self->drivePrint = val;
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
} else {
|
||||
snprintf(pBueffel,255,"devexe.drivePrint = %d",
|
||||
self->drivePrint);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: unknown subcommand to devexec",eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int ContinueAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
@@ -920,6 +1096,7 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
self->lastRun = time(NULL);
|
||||
iRet = CheckExeList(self);
|
||||
switch(iRet)
|
||||
{
|
||||
@@ -927,12 +1104,8 @@
|
||||
iInterrupt = SCGetInterrupt(self->pOwner);
|
||||
if(iInterrupt != eContinue)
|
||||
{
|
||||
SCWrite(self->pOwner,pBueffel, eError);
|
||||
if(iInterrupt > 1)
|
||||
{
|
||||
Interrupt2Text(iInterrupt,pInterrupt,79);
|
||||
snprintf(pBueffel,131,"ERROR: interrupt %s triggered",
|
||||
pInterrupt);
|
||||
StopExe(self,"all");
|
||||
}
|
||||
#ifdef DEBUG
|
||||
@@ -976,10 +1149,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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user