Commit e6374e07 authored by claes's avatar claes

Added i/o swap-method to avoid stall during warm restart

parent a8395fd3
/* /*
* Proview $Id: rt_io_base.c,v 1.22 2007-01-30 07:02:32 claes Exp $ * Proview $Id: rt_io_base.c,v 1.23 2007-05-18 12:05:12 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB. * Copyright (C) 2005 SSAB Oxelsund AB.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -74,7 +74,8 @@ static pwr_tStatus io_trv_child( ...@@ -74,7 +74,8 @@ static pwr_tStatus io_trv_child(
pwr_tStatus (* func) (), pwr_tStatus (* func) (),
void *arg1, void *arg1,
void *arg2, void *arg2,
int arg3); int arg3,
int arg4);
static pwr_tStatus io_replace_symbol( pwr_sAttrRef *chan, pwr_sAttrRef *sig) static pwr_tStatus io_replace_symbol( pwr_sAttrRef *chan, pwr_sAttrRef *sig)
{ {
...@@ -1256,7 +1257,8 @@ static pwr_tStatus io_FindMethods( ...@@ -1256,7 +1257,8 @@ static pwr_tStatus io_FindMethods(
pwr_tStatus (** Init) (), pwr_tStatus (** Init) (),
pwr_tStatus (** Close) (), pwr_tStatus (** Close) (),
pwr_tStatus (** Read) (), pwr_tStatus (** Read) (),
pwr_tStatus (** Write) () pwr_tStatus (** Write) (),
pwr_tStatus (** Swap) ()
) )
{ {
int found; int found;
...@@ -1279,9 +1281,11 @@ static pwr_tStatus io_FindMethods( ...@@ -1279,9 +1281,11 @@ static pwr_tStatus io_FindMethods(
*Read = 0; *Read = 0;
if ( Write) if ( Write)
*Write = 0; *Write = 0;
if ( Swap)
*Swap = 0;
for ( k = 0; k < 4; k++) { for ( k = 0; k < 5; k++) {
// Init, Close, Read, Write loop // Init, Close, Read, Write, Swap loop
cid = class; cid = class;
next = 0; next = 0;
while ( 1) { while ( 1) {
...@@ -1318,6 +1322,9 @@ static pwr_tStatus io_FindMethods( ...@@ -1318,6 +1322,9 @@ static pwr_tStatus io_FindMethods(
case 3: case 3:
strcat( methodobject, "Write"); strcat( methodobject, "Write");
break; break;
case 4:
strcat( methodobject, "Swap");
break;
} }
sts = gdh_GetObjectInfo( methodobject, &info, sizeof(info)); sts = gdh_GetObjectInfo( methodobject, &info, sizeof(info));
...@@ -1397,6 +1404,10 @@ static pwr_tStatus io_FindMethods( ...@@ -1397,6 +1404,10 @@ static pwr_tStatus io_FindMethods(
if ( Write) if ( Write)
*Write = method; *Write = method;
break; break;
case 4:
if ( Swap)
*Swap = method;
break;
} }
} }
if ( !found) if ( !found)
...@@ -1412,7 +1423,8 @@ static pwr_tStatus io_init_card( ...@@ -1412,7 +1423,8 @@ static pwr_tStatus io_init_card(
pwr_tObjid objid, pwr_tObjid objid,
io_tCtx ctx, io_tCtx ctx,
io_sRack *rp, io_sRack *rp,
int agent_type) int agent_type,
int swap)
{ {
pwr_tStatus sts; pwr_tStatus sts;
pwr_tClassId class; pwr_tClassId class;
...@@ -1420,6 +1432,7 @@ static pwr_tStatus io_init_card( ...@@ -1420,6 +1432,7 @@ static pwr_tStatus io_init_card(
pwr_tStatus (* CardClose) (); pwr_tStatus (* CardClose) ();
pwr_tStatus (* CardRead) (); pwr_tStatus (* CardRead) ();
pwr_tStatus (* CardWrite) (); pwr_tStatus (* CardWrite) ();
pwr_tStatus (* CardSwap) ();
pwr_tAName cname; pwr_tAName cname;
pwr_tAName attrname; pwr_tAName attrname;
pwr_tUInt32 process = 0; pwr_tUInt32 process = 0;
...@@ -1450,9 +1463,9 @@ static pwr_tStatus io_init_card( ...@@ -1450,9 +1463,9 @@ static pwr_tStatus io_init_card(
if ( io_CheckClassIoType( io_eType_Card, class)) { if ( io_CheckClassIoType( io_eType_Card, class)) {
sts = io_FindMethods( class, io_eType_Card, sts = io_FindMethods( class, io_eType_Card,
&CardInit, &CardClose, &CardRead, &CardWrite); &CardInit, &CardClose, &CardRead, &CardWrite, &CardSwap);
if ( ODD(sts)) { if ( ODD(sts)) {
if ( CardInit != NULL || CardClose != NULL || CardRead != NULL || CardWrite != NULL) { if ( CardInit != NULL || CardClose != NULL || CardRead != NULL || CardWrite != NULL || CardSwap != NULL) {
/* This is a card object */ /* This is a card object */
/* Check if the rack should be handled by this process */ /* Check if the rack should be handled by this process */
...@@ -1464,8 +1477,8 @@ static pwr_tStatus io_init_card( ...@@ -1464,8 +1477,8 @@ static pwr_tStatus io_init_card(
strcpy( attrname, cname); strcpy( attrname, cname);
strcat( attrname, ".Process"); strcat( attrname, ".Process");
sts = gdh_GetObjectInfo( attrname, &process, sizeof(process)); sts = gdh_GetObjectInfo( attrname, &process, sizeof(process));
if ( (EVEN(sts) && ctx->Process == io_mProcess_User) || if ( ((EVEN(sts) && ctx->Process == io_mProcess_User) ||
(ODD(sts) && ctx->Process == (int) process)) { (ODD(sts) && ctx->Process == (int) process)) && !swap) {
if ( process == io_mProcess_Plc) { if ( process == io_mProcess_Plc) {
/* Check thread also */ /* Check thread also */
strcpy( attrname, cname); strcpy( attrname, cname);
...@@ -1477,6 +1490,9 @@ static pwr_tStatus io_init_card( ...@@ -1477,6 +1490,9 @@ static pwr_tStatus io_init_card(
else else
ok = 1; ok = 1;
} }
else if (ODD(sts) && swap && CardSwap != NULL) {
ok = 1;
}
if ( ok) { if ( ok) {
/* Tread this card in this process */ /* Tread this card in this process */
...@@ -1500,14 +1516,25 @@ static pwr_tStatus io_init_card( ...@@ -1500,14 +1516,25 @@ static pwr_tStatus io_init_card(
cp->Local = NULL; cp->Local = NULL;
cp->Objid = objid; cp->Objid = objid;
strcpy( cp->Name, cname); strcpy( cp->Name, cname);
if ( CardRead != NULL) if (!swap) {
cp->Action |= io_mAction_Read; if ( CardRead != NULL)
if ( CardWrite != NULL) cp->Action |= io_mAction_Read;
cp->Action |= io_mAction_Write; if ( CardWrite != NULL)
cp->Init = CardInit; cp->Action |= io_mAction_Write;
cp->Close = CardClose; cp->Init = CardInit;
cp->Read = CardRead; cp->Close = CardClose;
cp->Write = CardWrite; cp->Read = CardRead;
cp->Write = CardWrite;
cp->Swap = CardSwap;
} else {
if ( CardSwap != NULL)
cp->Action |= io_mAction_Swap;
cp->Init = NULL;
cp->Close = CardClose;
cp->Read = NULL;
cp->Write = NULL;
cp->Swap = CardSwap;
}
if ( agent_type == io_eType_Agent) if ( agent_type == io_eType_Agent)
cp->AgentControlled = 1; cp->AgentControlled = 1;
memset( &attrref, 0, sizeof(attrref)); memset( &attrref, 0, sizeof(attrref));
...@@ -1531,335 +1558,337 @@ static pwr_tStatus io_init_card( ...@@ -1531,335 +1558,337 @@ static pwr_tStatus io_init_card(
} }
/* Fill in the channel and signal lists */ /* Fill in the channel and signal lists */
/* Find children */
sts = gdh_GetChild( objid, &chan);
while( ODD(sts)) {
memset( &attrref, 0, sizeof(attrref));
attrref.Objid = chan;
sts = gdh_DLRefObjectInfoAttrref( &attrref, (void *) &chan_op, &chandlid);
if ( EVEN(sts)) return sts;
sts = gdh_GetObjectClass( chan, &class);
if ( EVEN(sts)) return sts;
switch ( class) {
case pwr_cClass_ChanAi:
sigchancon = ((pwr_sClass_ChanAi *) chan_op)->SigChanCon;
number = ((pwr_sClass_ChanAi *) chan_op)->Number;
break;
case pwr_cClass_ChanAit:
sigchancon = ((pwr_sClass_ChanAit *) chan_op)->SigChanCon;
number = ((pwr_sClass_ChanAit *) chan_op)->Number;
break;
case pwr_cClass_ChanAo:
sigchancon = ((pwr_sClass_ChanAo *) chan_op)->SigChanCon;
number = ((pwr_sClass_ChanAo *) chan_op)->Number;
break;
case pwr_cClass_ChanDo:
sigchancon = ((pwr_sClass_ChanDo *) chan_op)->SigChanCon;
number = ((pwr_sClass_ChanDo *) chan_op)->Number;
break;
case pwr_cClass_ChanDi:
sigchancon = ((pwr_sClass_ChanDi *) chan_op)->SigChanCon;
number = ((pwr_sClass_ChanDi *) chan_op)->Number;
break;
case pwr_cClass_ChanIi:
sigchancon = ((pwr_sClass_ChanIi *) chan_op)->SigChanCon;
number = ((pwr_sClass_ChanIi *) chan_op)->Number;
break;
case pwr_cClass_ChanIo:
sigchancon = ((pwr_sClass_ChanIo *) chan_op)->SigChanCon;
number = ((pwr_sClass_ChanIo *) chan_op)->Number;
break;
case pwr_cClass_ChanCo:
sigchancon = ((pwr_sClass_ChanCo *) chan_op)->SigChanCon;
number = ((pwr_sClass_ChanCo *) chan_op)->Number;
break;
default:
sts = gdh_DLUnrefObjectInfo( chandlid);
sts = gdh_GetNextSibling( chan, &chan);
continue;
}
child_found = 1;
chan_cnt++;
if ( !fix_channels && chan_cnt > maxchan) {
errh_Error( "IO init error: max number of channels exceeded %s, chan nr %d",
cp->Name, chan_cnt);
sts = gdh_DLUnrefObjectInfo( chandlid);
break;
}
if ( fix_channels && (int) number > maxchan-1) {
/* Number out of range */
errh_Error( "IO init error: number out of range %s, chan nr %d",
cp->Name, number);
sts = gdh_DLUnrefObjectInfo( chandlid);
sts = gdh_GetNextSibling( chan, &chan);
continue;
}
/* Find signal */
sig_found = 1;
if ( cdh_ObjidIsNull( sigchancon.Objid)) {
/* Not connected */
sig_found = 0;
}
if ( sig_found) {
sts = gdh_GetAttrRefTid( &sigchancon, &sigclass);
if ( EVEN(sts))
sig_found = 0;
}
if ( sig_found) {
sts = gdh_DLRefObjectInfoAttrref( &sigchancon, (void *) &sig_op, &sigdlid);
if ( EVEN(sts))
sig_found = 0;
}
if ( fix_channels && !sig_found) { if (!swap) {
sts = gdh_DLUnrefObjectInfo( chandlid);
sts = gdh_GetNextSibling( chan, &chan);
continue;
}
if ( fix_channels)
idx = number;
else
idx = chan_cnt - 1;
/* Insert */
chanp = &cp->chanlist[idx];
chanp->cop = chan_op;
chanp->ChanDlid = chandlid;
chanp->ChanAref = cdh_ObjidToAref(chan);
chanp->ChanClass = class;
if ( sig_found) {
chanp->sop = sig_op;
chanp->SigDlid = sigdlid;
chanp->SigAref = sigchancon;
chanp->SigClass = sigclass;
switch( sigclass) {
case pwr_cClass_Di:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Di *)sig_op)->ActualValue);
break;
case pwr_cClass_Do:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Do *)sig_op)->ActualValue);
break;
case pwr_cClass_Po:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Po *)sig_op)->ActualValue);
break;
case pwr_cClass_Ai:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Ai *)sig_op)->ActualValue);
break;
case pwr_cClass_Ao:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Ao *)sig_op)->ActualValue);
break;
case pwr_cClass_Ii:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Ii *)sig_op)->ActualValue);
break;
case pwr_cClass_Io:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Io *)sig_op)->ActualValue);
break;
case pwr_cClass_Co:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Co *)sig_op)->RawValue);
chanp->abs_vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Co *)sig_op)->AbsValue);
break;
default:
errh_Error(
"IO init error: unknown signal class card %, chan nr %d",
cp->Name, number);
sts = gdh_DLUnrefObjectInfo( chandlid);
sts = gdh_DLUnrefObjectInfo( sigdlid);
memset( chanp, 0, sizeof(*chanp));
}
/* If the signal has a Sup-object as a child, this will be inserted
in the suplist */
/* if ( process != io_mProcess_Plc) */
io_ConnectToSupLst( ctx->SupCtx, sigclass, sigchancon.Objid, sig_op);
}
sts = gdh_GetNextSibling( chan, &chan);
}
/* Look for internal object attributes */ /* Find children */
if ( !child_found) { sts = gdh_GetChild( objid, &chan);
gdh_sAttrDef *bd; while( ODD(sts)) {
int rows; memset( &attrref, 0, sizeof(attrref));
int csize; attrref.Objid = chan;
int i, j; sts = gdh_DLRefObjectInfoAttrref( &attrref, (void *) &chan_op, &chandlid);
int elem; if ( EVEN(sts)) return sts;
sts = gdh_GetObjectBodyDef( cp->Class, &bd, &rows, pwr_cNObjid); sts = gdh_GetObjectClass( chan, &class);
if ( EVEN(sts)) return sts; if ( EVEN(sts)) return sts;
for ( i = 0; i < rows; i++) { switch ( class) {
switch ( bd[i].attr->Param.TypeRef) {
case pwr_cClass_ChanAi: case pwr_cClass_ChanAi:
csize = sizeof( pwr_sClass_ChanAi); sigchancon = ((pwr_sClass_ChanAi *) chan_op)->SigChanCon;
break; number = ((pwr_sClass_ChanAi *) chan_op)->Number;
break;
case pwr_cClass_ChanAit: case pwr_cClass_ChanAit:
csize = sizeof( pwr_sClass_ChanAit); sigchancon = ((pwr_sClass_ChanAit *) chan_op)->SigChanCon;
break; number = ((pwr_sClass_ChanAit *) chan_op)->Number;
break;
case pwr_cClass_ChanAo: case pwr_cClass_ChanAo:
csize = sizeof( pwr_sClass_ChanAo); sigchancon = ((pwr_sClass_ChanAo *) chan_op)->SigChanCon;
break; number = ((pwr_sClass_ChanAo *) chan_op)->Number;
case pwr_cClass_ChanDi: break;
csize = sizeof( pwr_sClass_ChanDi);
break;
case pwr_cClass_ChanDo: case pwr_cClass_ChanDo:
csize = sizeof( pwr_sClass_ChanDo); sigchancon = ((pwr_sClass_ChanDo *) chan_op)->SigChanCon;
break; number = ((pwr_sClass_ChanDo *) chan_op)->Number;
break;
case pwr_cClass_ChanDi:
sigchancon = ((pwr_sClass_ChanDi *) chan_op)->SigChanCon;
number = ((pwr_sClass_ChanDi *) chan_op)->Number;
break;
case pwr_cClass_ChanIi: case pwr_cClass_ChanIi:
csize = sizeof( pwr_sClass_ChanIi); sigchancon = ((pwr_sClass_ChanIi *) chan_op)->SigChanCon;
number = ((pwr_sClass_ChanIi *) chan_op)->Number;
break; break;
case pwr_cClass_ChanIo: case pwr_cClass_ChanIo:
csize = sizeof( pwr_sClass_ChanIo); sigchancon = ((pwr_sClass_ChanIo *) chan_op)->SigChanCon;
number = ((pwr_sClass_ChanIo *) chan_op)->Number;
break; break;
case pwr_cClass_ChanCo: case pwr_cClass_ChanCo:
csize = sizeof( pwr_sClass_ChanCo); sigchancon = ((pwr_sClass_ChanCo *) chan_op)->SigChanCon;
number = ((pwr_sClass_ChanCo *) chan_op)->Number;
break; break;
default: default:
sts = gdh_DLUnrefObjectInfo( chandlid);
sts = gdh_GetNextSibling( chan, &chan);
continue;
}
child_found = 1;
chan_cnt++;
if ( !fix_channels && chan_cnt > maxchan) {
errh_Error( "IO init error: max number of channels exceeded %s, chan nr %d",
cp->Name, chan_cnt);
sts = gdh_DLUnrefObjectInfo( chandlid);
break;
}
if ( fix_channels && (int) number > maxchan-1) {
/* Number out of range */
errh_Error( "IO init error: number out of range %s, chan nr %d",
cp->Name, number);
sts = gdh_DLUnrefObjectInfo( chandlid);
sts = gdh_GetNextSibling( chan, &chan);
continue; continue;
} }
elem = 1; /* Find signal */
if ( bd[i].attr->Param.Info.Flags & PWR_MASK_ARRAY) sig_found = 1;
elem = bd[i].attr->Param.Info.Elements; if ( cdh_ObjidIsNull( sigchancon.Objid)) {
for ( j = 0; j < elem; j++) { /* Not connected */
chan_op = ((char *)cp->op) + bd[i].attr->Param.Info.Offset + csize * j; sig_found = 0;
}
if ( sig_found) {
sts = gdh_GetAttrRefTid( &sigchancon, &sigclass);
if ( EVEN(sts))
sig_found = 0;
}
if ( sig_found) {
sts = gdh_DLRefObjectInfoAttrref( &sigchancon, (void *) &sig_op, &sigdlid);
if ( EVEN(sts))
sig_found = 0;
}
if ( fix_channels && !sig_found) {
sts = gdh_DLUnrefObjectInfo( chandlid);
sts = gdh_GetNextSibling( chan, &chan);
continue;
}
if ( fix_channels)
idx = number;
else
idx = chan_cnt - 1;
/* Insert */
chanp = &cp->chanlist[idx];
chanp->cop = chan_op;
chanp->ChanDlid = chandlid;
chanp->ChanAref = cdh_ObjidToAref(chan);
chanp->ChanClass = class;
if ( sig_found) {
chanp->sop = sig_op;
chanp->SigDlid = sigdlid;
chanp->SigAref = sigchancon;
chanp->SigClass = sigclass;
switch( sigclass) {
case pwr_cClass_Di:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Di *)sig_op)->ActualValue);
break;
case pwr_cClass_Do:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Do *)sig_op)->ActualValue);
break;
case pwr_cClass_Po:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Po *)sig_op)->ActualValue);
break;
case pwr_cClass_Ai:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Ai *)sig_op)->ActualValue);
break;
case pwr_cClass_Ao:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Ao *)sig_op)->ActualValue);
break;
case pwr_cClass_Ii:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Ii *)sig_op)->ActualValue);
break;
case pwr_cClass_Io:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Io *)sig_op)->ActualValue);
break;
case pwr_cClass_Co:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Co *)sig_op)->RawValue);
chanp->abs_vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Co *)sig_op)->AbsValue);
break;
default:
errh_Error(
"IO init error: unknown signal class card %, chan nr %d",
cp->Name, number);
sts = gdh_DLUnrefObjectInfo( chandlid);
sts = gdh_DLUnrefObjectInfo( sigdlid);
memset( chanp, 0, sizeof(*chanp));
}
/* If the signal has a Sup-object as a child, this will be inserted
in the suplist */
/* if ( process != io_mProcess_Plc) */
io_ConnectToSupLst( ctx->SupCtx, sigclass, sigchancon.Objid, sig_op);
}
sts = gdh_GetNextSibling( chan, &chan);
}
/* Look for internal object attributes */
if ( !child_found) {
gdh_sAttrDef *bd;
int rows;
int csize;
int i, j;
int elem;
sts = gdh_GetObjectBodyDef( cp->Class, &bd, &rows, pwr_cNObjid);
if ( EVEN(sts)) return sts;
for ( i = 0; i < rows; i++) {
switch ( bd[i].attr->Param.TypeRef) { switch ( bd[i].attr->Param.TypeRef) {
case pwr_cClass_ChanAi: case pwr_cClass_ChanAi:
sigchancon = ((pwr_sClass_ChanAi *) chan_op)->SigChanCon; csize = sizeof( pwr_sClass_ChanAi);
number = chan_cnt;
break; break;
case pwr_cClass_ChanAit: case pwr_cClass_ChanAit:
sigchancon = ((pwr_sClass_ChanAit *) chan_op)->SigChanCon; csize = sizeof( pwr_sClass_ChanAit);
number = chan_cnt;
break; break;
case pwr_cClass_ChanAo: case pwr_cClass_ChanAo:
sigchancon = ((pwr_sClass_ChanAo *) chan_op)->SigChanCon; csize = sizeof( pwr_sClass_ChanAo);
number = chan_cnt;
break; break;
case pwr_cClass_ChanDi: case pwr_cClass_ChanDi:
sigchancon = ((pwr_sClass_ChanDi *) chan_op)->SigChanCon; csize = sizeof( pwr_sClass_ChanDi);
number = chan_cnt;
break; break;
case pwr_cClass_ChanDo: case pwr_cClass_ChanDo:
sigchancon = ((pwr_sClass_ChanDo *) chan_op)->SigChanCon; csize = sizeof( pwr_sClass_ChanDo);
number = chan_cnt;
break; break;
case pwr_cClass_ChanIi: case pwr_cClass_ChanIi:
sigchancon = ((pwr_sClass_ChanIi *) chan_op)->SigChanCon; csize = sizeof( pwr_sClass_ChanIi);
number = chan_cnt;
break; break;
case pwr_cClass_ChanIo: case pwr_cClass_ChanIo:
sigchancon = ((pwr_sClass_ChanIo *) chan_op)->SigChanCon; csize = sizeof( pwr_sClass_ChanIo);
number = chan_cnt;
break; break;
case pwr_cClass_ChanCo: case pwr_cClass_ChanCo:
sigchancon = ((pwr_sClass_ChanCo *) chan_op)->SigChanCon; csize = sizeof( pwr_sClass_ChanCo);
number = chan_cnt;
break; break;
default: default:
; continue;
} }
chan_cnt++; elem = 1;
if ( bd[i].attr->Param.Info.Flags & PWR_MASK_ARRAY)
elem = bd[i].attr->Param.Info.Elements;
for ( j = 0; j < elem; j++) {
chan_op = ((char *)cp->op) + bd[i].attr->Param.Info.Offset + csize * j;
/* Find signal */ switch ( bd[i].attr->Param.TypeRef) {
sig_found = 0; case pwr_cClass_ChanAi:
if ( cdh_ObjidIsNotNull( sigchancon.Objid)) { sigchancon = ((pwr_sClass_ChanAi *) chan_op)->SigChanCon;
sts = gdh_GetAttrRefTid( &sigchancon, &sigclass); number = chan_cnt;
if ( ODD(sts)) {
sts = gdh_DLRefObjectInfoAttrref( &sigchancon, (void *) &sig_op, &sigdlid);
if ( ODD(sts))
sig_found = 1;
}
}
if ( !sig_found) {
sig_op = 0;
sigdlid = pwr_cNDlid;
sigclass = 0;
}
/* Insert */
if ( elem > 1)
sprintf( attrname, "%s.%s[%d]", cname, bd[i].attrName, j);
else
sprintf( attrname, "%s.%s", cname, bd[i].attrName);
chanp = &cp->chanlist[number];
chanp->cop = chan_op;
chanp->ChanDlid = pwr_cNDlid;
sts = gdh_NameToAttrref( pwr_cNObjid, attrname, &chanp->ChanAref);
if ( EVEN(sts)) return sts;
chanp->sop = sig_op;
chanp->SigDlid = sigdlid;
chanp->SigAref = sigchancon;
chanp->ChanClass = bd[i].attr->Param.TypeRef;
chanp->SigClass = sigclass;
if ( sig_found) {
switch( sigclass) {
case pwr_cClass_Di:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Di *)sig_op)->ActualValue);
break; break;
case pwr_cClass_Do: case pwr_cClass_ChanAit:
chanp->vbp = gdh_TranslateRtdbPointer( sigchancon = ((pwr_sClass_ChanAit *) chan_op)->SigChanCon;
(pwr_tUInt32) ((pwr_sClass_Do *)sig_op)->ActualValue); number = chan_cnt;
break; break;
case pwr_cClass_Po: case pwr_cClass_ChanAo:
chanp->vbp = gdh_TranslateRtdbPointer( sigchancon = ((pwr_sClass_ChanAo *) chan_op)->SigChanCon;
(pwr_tUInt32) ((pwr_sClass_Po *)sig_op)->ActualValue); number = chan_cnt;
break; break;
case pwr_cClass_Ai: case pwr_cClass_ChanDi:
chanp->vbp = gdh_TranslateRtdbPointer( sigchancon = ((pwr_sClass_ChanDi *) chan_op)->SigChanCon;
(pwr_tUInt32) ((pwr_sClass_Ai *)sig_op)->ActualValue); number = chan_cnt;
break; break;
case pwr_cClass_Ao: case pwr_cClass_ChanDo:
chanp->vbp = gdh_TranslateRtdbPointer( sigchancon = ((pwr_sClass_ChanDo *) chan_op)->SigChanCon;
(pwr_tUInt32) ((pwr_sClass_Ao *)sig_op)->ActualValue); number = chan_cnt;
break; break;
case pwr_cClass_Ii: case pwr_cClass_ChanIi:
chanp->vbp = gdh_TranslateRtdbPointer( sigchancon = ((pwr_sClass_ChanIi *) chan_op)->SigChanCon;
(pwr_tUInt32) ((pwr_sClass_Ii *)sig_op)->ActualValue); number = chan_cnt;
break; break;
case pwr_cClass_Io: case pwr_cClass_ChanIo:
chanp->vbp = gdh_TranslateRtdbPointer( sigchancon = ((pwr_sClass_ChanIo *) chan_op)->SigChanCon;
(pwr_tUInt32) ((pwr_sClass_Io *)sig_op)->ActualValue); number = chan_cnt;
break; break;
case pwr_cClass_Co: case pwr_cClass_ChanCo:
chanp->vbp = gdh_TranslateRtdbPointer( sigchancon = ((pwr_sClass_ChanCo *) chan_op)->SigChanCon;
(pwr_tUInt32) ((pwr_sClass_Co *)sig_op)->RawValue); number = chan_cnt;
chanp->abs_vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Co *)sig_op)->AbsValue);
break; break;
default: default:
errh_Error( ;
"IO init error: unknown signal class card %, chan nr %d", }
cp->Name, number);
sts = gdh_DLUnrefObjectInfo( sigdlid); chan_cnt++;
/* Find signal */
sig_found = 0;
if ( cdh_ObjidIsNotNull( sigchancon.Objid)) {
sts = gdh_GetAttrRefTid( &sigchancon, &sigclass);
if ( ODD(sts)) {
sts = gdh_DLRefObjectInfoAttrref( &sigchancon, (void *) &sig_op, &sigdlid);
if ( ODD(sts))
sig_found = 1;
}
}
if ( !sig_found) {
sig_op = 0; sig_op = 0;
sigdlid = pwr_cNDlid; sigdlid = pwr_cNDlid;
sigclass = 0;
}
/* Insert */
if ( elem > 1)
sprintf( attrname, "%s.%s[%d]", cname, bd[i].attrName, j);
else
sprintf( attrname, "%s.%s", cname, bd[i].attrName);
chanp = &cp->chanlist[number];
chanp->cop = chan_op;
chanp->ChanDlid = pwr_cNDlid;
sts = gdh_NameToAttrref( pwr_cNObjid, attrname, &chanp->ChanAref);
if ( EVEN(sts)) return sts;
chanp->sop = sig_op;
chanp->SigDlid = sigdlid;
chanp->SigAref = sigchancon;
chanp->ChanClass = bd[i].attr->Param.TypeRef;
chanp->SigClass = sigclass;
if ( sig_found) {
switch( sigclass) {
case pwr_cClass_Di:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Di *)sig_op)->ActualValue);
break;
case pwr_cClass_Do:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Do *)sig_op)->ActualValue);
break;
case pwr_cClass_Po:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Po *)sig_op)->ActualValue);
break;
case pwr_cClass_Ai:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Ai *)sig_op)->ActualValue);
break;
case pwr_cClass_Ao:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Ao *)sig_op)->ActualValue);
break;
case pwr_cClass_Ii:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Ii *)sig_op)->ActualValue);
break;
case pwr_cClass_Io:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Io *)sig_op)->ActualValue);
break;
case pwr_cClass_Co:
chanp->vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Co *)sig_op)->RawValue);
chanp->abs_vbp = gdh_TranslateRtdbPointer(
(pwr_tUInt32) ((pwr_sClass_Co *)sig_op)->AbsValue);
break;
default:
errh_Error(
"IO init error: unknown signal class card %, chan nr %d",
cp->Name, number);
sts = gdh_DLUnrefObjectInfo( sigdlid);
sig_op = 0;
sigdlid = pwr_cNDlid;
}
} }
} }
} }
free( (char *)bd);
} }
free( (char *)bd);
} }
} }
} }
} }
...@@ -1875,7 +1904,8 @@ static pwr_tStatus io_init_rack( ...@@ -1875,7 +1904,8 @@ static pwr_tStatus io_init_rack(
pwr_tObjid objid, pwr_tObjid objid,
io_tCtx ctx, io_tCtx ctx,
io_sAgent *ap, io_sAgent *ap,
int agent_type) int agent_type,
int swap)
{ {
pwr_tStatus sts; pwr_tStatus sts;
pwr_tClassId class; pwr_tClassId class;
...@@ -1883,6 +1913,7 @@ static pwr_tStatus io_init_rack( ...@@ -1883,6 +1913,7 @@ static pwr_tStatus io_init_rack(
pwr_tStatus (* RackClose) (); pwr_tStatus (* RackClose) ();
pwr_tStatus (* RackRead) (); pwr_tStatus (* RackRead) ();
pwr_tStatus (* RackWrite) (); pwr_tStatus (* RackWrite) ();
pwr_tStatus (* RackSwap) ();
pwr_tAName rname; pwr_tAName rname;
pwr_tAName attrname; pwr_tAName attrname;
pwr_tUInt32 process = 0; pwr_tUInt32 process = 0;
...@@ -1903,9 +1934,9 @@ static pwr_tStatus io_init_rack( ...@@ -1903,9 +1934,9 @@ static pwr_tStatus io_init_rack(
} }
if ( io_CheckClassIoType( io_eType_Rack, class)) { if ( io_CheckClassIoType( io_eType_Rack, class)) {
sts = io_FindMethods( class, io_eType_Rack, &RackInit, &RackClose, &RackRead, &RackWrite); sts = io_FindMethods( class, io_eType_Rack, &RackInit, &RackClose, &RackRead, &RackWrite, &RackSwap);
if ( ODD(sts)) { if ( ODD(sts)) {
if ( RackInit != NULL || RackClose != NULL || RackRead != NULL || RackWrite != NULL) { if ( RackInit != NULL || RackClose != NULL || RackRead != NULL || RackWrite != NULL || RackSwap != NULL) {
/* This is a rack object, */ /* This is a rack object, */
/* Check if the rack should be handled by this process */ /* Check if the rack should be handled by this process */
...@@ -1918,8 +1949,8 @@ static pwr_tStatus io_init_rack( ...@@ -1918,8 +1949,8 @@ static pwr_tStatus io_init_rack(
strcat( attrname, ".Process"); strcat( attrname, ".Process");
sts = gdh_GetObjectInfo( attrname, &process, sizeof(process)); sts = gdh_GetObjectInfo( attrname, &process, sizeof(process));
if ( EVEN(sts) || if ( (EVEN(sts) ||
(ODD(sts) && ctx->Process & process)) { (ODD(sts) && ctx->Process & process)) && !swap) {
if ( EVEN(sts)) if ( EVEN(sts))
process = io_mProcess_All; process = io_mProcess_All;
...@@ -1936,6 +1967,9 @@ static pwr_tStatus io_init_rack( ...@@ -1936,6 +1967,9 @@ static pwr_tStatus io_init_rack(
else else
ok = 1; ok = 1;
} }
else if (ODD(sts) && swap && RackSwap != NULL) {
ok = 1;
}
if ( ok) { if ( ok) {
...@@ -1946,14 +1980,25 @@ static pwr_tStatus io_init_rack( ...@@ -1946,14 +1980,25 @@ static pwr_tStatus io_init_rack(
rp->Objid = objid; rp->Objid = objid;
strcpy( rp->Name, rname); strcpy( rp->Name, rname);
rp->Process = process; rp->Process = process;
if ( RackRead != NULL) if (!swap) {
rp->Action |= io_mAction_Read; if ( RackRead != NULL)
if ( RackWrite != NULL) rp->Action |= io_mAction_Read;
rp->Action |= io_mAction_Write; if ( RackWrite != NULL)
rp->Init = RackInit; rp->Action |= io_mAction_Write;
rp->Close = RackClose; rp->Init = RackInit;
rp->Read = RackRead; rp->Close = RackClose;
rp->Write = RackWrite; rp->Read = RackRead;
rp->Write = RackWrite;
rp->Swap = RackSwap;
} else {
if ( RackSwap != NULL)
rp->Action |= io_mAction_Swap;
rp->Init = NULL;
rp->Close = RackClose;
rp->Read = NULL;
rp->Write = NULL;
rp->Swap = RackSwap;
}
if ( agent_type == io_eType_Agent) if ( agent_type == io_eType_Agent)
rp->AgentControlled = 1; rp->AgentControlled = 1;
memset( &attrref, 0, sizeof(attrref)); memset( &attrref, 0, sizeof(attrref));
...@@ -1976,7 +2021,7 @@ static pwr_tStatus io_init_rack( ...@@ -1976,7 +2021,7 @@ static pwr_tStatus io_init_rack(
rlp->next = rp; rlp->next = rp;
} }
sts = io_trv_child( objid, 0, io_init_card, ctx, rp, agent_type); sts = io_trv_child( objid, 0, io_init_card, ctx, rp, agent_type, swap);
} }
return IO__TRV_NEXT; return IO__TRV_NEXT;
} }
...@@ -1993,7 +2038,8 @@ static pwr_tStatus io_init_agent( ...@@ -1993,7 +2038,8 @@ static pwr_tStatus io_init_agent(
pwr_tObjid objid, pwr_tObjid objid,
io_tCtx ctx, io_tCtx ctx,
void *dummy, void *dummy,
int agent_type) int agent_type,
int swap)
{ {
pwr_tStatus sts; pwr_tStatus sts;
pwr_tClassId class; pwr_tClassId class;
...@@ -2001,6 +2047,7 @@ static pwr_tStatus io_init_agent( ...@@ -2001,6 +2047,7 @@ static pwr_tStatus io_init_agent(
pwr_tStatus (* AgentClose) (); pwr_tStatus (* AgentClose) ();
pwr_tStatus (* AgentRead) (); pwr_tStatus (* AgentRead) ();
pwr_tStatus (* AgentWrite) (); pwr_tStatus (* AgentWrite) ();
pwr_tStatus (* AgentSwap) ();
pwr_tAName aname; pwr_tAName aname;
pwr_tAName attrname; pwr_tAName attrname;
pwr_tUInt32 process = 0; pwr_tUInt32 process = 0;
...@@ -2015,9 +2062,9 @@ static pwr_tStatus io_init_agent( ...@@ -2015,9 +2062,9 @@ static pwr_tStatus io_init_agent(
if ( EVEN(sts)) return sts; if ( EVEN(sts)) return sts;
if ( io_CheckClassIoType( io_eType_Agent, class)) { if ( io_CheckClassIoType( io_eType_Agent, class)) {
sts = io_FindMethods( class, io_eType_Agent, &AgentInit, &AgentClose, &AgentRead, &AgentWrite); sts = io_FindMethods( class, io_eType_Agent, &AgentInit, &AgentClose, &AgentRead, &AgentWrite, &AgentSwap);
if ( ODD(sts)) { if ( ODD(sts)) {
if ( AgentInit != NULL || AgentClose != NULL || AgentRead != NULL || AgentWrite != NULL) { if ( AgentInit != NULL || AgentClose != NULL || AgentRead != NULL || AgentWrite != NULL || AgentSwap != NULL) {
/* This is a agent object or the node object, */ /* This is a agent object or the node object, */
/* Check if the agent should be handled by this process */ /* Check if the agent should be handled by this process */
...@@ -2029,8 +2076,8 @@ static pwr_tStatus io_init_agent( ...@@ -2029,8 +2076,8 @@ static pwr_tStatus io_init_agent(
strcpy( attrname, aname); strcpy( attrname, aname);
strcat( attrname, ".Process"); strcat( attrname, ".Process");
sts = gdh_GetObjectInfo( attrname, &process, sizeof(process)); sts = gdh_GetObjectInfo( attrname, &process, sizeof(process));
if ( EVEN(sts) || if (( EVEN(sts) ||
(ODD(sts) && ctx->Process & process)) { (ODD(sts) && ctx->Process & process)) && !swap) {
if ( EVEN(sts)) if ( EVEN(sts))
process = io_mProcess_All; process = io_mProcess_All;
if ( ctx->Process == io_mProcess_Profibus) if ( ctx->Process == io_mProcess_Profibus)
...@@ -2048,6 +2095,10 @@ static pwr_tStatus io_init_agent( ...@@ -2048,6 +2095,10 @@ static pwr_tStatus io_init_agent(
else else
ok = 1; ok = 1;
} }
else if (ODD(sts) && swap && AgentSwap != NULL) {
/* IoComm-process should always handle the Swap-method */
ok = 1;
}
if ( ok) { if ( ok) {
...@@ -2058,14 +2109,25 @@ static pwr_tStatus io_init_agent( ...@@ -2058,14 +2109,25 @@ static pwr_tStatus io_init_agent(
ap->Objid = objid; ap->Objid = objid;
strcpy( ap->Name, aname); strcpy( ap->Name, aname);
ap->Process = process; ap->Process = process;
if ( AgentRead != NULL) if (!swap) {
ap->Action |= io_mAction_Read; if ( AgentRead != NULL)
if ( AgentWrite != NULL) ap->Action |= io_mAction_Read;
ap->Action |= io_mAction_Write; if ( AgentWrite != NULL)
ap->Init = AgentInit; ap->Action |= io_mAction_Write;
ap->Close = AgentClose; ap->Init = AgentInit;
ap->Read = AgentRead; ap->Close = AgentClose;
ap->Write = AgentWrite; ap->Read = AgentRead;
ap->Write = AgentWrite;
ap->Swap = AgentSwap;
} else {
if ( AgentSwap != NULL)
ap->Action |= io_mAction_Swap;
ap->Init = NULL;
ap->Close = AgentClose;
ap->Read = NULL;
ap->Write = NULL;
ap->Swap = AgentSwap;
}
memset( &attrref, 0, sizeof(attrref)); memset( &attrref, 0, sizeof(attrref));
attrref.Objid = objid; attrref.Objid = objid;
sts = gdh_DLRefObjectInfoAttrref( &attrref, &ap->op, &ap->Dlid); sts = gdh_DLRefObjectInfoAttrref( &attrref, &ap->op, &ap->Dlid);
...@@ -2086,7 +2148,7 @@ static pwr_tStatus io_init_agent( ...@@ -2086,7 +2148,7 @@ static pwr_tStatus io_init_agent(
alp->next = ap; alp->next = ap;
} }
sts = io_trv_child( objid, 0, io_init_rack, ctx, ap, agent_type); sts = io_trv_child( objid, 0, io_init_rack, ctx, ap, agent_type, swap);
} }
} }
} }
...@@ -2104,7 +2166,8 @@ static pwr_tStatus io_trv_child( ...@@ -2104,7 +2166,8 @@ static pwr_tStatus io_trv_child(
pwr_tStatus (* func) (), pwr_tStatus (* func) (),
void *arg1, void *arg1,
void *arg2, void *arg2,
int arg3) int arg3,
int arg4)
{ {
pwr_tObjid child; pwr_tObjid child;
pwr_tStatus sts; pwr_tStatus sts;
...@@ -2112,12 +2175,12 @@ static pwr_tStatus io_trv_child( ...@@ -2112,12 +2175,12 @@ static pwr_tStatus io_trv_child(
sts = gdh_GetChild( parent, &child); sts = gdh_GetChild( parent, &child);
while ( ODD(sts)) while ( ODD(sts))
{ {
sts = (func) ( child, arg1, arg2, arg3); sts = (func) ( child, arg1, arg2, arg3, arg4);
if ( EVEN(sts)) return sts; if ( EVEN(sts)) return sts;
if ( deep && sts != IO__TRV_NEXT) if ( deep && sts != IO__TRV_NEXT)
{ {
sts = io_trv_child( child, deep, func, arg1, arg2, arg3); sts = io_trv_child( child, deep, func, arg1, arg2, arg3, arg4);
if ( EVEN(sts)) return sts; if ( EVEN(sts)) return sts;
} }
sts = gdh_GetNextSibling( child, &child); sts = gdh_GetNextSibling( child, &child);
...@@ -2363,11 +2426,11 @@ pwr_tStatus io_init ( ...@@ -2363,11 +2426,11 @@ pwr_tStatus io_init (
/* Traverse all objects in the NodeHierarchy, find methods and build /* Traverse all objects in the NodeHierarchy, find methods and build
the io context tree for the local racks and cards. */ the io context tree for the local racks and cards. */
sts = io_init_agent( node, *ctx, NULL, io_eType_Node); sts = io_init_agent( node, *ctx, NULL, io_eType_Node, 0);
if ( EVEN(sts)) return sts; if ( EVEN(sts)) return sts;
/* Build the io context tree for the remote racks and cards. */ /* Build the io context tree for the remote racks and cards. */
sts = io_trv_child( node, 1, io_init_agent, *ctx, NULL, io_eType_Agent); sts = io_trv_child( node, 1, io_init_agent, *ctx, NULL, io_eType_Agent, 0);
/* /*
sts = io_init_signals(); sts = io_init_signals();
...@@ -2422,6 +2485,69 @@ pwr_tStatus io_init ( ...@@ -2422,6 +2485,69 @@ pwr_tStatus io_init (
return IO__SUCCESS; return IO__SUCCESS;
} }
/*----------------------------------------------------------------------------*\
Initialize io racks and cards.
\*----------------------------------------------------------------------------*/
pwr_tStatus io_init_swap (
io_mProcess process,
pwr_tObjid thread,
io_tCtx *ctx,
int relativ_vector,
float scan_time)
{
pwr_tObjid node;
pwr_sNode *node_op;
pwr_sClass_IOHandler *io_op;
pwr_tStatus sts;
io_sAgent *ap;
if ( scan_time <= 0)
return IO__TIMEINVALID;
sts = io_get_iohandler_object(&io_op, NULL);
if ( EVEN(sts)) return sts;
sts = gdh_GetNodeObject( 0, &node);
if ( EVEN(sts)) return sts;
sts = gdh_ObjidToPointer( node, (void *) &node_op);
if ( EVEN(sts)) return sts;
*ctx = calloc( 1, sizeof(**ctx));
(*ctx)->Process = process;
(*ctx)->RelativVector = relativ_vector;
(*ctx)->Node = node_op;
(*ctx)->IOHandler = io_op;
(*ctx)->ScanTime = scan_time;
(*ctx)->Thread = thread;
if ( (*ctx)->Node->EmergBreakTrue || !(*ctx)->IOHandler->IOReadWriteFlag)
return IO__IS_STOPPED;
/* Traverse all objects in the NodeHierarchy, find methods and build
the io context tree for the local racks and cards. */
sts = io_init_agent( node, *ctx, NULL, io_eType_Node, 1);
if ( EVEN(sts)) return sts;
/* Build the io context tree for the remote racks and cards. */
sts = io_trv_child( node, 1, io_init_agent, *ctx, NULL, io_eType_Agent, 1);
/* Call the swap method for agents */
for ( ap = (*ctx)->agentlist; ap != NULL; ap = ap->next)
{
if (ap->Action & io_mAction_Swap)
{
sts = (ap->Swap) ( *ctx, ap);
if ( EVEN(sts)) return sts;
}
}
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\ /*----------------------------------------------------------------------------*\
...@@ -2558,6 +2684,73 @@ pwr_tStatus io_write( ...@@ -2558,6 +2684,73 @@ pwr_tStatus io_write(
return IO__SUCCESS; return IO__SUCCESS;
} }
/*----------------------------------------------------------------------------*\
Swap io racks and cards.
\*----------------------------------------------------------------------------*/
pwr_tStatus io_swap(
io_tCtx ctx)
{
pwr_tStatus sts;
io_sAgent *ap;
io_sRack *rp;
io_sCard *cp;
if ( ctx->Node->EmergBreakTrue || !ctx->IOHandler->IOReadWriteFlag)
return IO__IS_STOPPED;
/* Call the read methods for agents, racks and cards */
for ( ap = ctx->agentlist; ap != NULL; ap = ap->next)
{
if (ap->Action & io_mAction_Swap)
{
if ( ap->scan_interval_cnt <= 1)
{
sts = (ap->Swap) ( ctx, ap);
if ( EVEN(sts)) return sts;
ap->scan_interval_cnt = ap->scan_interval;
}
else
ap->scan_interval_cnt--;
}
for ( rp = ap->racklist; rp != NULL; rp = rp->next)
{
if (rp->Action & io_mAction_Swap)
{
if ( rp->scan_interval_cnt <= 1)
{
sts = (rp->Swap) ( ctx, ap, rp);
if ( EVEN(sts)) return sts;
rp->scan_interval_cnt = rp->scan_interval;
}
else
rp->scan_interval_cnt--;
}
for ( cp = rp->cardlist; cp != NULL; cp = cp->next)
{
if (cp->Action & io_mAction_Swap)
{
if ( cp->scan_interval_cnt <= 1)
{
sts = (cp->Swap) ( ctx, ap, rp, cp);
if ( EVEN(sts)) return sts;
cp->scan_interval_cnt = cp->scan_interval;
}
else
cp->scan_interval_cnt--;
}
}
}
}
/* Scan the Sup lists */
/* if ( ctx->Process != io_mProcess_Plc) */
sts = io_ScanSupLst( ctx->SupCtx);
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\ /*----------------------------------------------------------------------------*\
Close Io. Close Io.
......
/* /*
* Proview $Id: rt_io_base.h,v 1.8 2006-06-30 12:17:12 claes Exp $ * Proview $Id: rt_io_base.h,v 1.9 2007-05-18 12:05:12 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB. * Copyright (C) 2005 SSAB Oxelsund AB.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -68,7 +68,8 @@ typedef enum { ...@@ -68,7 +68,8 @@ typedef enum {
typedef enum { typedef enum {
io_mAction_None = 0, io_mAction_None = 0,
io_mAction_Read = 1 << 0, io_mAction_Read = 1 << 0,
io_mAction_Write = 1 << 1 io_mAction_Write = 1 << 1,
io_mAction_Swap = 1 << 2
} io_mAction; } io_mAction;
typedef enum { typedef enum {
...@@ -107,6 +108,7 @@ typedef struct s_Card { ...@@ -107,6 +108,7 @@ typedef struct s_Card {
pwr_tStatus (* Close) (); /* Close method */ pwr_tStatus (* Close) (); /* Close method */
pwr_tStatus (* Read) (); /* Read method */ pwr_tStatus (* Read) (); /* Read method */
pwr_tStatus (* Write) (); /* Write method */ pwr_tStatus (* Write) (); /* Write method */
pwr_tStatus (* Swap) (); /* Write method */
pwr_tAddress *op; /* Pointer to card object */ pwr_tAddress *op; /* Pointer to card object */
pwr_tDlid Dlid; /* Dlid for card object pointer */ pwr_tDlid Dlid; /* Dlid for card object pointer */
pwr_tUInt32 size; /* Size of card data area in byte */ pwr_tUInt32 size; /* Size of card data area in byte */
...@@ -130,6 +132,7 @@ typedef struct s_Rack { ...@@ -130,6 +132,7 @@ typedef struct s_Rack {
pwr_tStatus (* Close) (); /* Close method */ pwr_tStatus (* Close) (); /* Close method */
pwr_tStatus (* Read) (); /* Read method */ pwr_tStatus (* Read) (); /* Read method */
pwr_tStatus (* Write) (); /* Write method */ pwr_tStatus (* Write) (); /* Write method */
pwr_tStatus (* Swap) (); /* Swap method */
void *op; /* Pointer to rack object */ void *op; /* Pointer to rack object */
pwr_tDlid Dlid; /* Dlid fr rack object pointer */ pwr_tDlid Dlid; /* Dlid fr rack object pointer */
pwr_tUInt32 size; /* Size of rack data area in byte */ pwr_tUInt32 size; /* Size of rack data area in byte */
...@@ -152,6 +155,7 @@ typedef struct s_Agent { ...@@ -152,6 +155,7 @@ typedef struct s_Agent {
pwr_tStatus (* Close) (); /* Close method */ pwr_tStatus (* Close) (); /* Close method */
pwr_tStatus (* Read) (); /* Read method */ pwr_tStatus (* Read) (); /* Read method */
pwr_tStatus (* Write) (); /* Write method */ pwr_tStatus (* Write) (); /* Write method */
pwr_tStatus (* Swap) (); /* Write method */
void *op; /* Pointer to agent object */ void *op; /* Pointer to agent object */
pwr_tDlid Dlid; /* Dlid for agent object pointer */ pwr_tDlid Dlid; /* Dlid for agent object pointer */
int scan_interval; /* Interval between scans */ int scan_interval; /* Interval between scans */
...@@ -197,6 +201,14 @@ pwr_tStatus io_init( ...@@ -197,6 +201,14 @@ pwr_tStatus io_init(
float scan_time float scan_time
); );
pwr_tStatus io_init_swap(
io_mProcess process,
pwr_tObjid thread,
io_tCtx *ctx,
int relativ_vector,
float scan_time
);
pwr_tStatus io_read( pwr_tStatus io_read(
io_tCtx ctx io_tCtx ctx
); );
...@@ -205,6 +217,10 @@ pwr_tStatus io_write( ...@@ -205,6 +217,10 @@ pwr_tStatus io_write(
io_tCtx ctx io_tCtx ctx
); );
pwr_tStatus io_swap(
io_tCtx ctx
);
pwr_tStatus io_close( pwr_tStatus io_close(
io_tCtx ctx io_tCtx ctx
); );
......
/* /*
* Proview $Id: rt_io_m_node.c,v 1.2 2005-09-01 14:57:55 claes Exp $ * Proview $Id: rt_io_m_node.c,v 1.3 2007-05-18 12:05:12 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB. * Copyright (C) 2005 SSAB Oxelsund AB.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -40,6 +40,15 @@ static pwr_tStatus IoAgentInit ( ...@@ -40,6 +40,15 @@ static pwr_tStatus IoAgentInit (
return 1; return 1;
} }
static pwr_tStatus IoAgentSwap (
io_tCtx ctx,
io_sAgent *ap
)
{
return 1;
}
/*----------------------------------------------------------------------------*\ /*----------------------------------------------------------------------------*\
...@@ -52,5 +61,6 @@ static pwr_tStatus IoAgentInit ( ...@@ -52,5 +61,6 @@ static pwr_tStatus IoAgentInit (
pwr_dExport pwr_BindIoMethods(Node) = { pwr_dExport pwr_BindIoMethods(Node) = {
pwr_BindIoMethod(IoAgentInit), pwr_BindIoMethod(IoAgentInit),
pwr_BindIoMethod(IoAgentSwap),
pwr_NullMethod pwr_NullMethod
}; };
! !
! Proview $Id: pwrs_c_node.wb_load,v 1.11 2006-03-31 14:47:15 claes Exp $ ! Proview $Id: pwrs_c_node.wb_load,v 1.12 2007-05-18 12:06:05 claes Exp $
! Copyright (C) 2005 SSAB Oxelsund AB. ! Copyright (C) 2005 SSAB Oxelsund AB.
! !
! This program is free software; you can redistribute it and/or ! This program is free software; you can redistribute it and/or
...@@ -344,6 +344,11 @@ SObject pwrs:Class ...@@ -344,6 +344,11 @@ SObject pwrs:Class
Attr MethodName = "Node-IoAgentInit" Attr MethodName = "Node-IoAgentInit"
EndBody EndBody
EndObject EndObject
Object IoAgentSwap $Method
Body SysBody
Attr MethodName = "Node-IoAgentSwap"
EndBody
EndObject
EndObject EndObject
EndObject EndObject
EndSObject EndSObject
/* /*
* Proview $Id: rt_io_m_rack_ssab.c,v 1.2 2006-04-12 10:14:49 claes Exp $ * Proview $Id: rt_io_m_rack_ssab.c,v 1.3 2007-05-18 12:06:05 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB. * Copyright (C) 2005 SSAB Oxelsund AB.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -64,6 +64,31 @@ static pwr_tStatus IoRackInit ( ...@@ -64,6 +64,31 @@ static pwr_tStatus IoRackInit (
return 1; return 1;
} }
static pwr_tStatus IoRackSwap (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp
)
{
io_sRackLocal *local;
if (!rp->Local) {
/* Open Qbus driver */
local = calloc( 1, sizeof(*local));
rp->Local = local;
local->Qbus_fp = open("/dev/qbus", O_RDWR);
if ( local->Qbus_fp == -1)
{
errh_Error( "Qbus swap initialization error, IO rack %s", rp->Name);
return IO__ERRDEVICE;
}
errh_Info( "Swap init of IO rack %s", rp->Name);
}
return 1;
}
static pwr_tStatus IoRackClose ( static pwr_tStatus IoRackClose (
io_tCtx ctx, io_tCtx ctx,
io_sAgent *ap, io_sAgent *ap,
...@@ -93,6 +118,7 @@ static pwr_tStatus IoRackClose ( ...@@ -93,6 +118,7 @@ static pwr_tStatus IoRackClose (
pwr_dExport pwr_BindIoMethods(Rack_SSAB) = { pwr_dExport pwr_BindIoMethods(Rack_SSAB) = {
pwr_BindIoMethod(IoRackInit), pwr_BindIoMethod(IoRackInit),
pwr_BindIoMethod(IoRackSwap),
pwr_BindIoMethod(IoRackClose), pwr_BindIoMethod(IoRackClose),
pwr_NullMethod pwr_NullMethod
}; };
/* /*
* Proview $Id: rt_io_m_ssab_do.c,v 1.4 2007-04-30 12:08:08 claes Exp $ * Proview $Id: rt_io_m_ssab_do.c,v 1.5 2007-05-18 12:06:05 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB. * Copyright (C) 2005 SSAB Oxelsund AB.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -250,6 +250,54 @@ static pwr_tStatus IoCardWrite ( ...@@ -250,6 +250,54 @@ static pwr_tStatus IoCardWrite (
return 1; return 1;
} }
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardSwap (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sLocal *local;
io_sRackLocal *r_local = (io_sRackLocal *)(rp->Local);
pwr_tUInt16 data = 0;
pwr_sClass_Ssab_BaseDoCard *op;
int i;
qbus_io_read rb;
int sts;
if (!cp->Local) {
local = calloc( 1, sizeof(*local));
cp->Local = local;
local->Address[0] = op->RegAddress;
local->Address[1] = op->RegAddress + 2;
local->Qbus_fp = ((io_sRackLocal *)(rp->Local))->Qbus_fp;
}
op = (pwr_sClass_Ssab_BaseDoCard *) cp->op;
for ( i = 0; i < 2; i++)
{
if (r_local->Qbus_fp != 0 && r_local->s == 0) {
/* Write to local Q-bus */
rb.Address = local->Address[i];
sts = read( local->Qbus_fp, &rb, sizeof(rb));
}
else {
/* Ethernet I/O, Get data from current address */
data = bfbeth_get_data(r_local, (pwr_tUInt16) local->Address[i], &sts);
/* Yes, we want to read this address the next time aswell */
bfbeth_set_read_req(r_local, (pwr_tUInt16) local->Address[i]);
sts = 1;
}
}
return 1;
}
/*----------------------------------------------------------------------------*\ /*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here. Every method to be exported to the workbench should be registred here.
...@@ -259,5 +307,6 @@ pwr_dExport pwr_BindIoMethods(Ssab_Do) = { ...@@ -259,5 +307,6 @@ pwr_dExport pwr_BindIoMethods(Ssab_Do) = {
pwr_BindIoMethod(IoCardInit), pwr_BindIoMethod(IoCardInit),
pwr_BindIoMethod(IoCardClose), pwr_BindIoMethod(IoCardClose),
pwr_BindIoMethod(IoCardWrite), pwr_BindIoMethod(IoCardWrite),
pwr_BindIoMethod(IoCardSwap),
pwr_NullMethod pwr_NullMethod
}; };
/* /*
* Proview $Id: rt_io_m_ssab_remoterack.c,v 1.5 2006-09-05 12:03:01 claes Exp $ * Proview $Id: rt_io_m_ssab_remoterack.c,v 1.6 2007-05-18 12:06:05 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB. * Copyright (C) 2005 SSAB Oxelsund AB.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -134,6 +134,64 @@ static pwr_tStatus IoRackInit ( ...@@ -134,6 +134,64 @@ static pwr_tStatus IoRackInit (
return IO__SUCCESS; return IO__SUCCESS;
} }
static pwr_tStatus IoRackSwap (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp
)
{
io_sRackLocal *local;
pwr_sClass_Ssab_RemoteRack *op;
int sts;
fd_set fds;
struct timeval tv;
struct bfb_buf rbuf;
int size;
if (!rp->Local) {
sts = IoRackInit(ctx, ap, rp);
if (sts != IO__SUCCESS)
return IO__ERRINIDEVICE;
}
local = (io_sRackLocal *) rp->Local;
op = (pwr_sClass_Ssab_RemoteRack *) rp->op;
// Calc length and send read request
local->read_req.service = BFB_SERVICE_READ;
local->read_req.length = local->next_read_req_item*4 + 4;
sts = send(local->s, &local->read_req, local->read_req.length, 0);
op->TX_packets++;
local->next_read_req_item = 0;
bzero(&local->read_area, sizeof(local->read_area));
sts = 1;
while (sts > 0) {
FD_ZERO(&fds);
FD_SET(local->s, &fds);
tv.tv_sec = 0;
tv.tv_usec = 0;
sts = select(32, &fds, NULL, NULL, &tv);
if (sts > 0) {
size = recv(local->s, &rbuf, sizeof(rbuf), 0);
if (rbuf.service == BFB_SERVICE_READ) {
bzero(&local->read_area, sizeof(local->read_area));
memcpy(&local->read_area, &rbuf, size);
}
else if (rbuf.service == BFB_SERVICE_WRITE) {
bzero(&local->write_area, sizeof(local->write_area));
memcpy(&local->write_area, &rbuf, size);
}
op->RX_packets++;
}
}
return IO__SUCCESS;
}
static pwr_tStatus IoRackClose ( static pwr_tStatus IoRackClose (
io_tCtx ctx, io_tCtx ctx,
io_sAgent *ap, io_sAgent *ap,
...@@ -223,6 +281,7 @@ static pwr_tStatus IoRackWrite ( ...@@ -223,6 +281,7 @@ static pwr_tStatus IoRackWrite (
pwr_dExport pwr_BindIoMethods(Ssab_RemoteRack) = { pwr_dExport pwr_BindIoMethods(Ssab_RemoteRack) = {
pwr_BindIoMethod(IoRackInit), pwr_BindIoMethod(IoRackInit),
pwr_BindIoMethod(IoRackSwap),
pwr_BindIoMethod(IoRackClose), pwr_BindIoMethod(IoRackClose),
pwr_BindIoMethod(IoRackRead), pwr_BindIoMethod(IoRackRead),
pwr_BindIoMethod(IoRackWrite), pwr_BindIoMethod(IoRackWrite),
......
Volume SsabOx $ClassVolume 0.0.250.5 Volume SsabOx $ClassVolume 0.0.250.5
Body SysBody 01-JAN-1970 01:00:00.00 Body SysBody 01-JAN-1970 01:00:00.00
Attr NextOix = "_X160" Attr NextOix = "_X162"
Attr NextCix = "_X30" Attr NextCix = "_X30"
Attr NextTix[0] = "_X5" Attr NextTix[0] = "_X5"
EndBody EndBody
...@@ -145,6 +145,11 @@ Volume SsabOx $ClassVolume 0.0.250.5 ...@@ -145,6 +145,11 @@ Volume SsabOx $ClassVolume 0.0.250.5
Attr MethodName = "Rack_SSAB-IoRackClose" Attr MethodName = "Rack_SSAB-IoRackClose"
EndBody EndBody
EndObject EndObject
Object IoRackSwap $Method 161 18-MAY-2007 10:19:42.40
Body SysBody 18-MAY-2007 10:19:47.20
Attr MethodName = "Rack_SSAB-IoRackSwap"
EndBody
EndObject
EndObject EndObject
Object Template Rack_SSAB 2154004480 01-JAN-1970 01:00:00.00 Object Template Rack_SSAB 2154004480 01-JAN-1970 01:00:00.00
Body RtBody 30-DEC-2005 14:46:17.32 Body RtBody 30-DEC-2005 14:46:17.32
...@@ -3815,6 +3820,11 @@ Volume SsabOx $ClassVolume 0.0.250.5 ...@@ -3815,6 +3820,11 @@ Volume SsabOx $ClassVolume 0.0.250.5
Attr MethodName = "Ssab_Do-IoCardWrite" Attr MethodName = "Ssab_Do-IoCardWrite"
EndBody EndBody
EndObject EndObject
Object IoCardSwap $Method 162 18-MAY-2007 10:20:35.84
Body SysBody 18-MAY-2007 10:20:39.25
Attr MethodName = "Ssab_Do-IoCardSwap"
EndBody
EndObject
EndObject EndObject
EndObject EndObject
!/** !/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment