- Reworked the connection object and the IO system
- Reworked the support for TRICS - Added a second generation motor
This commit is contained in:
288
devexec.c
288
devexec.c
@ -12,6 +12,9 @@
|
||||
Refactored and instrumentation for instrument staticstics added.
|
||||
Mark Koennecke, July 2006
|
||||
|
||||
Reworked to use copied connection objects instead of context pushes.
|
||||
Mark Koennecke, January 2009
|
||||
|
||||
Copyright:
|
||||
|
||||
Labor fuer Neutronenstreuung
|
||||
@ -113,7 +116,7 @@ void DevexecLog(char *operation, char *device) {
|
||||
pObjectDescriptor pDescriptor;
|
||||
float fVal;
|
||||
char *name;
|
||||
commandContext comCon;
|
||||
SConnection *pCon;
|
||||
} DevEntry, *pDevEntry;
|
||||
/*------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
@ -123,7 +126,8 @@ typedef struct {
|
||||
pIDrivable pDrivInt;
|
||||
}checkContext, *pCheckContext;
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, void *pData,
|
||||
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, SConnection *pCon,
|
||||
void *pData,
|
||||
float fVal, char *name)
|
||||
{
|
||||
pDevEntry pNew = NULL;
|
||||
@ -139,7 +143,7 @@ typedef struct {
|
||||
pNew->pData = pData;
|
||||
pNew->name = strdup(name);
|
||||
pNew->fVal = fVal;
|
||||
memset(&pNew->comCon,0,sizeof(commandContext));
|
||||
pNew->pCon = SCCopyConnection(pCon);
|
||||
return pNew;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@ -151,9 +155,11 @@ typedef struct {
|
||||
{
|
||||
free(self->name);
|
||||
}
|
||||
if(self->pCon){
|
||||
SCDeleteConnection(self->pCon);
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
|
||||
/* ----------------- The Executor himself ---------------------------------*/
|
||||
typedef struct __EXELIST{
|
||||
pObjectDescriptor pDes;
|
||||
@ -242,6 +248,11 @@ typedef struct {
|
||||
if(self->pCall)
|
||||
DeleteCallBackInterface(self->pCall);
|
||||
|
||||
if(self->pOwner){
|
||||
SCDeleteConnection(self->pOwner);
|
||||
self->pOwner = NULL;
|
||||
}
|
||||
|
||||
free(self);
|
||||
pServ->pExecutor = NULL;
|
||||
if(devLog != NULL){
|
||||
@ -279,7 +290,7 @@ typedef struct {
|
||||
/* may we? */
|
||||
if(self->pOwner != NULL)
|
||||
{
|
||||
if(pCon != self->pOwner)
|
||||
if(pCon->ident != self->pOwner->ident)
|
||||
{
|
||||
/* this hack helps on rita2, when using the sendsics script
|
||||
which opens a client for every command */
|
||||
@ -288,7 +299,8 @@ typedef struct {
|
||||
overwriteOwner = overwriteOption && *overwriteOption != '0';
|
||||
}
|
||||
if (overwriteOwner) {
|
||||
self->pOwner = pCon;
|
||||
SCDeleteConnection(self->pOwner);
|
||||
self->pOwner = SCCopyConnection(pCon);
|
||||
} else {
|
||||
SCWrite(pCon,
|
||||
"ERROR: somebody else is still driving, Request rejected",eError);
|
||||
@ -298,7 +310,7 @@ typedef struct {
|
||||
}
|
||||
else
|
||||
{
|
||||
self->pOwner = pCon;
|
||||
self->pOwner = SCCopyConnection(pCon);
|
||||
}
|
||||
if(self->iLock == 1)
|
||||
{
|
||||
@ -308,14 +320,12 @@ typedef struct {
|
||||
|
||||
/* well create a new entry */
|
||||
self->iStop = 0;
|
||||
pNew = CreateDevEntry(pDes,pData,fNew,name);
|
||||
pNew = CreateDevEntry(pDes,pCon,pData,fNew,name);
|
||||
if(!pNew)
|
||||
{
|
||||
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);
|
||||
@ -328,7 +338,7 @@ typedef struct {
|
||||
oldVal = pDrivInt->GetValue(pData,pCon);
|
||||
snprintf(pBueffel,131,"Driving %s from %8.3f to %8.3f",
|
||||
name, oldVal, fNew);
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
}
|
||||
}
|
||||
else if(pCountInt)
|
||||
@ -346,9 +356,9 @@ typedef struct {
|
||||
{
|
||||
LLDnodeAppendFrom(self->iList,&pNew);
|
||||
sprintf(pBueffel,"started");
|
||||
if(NULL!=pNew->comCon.deviceID)
|
||||
if(NULL!=pNew->pCon->deviceID)
|
||||
{
|
||||
snprintf(pBueffel,130,"started (%s)",pNew->comCon.deviceID);
|
||||
snprintf(pBueffel,130,"started (%s)",pNew->pCon->deviceID);
|
||||
}
|
||||
ExeInterest(self, pNew, pBueffel);
|
||||
self->iRun = 1;
|
||||
@ -375,13 +385,15 @@ typedef struct {
|
||||
DeleteDevEntry(pNew);
|
||||
if(LLDcheck(self->iList) >= LIST_EMPTY)
|
||||
{
|
||||
if(self->pOwner != NULL){
|
||||
SCDeleteConnection(self->pOwner);
|
||||
}
|
||||
self->pOwner = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int StartMotor(pExeList self, SicsInterp *pSics, SConnection *pCon,
|
||||
char *name, float fVal)
|
||||
@ -467,183 +479,10 @@ typedef struct {
|
||||
return StartDevice(self,name,pCter->pDes,(void *)pCter,
|
||||
pCon,pCter->pDriv->fPreset);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int CheckExeListOld(pExeList self)
|
||||
{
|
||||
int iRet;
|
||||
pDevEntry pDev = NULL;
|
||||
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
|
||||
cases where this is feasible for maintainance, but in some cases it
|
||||
is pure rubbish, because nothing runs. This will be checked here.
|
||||
*/
|
||||
if((self->pOwner == NULL) || (LLDcheck(self->iList) == LIST_EMPTY))
|
||||
{
|
||||
self->iRun = 0;
|
||||
self->iEnd = 1;
|
||||
self->iStop = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
check the status of all registered devices. Remove when finished
|
||||
*/
|
||||
iRet = LLDnodePtr2First(self->iList);
|
||||
while(iRet != 0)
|
||||
{
|
||||
LLDnodeDataTo(self->iList,&pDev);
|
||||
if(pDev)
|
||||
{
|
||||
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
|
||||
|
||||
pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
|
||||
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
|
||||
|
||||
if(pDrivInt)
|
||||
{
|
||||
eCode = pDrivInt->CheckStatus(pDev->pData,self->pOwner);
|
||||
}
|
||||
else if(pCountInt)
|
||||
{
|
||||
eCode = pCountInt->CheckCountStatus(pDev->pData,self->pOwner);
|
||||
}
|
||||
switch(eCode)
|
||||
{
|
||||
case HWIdle:
|
||||
case OKOK:
|
||||
if(pCountInt)
|
||||
{
|
||||
pCountInt->TransferData(pDev->pData,self->pOwner);
|
||||
}
|
||||
else if(pDrivInt)
|
||||
{
|
||||
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)
|
||||
{
|
||||
pDrivInt->iErrorCount++;
|
||||
}
|
||||
if(SCGetInterrupt(self->pOwner) != eContinue)
|
||||
{
|
||||
self->iStatus = DEVINT;
|
||||
SCPopContext(self->pOwner);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case HWNoBeam:
|
||||
SetStatus(eOutOfBeam);
|
||||
if(SCGetInterrupt(self->pOwner) != eContinue)
|
||||
{
|
||||
SetStatus(eEager);
|
||||
self->iStatus = DEVINT;
|
||||
SCPopContext(self->pOwner);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case HWPause:
|
||||
SetStatus(ePaused);
|
||||
if(SCGetInterrupt(self->pOwner) != eContinue)
|
||||
{
|
||||
ContinueExecution(self);
|
||||
self->iStatus = DEVINT;
|
||||
SCPopContext(self->pOwner);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case HWBusy:
|
||||
if(pDrivInt != NULL)
|
||||
{
|
||||
isDriving = 1;
|
||||
}
|
||||
else if(pCountInt != NULL)
|
||||
{
|
||||
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)
|
||||
{
|
||||
pDrivInt->iErrorCount++;
|
||||
}
|
||||
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)
|
||||
{
|
||||
self->pOwner = NULL;
|
||||
self->iEnd = 1;
|
||||
self->iRun = 0;
|
||||
self->lTask = -1;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int checkInterrupt(pCheckContext pCheck, int targetStatus){
|
||||
if(SCGetInterrupt(pCheck->self->pOwner) != eContinue) {
|
||||
pCheck->self->iStatus = DEVINT;
|
||||
SCPopContext(pCheck->self->pOwner);
|
||||
SetStatus(eEager);
|
||||
return -1;
|
||||
} else {
|
||||
@ -654,15 +493,13 @@ static int checkInterrupt(pCheckContext pCheck, int targetStatus){
|
||||
static int initializeCheck(pCheckContext pCheck, pDevEntry pDev){
|
||||
int eCode = HWFault;
|
||||
|
||||
SCPushContext(pCheck->self->pOwner,
|
||||
pDev->comCon.transID, pDev->comCon.deviceID);
|
||||
pCheck->pDev = pDev;
|
||||
pCheck->pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
|
||||
pCheck->pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
|
||||
if(pCheck->pDrivInt != NULL){
|
||||
eCode = pCheck->pDrivInt->CheckStatus(pDev->pData,pCheck->self->pOwner);
|
||||
eCode = pCheck->pDrivInt->CheckStatus(pDev->pData,pDev->pCon);
|
||||
} else if(pCheck->pCountInt != NULL) {
|
||||
eCode = pCheck->pCountInt->CheckCountStatus(pDev->pData,pCheck->self->pOwner);
|
||||
eCode = pCheck->pCountInt->CheckCountStatus(pDev->pData,pDev->pCon);
|
||||
}
|
||||
return eCode;
|
||||
}
|
||||
@ -671,7 +508,7 @@ static int finishDevice(pCheckContext pCheck){
|
||||
int status;
|
||||
|
||||
if(pCheck->pCountInt != NULL) {
|
||||
pCheck->pCountInt->TransferData(pCheck->pDev->pData,pCheck->self->pOwner);
|
||||
pCheck->pCountInt->TransferData(pCheck->pDev->pData,pCheck->pDev->pCon);
|
||||
} else if(pCheck->pDrivInt != NULL) {
|
||||
pCheck->pDrivInt->iErrorCount = 0;
|
||||
}
|
||||
@ -704,6 +541,9 @@ static int errorDevice(pCheckContext pCheck){
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int testFinish(pExeList self){
|
||||
if((self->pOwner == NULL) || (LLDcheck(self->iList) == LIST_EMPTY)) {
|
||||
if(self->pOwner != NULL){
|
||||
SCDeleteConnection(self->pOwner);
|
||||
}
|
||||
self->pOwner = NULL;
|
||||
self->iRun = 0;
|
||||
self->iEnd = 1;
|
||||
@ -725,8 +565,6 @@ static int testFinish(pExeList self){
|
||||
int eCode;
|
||||
int isCounting=0, isDriving=0;
|
||||
char pBueffel[512];
|
||||
SConnection *pCon;
|
||||
pCon = self->pOwner;
|
||||
|
||||
assert(self);
|
||||
|
||||
@ -812,7 +650,6 @@ static int testFinish(pExeList self){
|
||||
}
|
||||
break;
|
||||
}
|
||||
SCPopContext(self->pOwner);
|
||||
}
|
||||
status = LLDnodePtr2Next(self->iList);
|
||||
}
|
||||
@ -866,12 +703,12 @@ static int testFinish(pExeList self){
|
||||
iRet = CheckExeList(self);
|
||||
if(iRet == 1) /* nothing to do! */
|
||||
{
|
||||
SCWrite(pCon,"Machine idle",eStatus);
|
||||
SCWrite(pCon,"Machine idle",eValue);
|
||||
return 1;
|
||||
}
|
||||
else if(iRet == -1)
|
||||
{
|
||||
SCWrite(pCon,"Handling Interrupt",eStatus);
|
||||
SCWrite(pCon,"Handling Interrupt",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -884,7 +721,7 @@ static int testFinish(pExeList self){
|
||||
if(pDev)
|
||||
{
|
||||
sprintf(pBueffel,"\t%s %f",pDev->name,pDev->fVal);
|
||||
SCWrite(pCon,pBueffel,eStatus);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self->iList);
|
||||
}
|
||||
@ -949,9 +786,7 @@ static int testFinish(pExeList self){
|
||||
}
|
||||
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;
|
||||
@ -1009,12 +844,10 @@ static int testFinish(pExeList self){
|
||||
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)
|
||||
{
|
||||
iRet = pCountInt->Pause(pDev->pData,self->pOwner);
|
||||
iRet = pCountInt->Pause(pDev->pData,pDev->pCon);
|
||||
if(!iRet)
|
||||
{
|
||||
iRes = 0;
|
||||
@ -1022,7 +855,6 @@ static int testFinish(pExeList self){
|
||||
}
|
||||
|
||||
}
|
||||
SCPopContext(self->pOwner);
|
||||
iRet = LLDnodePtr2Next(self->iList);
|
||||
}
|
||||
SetStatus(ePaused);
|
||||
@ -1072,13 +904,11 @@ static int testFinish(pExeList self){
|
||||
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);
|
||||
iRet = pCountInt->Continue(pDev->pData,pDev->pCon);
|
||||
if(!iRet)
|
||||
{
|
||||
iRes = 0;
|
||||
}
|
||||
SCPopContext(self->pOwner);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1113,6 +943,7 @@ static int testFinish(pExeList self){
|
||||
{
|
||||
self->iStatus = DEVINT;
|
||||
}
|
||||
SCDeleteConnection(self->pOwner);
|
||||
}
|
||||
self->pOwner = NULL;
|
||||
self->iEnd = 1;
|
||||
@ -1156,15 +987,17 @@ static int testFinish(pExeList self){
|
||||
return iRet;
|
||||
}
|
||||
/*------------------- The CallBack function for interest ------------------*/
|
||||
static int DrivStatCallback(int iEvent, void *text, void *pCon,
|
||||
commandContext cc)
|
||||
static int DrivStatCallback(int iEvent, void *text, void *pCon)
|
||||
{
|
||||
assert(pCon);
|
||||
assert(text);
|
||||
|
||||
SCPushContext2(pCon,cc);
|
||||
SCWrite(pCon, text, eValue);
|
||||
SCPopContext(pCon);
|
||||
SConnection *con = (SConnection *)pCon;
|
||||
|
||||
if(con == NULL || !SCisConnected(con))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
SCWrite(pCon, text, eLog);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@ -1183,17 +1016,15 @@ static int testFinish(pExeList self){
|
||||
if (argc == 2) {
|
||||
if (strcmp(argv[1], "interest") == 0)
|
||||
{
|
||||
list = RegisterCallback(self->pCall, SCGetContext(pCon),
|
||||
list = RegisterCallback(self->pCall,
|
||||
DRIVSTAT, DrivStatCallback,
|
||||
pCon, NULL);
|
||||
SCRegister(pCon, pSics, self->pCall,list);
|
||||
SCCopyConnection(pCon), NULL);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(argv[1], "uninterest") == 0)
|
||||
{
|
||||
RemoveCallback2(self->pCall, pCon);
|
||||
SCUnregister(pCon, self->pCall);
|
||||
{
|
||||
RemoveCallbackCon(self->pCall,pCon);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
@ -1240,12 +1071,12 @@ static int testFinish(pExeList self){
|
||||
}
|
||||
else if(iRet == DEVDONE)
|
||||
{
|
||||
SCWrite(pCon,"All done",eStatus);
|
||||
SCWrite(pCon,"All done",eValue);
|
||||
iRet = 1;
|
||||
}
|
||||
else if(iRet == DEVERROR)
|
||||
{
|
||||
SCWrite(pCon,"Finished with Problems",eStatus);
|
||||
SCWrite(pCon,"Finished with Problems",eValue);
|
||||
iRet = 1;
|
||||
}
|
||||
SetStatus(eEager);
|
||||
@ -1422,6 +1253,7 @@ static int testFinish(pExeList self){
|
||||
{
|
||||
int *iInt;
|
||||
pExeList self = NULL;
|
||||
SConnection *pCon = NULL;
|
||||
|
||||
self = (pExeList)pEL;
|
||||
assert(self);
|
||||
@ -1433,12 +1265,16 @@ static int testFinish(pExeList self){
|
||||
{
|
||||
if(self->pOwner)
|
||||
{
|
||||
SCPushContext(self->pOwner,0,"system");
|
||||
SCWrite(self->pOwner,
|
||||
pCon = SCCopyConnection(self->pOwner);
|
||||
if(pCon != NULL){
|
||||
pCon->transID = 0;
|
||||
strcpy(pCon->deviceID,"system");
|
||||
SCWrite(pCon,
|
||||
"ERROR: Interrupting Current Hardware Operation",
|
||||
eError);
|
||||
SCSetInterrupt(self->pOwner,*iInt);
|
||||
SCPopContext(self->pOwner);
|
||||
SCSetInterrupt(pCon,*iInt);
|
||||
SCDeleteConnection(pCon);
|
||||
}
|
||||
}
|
||||
StopExe(self,"all");
|
||||
}
|
||||
@ -1456,7 +1292,7 @@ void UnlockDeviceExecutor(pExeList self)
|
||||
assert(self);
|
||||
self->iLock = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user