- Reworked the connection object and the IO system

- Reworked the support for TRICS
- Added a second generation motor
This commit is contained in:
koennecke
2009-02-03 08:05:39 +00:00
parent f6d595665e
commit 361ee9ebea
119 changed files with 16455 additions and 3674 deletions

288
devexec.c
View File

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