/*----------------------------------------------------------------------------*\
   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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
/*----------------------------------------------------------------------------*\
   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;
}
Beispiel #7
0
/*----------------------------------------------------------------------------*\
  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;
}