/*----------------------------------------------------------------------------*\ Read method for the Modbus RTU server module \*----------------------------------------------------------------------------*/ static pwr_tStatus IoCardRead ( io_tCtx ctx, io_sAgent *ap, io_sRack *rp, io_sCard *cp ) { io_sServerModuleLocal *local; io_sServerLocal *local_server; pwr_sClass_Modbus_RTU_ServerModule *op; pwr_sClass_Modbus_RTU_Server *server; op = (pwr_sClass_Modbus_RTU_ServerModule *) cp->op; local = (io_sServerModuleLocal *) cp->Local; server = (pwr_sClass_Modbus_RTU_Server *) rp->op; local_server = (io_sServerLocal *) rp->Local; if ( server->DisableServer || !local) return IO__SUCCESS; if (server->Status == MB__NORMAL) { thread_MutexLock( &local_server->mutex); io_bus_card_read(ctx, rp, cp, local->input_area, NULL, pwr_eByteOrderingEnum_BigEndian, pwr_eFloatRepEnum_FloatIntel); thread_MutexUnlock( &local_server->mutex); } // printf("Method Modbus_Module-IoCardRead\n"); return IO__SUCCESS; }
/*----------------------------------------------------------------------------*\ Read method for the Pb module \*----------------------------------------------------------------------------*/ static pwr_tStatus IoCardRead ( io_tCtx ctx, io_sAgent *ap, io_sRack *rp, io_sCard *cp ) { io_sCardLocal *local; pwr_sClass_Modbus_ModuleReadWrite *op; pwr_sClass_Modbus_TCP_Slave *slave; op = (pwr_sClass_Modbus_ModuleReadWrite *) cp->op; local = (io_sCardLocal *) cp->Local; slave = (pwr_sClass_Modbus_TCP_Slave *) rp->op; if ( op->Read.ScanInterval > 1) { local->msg[0].has_read_method = 1; if ( local->msg[0].interval_cnt != 0) { local->msg[0].interval_cnt++; if ( local->msg[0].interval_cnt >= op->Read.ScanInterval) local->msg[0].interval_cnt = 0; return IO__SUCCESS; } local->msg[0].interval_cnt++; } if (slave->Status == MB__NORMAL) { io_bus_card_read(ctx, rp, cp, slave->Inputs, NULL, pwr_eByteOrderingEnum_BigEndian, pwr_eFloatRepEnum_FloatIntel); } return IO__SUCCESS; }
/*----------------------------------------------------------------------------*\ Read method for the Modbus RTU module \*----------------------------------------------------------------------------*/ static pwr_tStatus IoCardRead( io_tCtx ctx, io_sAgent* ap, io_sRack* rp, io_sCard* cp) { io_sCardLocalMsg* local; io_sRackLocal* local_rack = (io_sRackLocal*)rp->Local; pwr_sClass_Modbus_RTU_Module* op; pwr_sClass_Modbus_RTU_Slave* slave; if (!((io_sAgentLocal*)ap->Local)->initialized) return IO__SUCCESS; op = (pwr_sClass_Modbus_RTU_Module*)cp->op; local = ((io_sCardLocal*)cp->Local)->msg; slave = (pwr_sClass_Modbus_RTU_Slave*)rp->op; if (op->ScanInterval > 1) { local->has_read_method = 1; if (local->interval_cnt != 0) { local->interval_cnt++; if (local->interval_cnt >= op->ScanInterval) local->interval_cnt = 0; return IO__SUCCESS; } local->interval_cnt++; } if (slave->Status == MB__NORMAL || local_rack->reset_inputs) { io_bus_card_read(ctx, rp, cp, slave->Inputs, NULL, pwr_eByteOrderingEnum_BigEndian, pwr_eFloatRepEnum_FloatIntel); } // printf("Method Modbus_RTU_Module-IoCardRead\n"); return IO__SUCCESS; }
/*----------------------------------------------------------------------------*\ Read method for the Pb FDL Data transfer module \*----------------------------------------------------------------------------*/ static pwr_tStatus IoCardRead( io_tCtx ctx, io_sAgent* ap, io_sRack* rp, io_sCard* cp) { io_sFDLCardLocal* local = (io_sFDLCardLocal*)cp->Local; io_bus_card_read(ctx, rp, cp, local->input_area, 0, local->byte_ordering, local->float_representation); return IO__SUCCESS; }
static pwr_tStatus IoCardRead( io_tCtx ctx, io_sAgent *ap, io_sRack *rp, io_sCard *cp) { io_sLocalSPI_Slave *local = (io_sLocalSPI_Slave *)cp->Local; pwr_sClass_SPI_Slave *op = (pwr_sClass_SPI_Slave *)cp->op; int sts; int i; // sts = read( local->fd, local->input_area, local->input_area_size); for ( i = 0; i < local->input_area_size; i++) { sts = read( local->fd, &local->input_area[i], 1); if ( sts != 1) break; } if ( sts < 0) { op->ErrorCount++; if ( !local->readerror_logged) { errh_Error( "SPI read error errno %d, '%s'", errno, cp->Name); local->readerror_logged = 1; } op->Status = IOM__SPI_READERROR; } //else if ( sts != local->input_area_size) { else if ( sts == 0) { op->ErrorCount++; if ( !local->readerror_logged) { errh_Error( "SPI read buffer smaller than expected: %d, '%s'", sts, cp->Name); local->readerror_logged = 1; } op->Status = IOM__SPI_READERROR; } else { local->readerror_logged = 0; op->Status = IOM__SPI_NORMAL; io_bus_card_read( ctx, rp, cp, local->input_area, 0, local->byte_ordering, pwr_eFloatRepEnum_FloatIEEE); } if ( op->ErrorSoftLimit && op->ErrorCount == op->ErrorSoftLimit && !local->softlimit_logged) { errh_Warning( "IO Card ErrorSoftLimit reached, '%s'", cp->Name); local->softlimit_logged = 1; } if ( op->ErrorHardLimit && op->ErrorCount >= op->ErrorHardLimit) { errh_Error( "IO Card ErrorHardLimit reached '%s', IO stopped", cp->Name); ctx->Node->EmergBreakTrue = 1; return IO__ERRDEVICE; } return IO__SUCCESS; }
/*----------------------------------------------------------------------------*\ Read method for the Pn module \*----------------------------------------------------------------------------*/ static pwr_tStatus IoCardRead( io_tCtx ctx, io_sAgent* ap, io_sRack* rp, io_sCard* cp) { io_sPnCardLocal* local; pwr_sClass_PnModule* op; pwr_sClass_PnDevice* slave; op = (pwr_sClass_PnModule*)cp->op; local = (io_sPnCardLocal*)cp->Local; slave = (pwr_sClass_PnDevice*)rp->op; op->Status = slave->Status; /* I/O-read operations should always be made. This ensures correct values */ /* on all inputs. Default StallAction is ResetInputs which means that */ /* all inputs will be zeroed */ io_bus_card_read(ctx, rp, cp, local->input_area, 0, slave->ByteOrdering, slave->FloatRepresentation); return IO__SUCCESS; }
/*----------------------------------------------------------------------------*\ Read method for the Powerlink master \*----------------------------------------------------------------------------*/ static pwr_tStatus IoAgentRead( io_tCtx ctx, io_sAgent *ap) { io_sLocalEpl_MN *local = (io_sLocalEpl_MN *)ap->Local; io_sLocalEpl_CN *local1; pwr_sClass_Epl_MN *op = (pwr_sClass_Epl_MN *)ap->op; io_sRack *rp; io_sCard *cp; pwr_tUInt32 error_count = 0; int ret = IO__SUCCESS; if(!ap->Local) return ret; // Remeber the time when this functions was called the first time if( local->init == 0) { clock_gettime(CLOCK_REALTIME, &local->boot); local->init = 1; } // Time now (tps = time when bad state occurred) clock_gettime(CLOCK_REALTIME, &local->tpe); error_count = op->ErrorCount; // Add to error count if agent changed from good to bad state and setup is complete if( local->prevState == pwr_eEplNmtState_EplNmtMsOperational && op->NmtState != pwr_eEplNmtState_EplNmtMsOperational && ( (local->tpe).tv_sec - (local->boot).tv_sec) >= op->StartupTimeout) op->ErrorCount++; // Copy Powerlink process image to temp memory (only if stallaction=resetinputs else tmp_area=input_area) if( local->inputResetEnabled) memcpy( local->tmp_area , local->input_area, local->input_area_size); // If no bad state and were still in startup there can be no error (else remember when error occurred) if( op->NmtState == pwr_eEplNmtState_EplNmtMsOperational || ( (local->tpe).tv_sec - (local->boot).tv_sec) < op->StartupTimeout) { (local->tps).tv_sec = 0; local->timeoutStatus = 0; } else if( (local->tps).tv_sec == 0) { clock_gettime(CLOCK_REALTIME, &local->tps); } // Agent error soft limit reached, tell log (once) if ( op->ErrorCount >= op->ErrorSoftLimit && error_count < op->ErrorSoftLimit) { errh_Warning( "IO Agent ErrorSoftLimit reached, '%s'", ap->Name); } // Agent error hard limit reached, tell log (once) if ( op->ErrorCount >= op->ErrorHardLimit && error_count < op->ErrorHardLimit) { if( op->StallAction == pwr_eStallActionEnum_EmergencyBreak) { errh_Error( "IO Agent ErrorHardLimit reached '%s', IO stopped", ap->Name); } else errh_Error( "IO Agent ErrorHardLimit reached '%s'", ap->Name); } // Agent timeout has elapsed, tell log (once) if( ( (local->tpe).tv_sec - (local->tps).tv_sec) >= op->Timeout && local->timeoutStatus == 0 && (local->tps).tv_sec != 0) { local->timeoutStatus = 1; if( op->StallAction == pwr_eStallActionEnum_EmergencyBreak) { errh_Error( "IO Agent timeout time elapsed '%s', IO stopped", ap->Name); } else if( op->StallAction == pwr_eStallActionEnum_ResetInputs) { errh_Error( "IO Agent timeout time elapsed '%s', IO input area reset", ap->Name); } else errh_Error( "IO Agent timeout time elapsed '%s'", ap->Name); } // Agent error hard limit reached, take action (always) if ( op->ErrorCount >= op->ErrorHardLimit) { if( op->StallAction == pwr_eStallActionEnum_EmergencyBreak) { ctx->Node->EmergBreakTrue = 1; errh_SetStatus(PWR__SRVFATAL); IoAgentClose(ctx, ap); } ret = IO__ERRDEVICE; } // Agent timeout time elapsed, take action (always) if ( ( (local->tpe).tv_sec - (local->tps).tv_sec) >= op->Timeout && (local->tps).tv_sec != 0) { if( op->StallAction == pwr_eStallActionEnum_EmergencyBreak) { ctx->Node->EmergBreakTrue = 1; errh_SetStatus(PWR__SRVFATAL); IoAgentClose(ctx, ap); } else if( op->StallAction == pwr_eStallActionEnum_ResetInputs) { memset( local->tmp_area, 0, local->input_area_size); } ret = IO__ERRDEVICE; } // Remember agent state til next scan local->prevState = op->NmtState; // Loop through all slaves for ( rp = ap->racklist; rp; rp = rp->next) { ((pwr_sClass_Epl_CN *)rp->op)->Status = ((pwr_sClass_Epl_CN *)rp->op)->NmtState == pwr_eEplNmtState_EplNmtCsOperational ? IOM__EPL_OPER : IOM__EPL_NOOPER; local1 = (io_sLocalEpl_CN *)rp->Local; // Time now (tps = time when bad state occurred) clock_gettime(CLOCK_REALTIME, &local1->tpe); error_count = ((pwr_sClass_Epl_CN *)rp->op)->ErrorCount; // Add to error count if slave changed from good to bad state and setup is complete if( local1->prevState == pwr_eEplNmtState_EplNmtCsOperational && ((pwr_sClass_Epl_CN *)rp->op)->NmtState != pwr_eEplNmtState_EplNmtCsOperational && ( (local1->tpe).tv_sec - (local->boot).tv_sec) >= op->StartupTimeout) ((pwr_sClass_Epl_CN *)rp->op)->ErrorCount++; // Save time when bad state occurs if( ( (pwr_sClass_Epl_CN *)rp->op)->NmtState == pwr_eEplNmtState_EplNmtCsOperational || ( (local1->tpe).tv_sec - (local->boot).tv_sec) < op->StartupTimeout) { (local1->tps).tv_sec = 0; local1->timeoutStatus = 0; } else if( (local1->tps).tv_sec == 0) clock_gettime(CLOCK_REALTIME, &local1->tps); // Slave error soft limit reached, tell log (once) if ( ((pwr_sClass_Epl_CN *)rp->op)->ErrorCount >= ((pwr_sClass_Epl_CN *)rp->op)->ErrorSoftLimit && error_count < ((pwr_sClass_Epl_CN *)rp->op)->ErrorSoftLimit) { errh_Warning( "IO Rack ErrorSoftLimit reached, '%s'", rp->Name); } // Slave error hard limit reached, tell log (once) if ( ((pwr_sClass_Epl_CN *)rp->op)->ErrorCount >= ((pwr_sClass_Epl_CN *)rp->op)->ErrorHardLimit && error_count < ((pwr_sClass_Epl_CN *)rp->op)->ErrorHardLimit) { if( ((pwr_sClass_Epl_CN *)rp->op)->StallAction == pwr_eStallActionEnum_EmergencyBreak) { errh_Error( "IO Rack ErrorHardLimit reached '%s', IO stopped", rp->Name); } else errh_Error( "IO Rack ErrorHardLimit reached '%s'", rp->Name); } // Slave timeout has elapsed, tell log (once) if( ( (local1->tpe).tv_sec - (local1->tps).tv_sec) >= ((pwr_sClass_Epl_CN *)rp->op)->Timeout && local1->timeoutStatus == 0 && (local1->tps).tv_sec != 0) { local1->timeoutStatus = 1; if( ((pwr_sClass_Epl_CN *)rp->op)->StallAction == pwr_eStallActionEnum_EmergencyBreak) { errh_Error( "Rack timeout time elapsed '%s', IO stopped", rp->Name); } else if( ((pwr_sClass_Epl_CN *)rp->op)->StallAction == pwr_eStallActionEnum_ResetInputs) { errh_Error( "Rack timeout time elapsed '%s', IO input area reset", rp->Name); } else errh_Error( "Rack timeout time elapsed '%s'", rp->Name); } // Slave error hard limit reached, take action (always) if ( ((pwr_sClass_Epl_CN *)rp->op)->ErrorCount >= ((pwr_sClass_Epl_CN *)rp->op)->ErrorHardLimit) { if( ((pwr_sClass_Epl_CN *)rp->op)->StallAction == pwr_eStallActionEnum_EmergencyBreak) { ctx->Node->EmergBreakTrue = 1; errh_SetStatus(PWR__SRVFATAL); IoAgentClose(ctx, ap); } ret = IO__ERRDEVICE; } // Slave timeout elapsed, take action (always) if( ( (local1->tpe).tv_sec - (local1->tps).tv_sec) >= ((pwr_sClass_Epl_CN *)rp->op)->Timeout && (local1->tps).tv_sec != 0) { if( ((pwr_sClass_Epl_CN *)rp->op)->StallAction == pwr_eStallActionEnum_EmergencyBreak) { ctx->Node->EmergBreakTrue = 1; errh_SetStatus(PWR__SRVFATAL); IoAgentClose(ctx, ap); } else if( ((pwr_sClass_Epl_CN *)rp->op)->StallAction == pwr_eStallActionEnum_ResetInputs) { memset( local->tmp_area + ((pwr_sClass_Epl_CN *)rp->op)->InputAreaOffset, 0, ((pwr_sClass_Epl_CN *)rp->op)->InputAreaSize); } ret = IO__ERRDEVICE; } // Remeber slave state til next scan local1->prevState = ((pwr_sClass_Epl_CN *)rp->op)->NmtState; // Update Proview chan-objects with data from Powerlink process image for ( cp = rp->cardlist; cp; cp = cp->next) { io_bus_card_read( ctx, rp, cp, local->tmp_area, 0, ((io_sLocalEpl_CN *)rp->Local)->byte_ordering, pwr_eFloatRepEnum_FloatIEEE); } } return ret; }