tEplKernel EdrvCyclicSetNextTxBufferList(tEdrvTxBuffer** apTxBuffer_p, unsigned int uiTxBufferCount_p)
{
tEplKernel  Ret = kEplSuccessful;
unsigned int    uiNextTxBufferList;

    uiNextTxBufferList = EdrvCyclicInstance_l.m_uiCurTxBufferList ^ EdrvCyclicInstance_l.m_uiMaxTxBufferCount;

    // check if next list is free
    if (EdrvCyclicInstance_l.m_paTxBufferList[uiNextTxBufferList] != NULL)
    {
        Ret = kEplEdrvNextTxListNotEmpty;
        goto Exit;
    }

    if ((uiTxBufferCount_p == 0)
        || (uiTxBufferCount_p > EdrvCyclicInstance_l.m_uiMaxTxBufferCount))
    {
        Ret = kEplEdrvInvalidParam;
        goto Exit;
    }

    // check if last entry in list equals a NULL pointer
    if (apTxBuffer_p[uiTxBufferCount_p - 1] != NULL)
    {
        Ret = kEplEdrvInvalidParam;
        goto Exit;
    }

    EPL_MEMCPY(&EdrvCyclicInstance_l.m_paTxBufferList[uiNextTxBufferList], apTxBuffer_p, sizeof (*apTxBuffer_p) * uiTxBufferCount_p);

Exit:
    return Ret;
}
tEplKernel PUBLIC EplEventkPostError(tEplEventSource EventSource_p,
                                     tEplKernel      EplError_p,
                                     unsigned int    uiArgSize_p,
                                     void*           pArg_p)
{
tEplKernel      Ret;
tEplEventError  EventError;
tEplEvent       EplEvent;

    Ret = kEplSuccessful;

    // create argument
    EventError.m_EventSource = EventSource_p;
    EventError.m_EplError = EplError_p;
    uiArgSize_p = (unsigned int) min ((size_t) uiArgSize_p, sizeof (EventError.m_Arg));
    EPL_MEMCPY(&EventError.m_Arg, pArg_p, uiArgSize_p);

    // create event
    EplEvent.m_EventType = kEplEventTypeError;
    EplEvent.m_EventSink = kEplEventSinkApi;
    EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(EplEvent.m_NetTime));
    EplEvent.m_uiSize = (memberoffs (tEplEventError, m_Arg) + uiArgSize_p);
    EplEvent.m_pArg = &EventError;

    // post errorevent
    Ret = EplEventkPost(&EplEvent);

    return Ret;
}
 //---------------------------------------------------------------------------
//
// Function:    EplTimeruModifyTimerMs
//
// Description: function change a timer and return a handle to the pointer
//
//
//
// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
//              ulTime_p    = time for timer in ms
//              Argument_p  = argument for timer
//
//
// Returns:     tEplKernel  = errorcode
//
//
// State:
//
//---------------------------------------------------------------------------
tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
					 unsigned long ulTime_p,
					 tEplTimerArg Argument_p)
{
	tEplKernel Ret;
	HANDLE DeleteHandle;
	HANDLE ThreadHandle;
	DWORD ThreadId;

	Ret = kEplSuccessful;

	// check parameter
	if (pTimerHdl_p == NULL) {
		Ret = kEplTimerInvalidHandle;
		goto Exit;
	}

	DeleteHandle = (HANDLE) (*pTimerHdl_p);

	// set event to end timer task for this timer
	SetEvent(DeleteHandle);

	// create new timer
	// first create event to delete timer
	DeleteHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (DeleteHandle == NULL) {
		Ret = kEplTimerNoTimerCreated;
		goto Exit;
	}
	// set handle for caller
	*pTimerHdl_p = (tEplTimerHdl) DeleteHandle;

	// enter  critical section
	EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);

	// fill data for thread
	ThreadData_l.DelteHandle = DeleteHandle;
	EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p,
		   sizeof(tEplTimerArg));
	ThreadData_l.ulTimeout = ulTime_p;

	// create thread to create waitable timer and wait for timer
	ThreadHandle = CreateThread(NULL,
				    0,
				    EplSdoTimeruThreadms,
				    &ThreadData_l, 0, &ThreadId);
	if (ThreadHandle == NULL) {
		// leave critical section
		LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);

		// delte handle

		Ret = kEplTimerNoTimerCreated;
		goto Exit;
	}

      Exit:
	return Ret;
}
예제 #4
0
static tEplKernel EplIdentuCbIdentResponse(tEplFrameInfo *pFrameInfo_p)
{
	tEplKernel Ret = kEplSuccessful;
	unsigned int uiNodeId;
	unsigned int uiIndex;
	tEplIdentuCbResponse pfnCbResponse;

	uiNodeId = AmiGetByteFromLe(&pFrameInfo_p->m_pFrame->m_le_bSrcNodeId);

	uiIndex = uiNodeId - 1;

	if (uiIndex < tabentries(EplIdentuInstance_g.m_apfnCbResponse)) {
		// memorize pointer to callback function
		pfnCbResponse = EplIdentuInstance_g.m_apfnCbResponse[uiIndex];
		// reset callback function pointer so that caller may issue next request immediately
		EplIdentuInstance_g.m_apfnCbResponse[uiIndex] = NULL;

		if (pFrameInfo_p->m_uiFrameSize < EPL_C_DLL_MINSIZE_IDENTRES) {	// IdentResponse not received or it has invalid size
			if (pfnCbResponse == NULL) {	// response was not requested
				goto Exit;
			}
			Ret = pfnCbResponse(uiNodeId, NULL);
		} else {	// IdentResponse received
			if (EplIdentuInstance_g.m_apIdentResponse[uiIndex] == NULL) {	// memory for IdentResponse must be allocated
				EplIdentuInstance_g.m_apIdentResponse[uiIndex] =
				    EPL_MALLOC(sizeof(tEplIdentResponse));
				if (EplIdentuInstance_g.m_apIdentResponse[uiIndex] == NULL) {	// malloc failed
					if (pfnCbResponse == NULL) {	// response was not requested
						goto Exit;
					}
					Ret =
					    pfnCbResponse(uiNodeId,
							  &pFrameInfo_p->
							  m_pFrame->m_Data.
							  m_Asnd.m_Payload.
							  m_IdentResponse);
					goto Exit;
				}
			}
			// copy IdentResponse to instance structure
			EPL_MEMCPY(EplIdentuInstance_g.
				   m_apIdentResponse[uiIndex],
				   &pFrameInfo_p->m_pFrame->m_Data.m_Asnd.
				   m_Payload.m_IdentResponse,
				   sizeof(tEplIdentResponse));
			if (pfnCbResponse == NULL) {	// response was not requested
				goto Exit;
			}
			Ret =
			    pfnCbResponse(uiNodeId,
					  EplIdentuInstance_g.
					  m_apIdentResponse[uiIndex]);
		}
	}

      Exit:
	return Ret;
}
예제 #5
0
tEplKernel PUBLIC EplApiInitialize(tEplApiInitParam * pInitParam_p)
{
tEplKernel   Ret = kEplSuccessful;
const char*  pszDrvName;                // driver name
int          iRet;

    // reset instance structure
    EPL_MEMSET(&EplApiInstance_g, 0, sizeof (EplApiInstance_g));

    EPL_MEMCPY(&EplApiInstance_g.m_InitParam, pInitParam_p,
        (sizeof (tEplApiInitParam) < pInitParam_p->m_uiSizeOfStruct) ? sizeof (tEplApiInitParam) : pInitParam_p->m_uiSizeOfStruct);

    // check event callback function pointer
    if (EplApiInstance_g.m_InitParam.m_pfnCbEvent == NULL)
    {   // application must always have an event callback function
        Ret = kEplApiInvalidParam;
        goto Exit;
    }

    pszDrvName = "/dev/"EPLLIN_DEV_NAME;
    EplApiInstance_g.m_hDrvInst = -1;

    // open driver
    TRACE1("EPL: Try to open driver '%s'\n", pszDrvName);
    EplApiInstance_g.m_hDrvInst = open (pszDrvName, O_RDWR);
    if (EplApiInstance_g.m_hDrvInst > -1)
    {
        TRACE2("EPL: open '%s' successful -> hDrvInst=%d\n", pszDrvName, EplApiInstance_g.m_hDrvInst);
    }
    else
    {
        TRACE1("EPL: ERROR: Can't open '%s'\n", pszDrvName);
        Ret = kEplNoResource;
        goto Exit;
    }

    // initialize hardware
    iRet = ioctl (EplApiInstance_g.m_hDrvInst, EPLLIN_CMD_INITIALIZE, (unsigned long)&EplApiInstance_g.m_InitParam);
    if (iRet < 0)
    {
        Ret = kEplNoResource;
        goto Exit;
    }
    else
    {
        Ret = (tEplKernel)iRet;
    }

    // the application must start NMT state machine
    // via EplApiExecNmtCommand(kEplNmtEventSwReset)
    // and thereby the whole EPL stack :-)
/*#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
    Ret = EplNmtuNmtEvent(kEplNmtEventSwReset);
#endif*/

Exit:
    return Ret;
}
예제 #6
0
tEplKernel PUBLIC EplTimeruProcess(void)
{
tTimerEntry*        pTimerEntry;
DWORD               dwTimeoutMs;
tEplEvent           EplEvent;
tEplTimerEventArg   TimerEventArg;
tEplKernel          Ret;


    Ret      = kEplSuccessful;

    EplTimeruEnterCriticalSection(TIMERU_TIMER_LIST);
    // calculate elapsed time since start time
    dwTimeoutMs = EplTimeruGetTickCountMs() - EplTimeruInstance_g.m_dwStartTimeMs;

    // observe first timer entry in timer list
    pTimerEntry = EplTimeruInstance_g.m_pTimerListFirst;
    if (pTimerEntry != NULL)
    {
        if (dwTimeoutMs >= pTimerEntry->m_dwTimeoutMs)
        {   // timeout elapsed
            // remove entry from timer list
            EplTimeruInstance_g.m_pTimerListFirst = pTimerEntry->m_pNext;

            // adjust start time
            EplTimeruInstance_g.m_dwStartTimeMs += pTimerEntry->m_dwTimeoutMs;
        }
        else
        {
            pTimerEntry = NULL;
        }
    }
    EplTimeruLeaveCriticalSection(TIMERU_TIMER_LIST);

    if (pTimerEntry != NULL)
    {
        // call event function
        TimerEventArg.m_TimerHdl = (tEplTimerHdl) pTimerEntry;
        EPL_MEMCPY(&TimerEventArg.m_Arg, &pTimerEntry->m_TimerArg.m_Arg, sizeof (TimerEventArg.m_Arg));
    
        EplEvent.m_EventSink = pTimerEntry->m_TimerArg.m_EventSink;
        EplEvent.m_EventType = kEplEventTypeTimer;
        EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime));
        EplEvent.m_pArg = &TimerEventArg;
        EplEvent.m_uiSize = sizeof(TimerEventArg);

        Ret = EplEventuPost(&EplEvent);
    }

    return Ret;
}
//---------------------------------------------------------------------------
//
// Function:    VEthAddInstance
//
// Description: Add a VEth instance
//
// Parameters: abSrcMac_p = The MAC Address to set
//
// Returns:     tEplKernel              = error code
//
//
// State:
//
//---------------------------------------------------------------------------
tEplKernel PUBLIC VEthAddInstance(const BYTE abSrcMac_p[6])
{
    tEplKernel  Ret = kEplSuccessful;

    EPL_MEMSET(&VEthInstance_g, 0 , sizeof(VEthInstance_g));

    EPL_MEMCPY(VEthInstance_g.m_abEthMac, abSrcMac_p, sizeof(VEthInstance_g.m_abEthMac) );

    Ret = VEthOpen();
    if(Ret != kEplSuccessful)
    {
        EPL_DBGLVL_VETH_TRACE("VEthOpen: returned 0x%02X\n", Ret);
    }

    return Ret;
}
예제 #8
0
tEplKernel PUBLIC EplApiProcessImageExchangeOut(tEplApiProcessImage* pPI_p)
{
tEplKernel      Ret = kEplSuccessful;

#if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0
    #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
        copy_from_user(EplApiProcessImageInstance_g.m_abProcessImageOutput,
            pPI_p->m_pImage,
            min(pPI_p->m_uiSize, sizeof (EplApiProcessImageInstance_g.m_abProcessImageOutput)));
    #else
        EPL_MEMCPY(EplApiProcessImageInstance_g.m_abProcessImageOutput,
            pPI_p->m_pImage,
            min(pPI_p->m_uiSize, sizeof (EplApiProcessImageInstance_g.m_abProcessImageOutput)));
    #endif
#endif

    return Ret;
}
tEplKernel EplTimeruModifyTimerMs(tEplTimerHdl *pTimerHdl_p,
				  unsigned long ulTime_p,
				  tEplTimerArg Argument_p)
{
	tEplKernel Ret = kEplSuccessful;
	tEplTimeruData *pData;

	// check pointer to handle
	if (pTimerHdl_p == NULL) {
		Ret = kEplTimerInvalidHandle;
		goto Exit;
	}
	// check handle itself, i.e. was the handle initialized before
	if (*pTimerHdl_p == 0) {
		Ret = EplTimeruSetTimerMs(pTimerHdl_p, ulTime_p, Argument_p);
		goto Exit;
	}
	pData = (tEplTimeruData *) * pTimerHdl_p;
	if ((tEplTimeruData *) pData->m_Timer.data != pData) {
		Ret = kEplTimerInvalidHandle;
		goto Exit;
	}

	mod_timer(&pData->m_Timer, (jiffies + ulTime_p * HZ / 1000));

	// copy the TimerArg after the timer is restarted,
	// so that a timer occured immediately before mod_timer
	// won't use the new TimerArg and
	// therefore the old timer cannot be distinguished from the new one.
	// But if the new timer is too fast, it may get lost.
	EPL_MEMCPY(&pData->TimerArgument, &Argument_p, sizeof(tEplTimerArg));

	// check if timer is really running
	if (timer_pending(&pData->m_Timer) == 0) {	// timer is not running
		// retry starting it
		add_timer(&pData->m_Timer);
	}
	// set handle to pointer of tEplTimeruData
//    *pTimerHdl_p = (tEplTimerHdl) pData;

      Exit:
	return Ret;
}
예제 #10
0
/*----------------------------------------------------------------------------*\
  Init method for the Powerlink module
  \*----------------------------------------------------------------------------*/
static pwr_tStatus IoAgentInit (io_tCtx ctx, io_sAgent *ap) {
  io_sLocalEpl_MN *local;
  int sts;
  pwr_sClass_Epl_MN *op = (pwr_sClass_Epl_MN *)ap->op;
	
  local = (io_sLocalEpl_MN *) calloc( 1, sizeof(io_sLocalEpl_MN));
  ap->Local = local;
  local->inputResetEnabled = 0;
  op->NumberOfSlaves = 0;
	
  static tEplApiInitParam EplApiInitParam;
  tEplKernel EplRet = kEplSuccessful;
  pwr_tFileName cdc_file;
  char* sHostname = malloc(1023);
    
  if ( strchr(op->CDCfile, '/') != 0)
    strcpy( cdc_file, op->CDCfile);
  else {
    strcpy( cdc_file, "$pwrp_load/");
    strcat( cdc_file, op->CDCfile);
  }
  dcli_translate_filename( cdc_file, cdc_file);
  gethostname(sHostname, 1023);
	
  if( op->StallAction == pwr_eStallActionEnum_ResetInputs)
    local->inputResetEnabled = 1;
	
  // Init the I/O area
  unsigned int input_area_offset = 0;
  unsigned int input_area_chansize = 0;
  unsigned int output_area_offset = 0;
  unsigned int output_area_chansize = 0;
  io_sRack *rp;
  io_sCard *cp;
  pwr_tCid cid;

  for ( rp = ap->racklist; rp; rp = rp->next) {
    rp->Local =  calloc( 1, sizeof(io_sLocalEpl_CN));
    rp->MethodDisabled = 1;
    op->NumberOfSlaves++;
		
    if( ((pwr_sClass_Epl_CN *)rp->op)->StallAction == pwr_eStallActionEnum_ResetInputs)
      local->inputResetEnabled = 1;
		
    // Show device offset and size
    if ( rp->Class == pwr_cClass_Epl_CN && rp->op) {
      ((pwr_sClass_Epl_CN *)rp->op)->InputAreaOffset = input_area_offset + input_area_chansize;
      ((pwr_sClass_Epl_CN *)rp->op)->OutputAreaOffset = output_area_offset + output_area_chansize;
    }
		
    // Get byte ordering
    pwr_tAName name;
    pwr_tEnum byte_ordering;

    strcpy( name, rp->Name);
    strcat( name, ".ByteOrdering");
    sts = gdh_GetObjectInfo( name, &byte_ordering, sizeof(byte_ordering));
    if ( ODD(sts))
      ((io_sLocalEpl_CN *)rp->Local)->byte_ordering = byte_ordering;
    else
      ((io_sLocalEpl_CN *)rp->Local)->byte_ordering = 
	pwr_eByteOrderingEnum_LittleEndian;

    for ( cp = rp->cardlist; cp; cp = cp->next) {			
      cid = cp->Class;
      while ( ODD( gdh_GetSuperClass( cid, &cid, cp->Objid))) ;

      cp->MethodDisabled = 1;

      // Show module offset and size
      if ( cid == pwr_cClass_Epl_Module && cp->op) {
	((pwr_sClass_Epl_Module *)cp->op)->InputAreaOffset = 
	  input_area_offset + input_area_chansize;
	((pwr_sClass_Epl_Module *)cp->op)->OutputAreaOffset = 
	  output_area_offset + output_area_chansize;
      }
			
      io_bus_card_init( ctx, cp, &input_area_offset, &input_area_chansize, 
			&output_area_offset, &output_area_chansize, byte_ordering, 
			io_eAlignment_Powerlink);
			
      // Show module offset and size
      if ( cid == pwr_cClass_Epl_Module && cp->op) {
	((pwr_sClass_Epl_Module *)cp->op)->InputAreaSize = 
	  input_area_offset + input_area_chansize - ((pwr_sClass_Epl_Module *)cp->op)->InputAreaOffset;
	((pwr_sClass_Epl_Module *)cp->op)->OutputAreaSize = 
	  output_area_offset + output_area_chansize - ((pwr_sClass_Epl_Module *)cp->op)->OutputAreaOffset;
      }
			
      if(rp->next == NULL) {
	if(cp->next == NULL) {
	  ((pwr_sClass_Epl_Module *)cp->op)->InputAreaSize += 
	    pwr_Align(input_area_offset + input_area_chansize, 4) - 
	    (input_area_offset + input_area_chansize);
	  ((pwr_sClass_Epl_Module *)cp->op)->OutputAreaSize += 
	    pwr_Align(output_area_offset + output_area_chansize, 4) - 
	    (output_area_offset + output_area_chansize);
	}
      }
    }

    // Show slave offset and size
    if ( rp->Class == pwr_cClass_Epl_CN && rp->op) {
      ((pwr_sClass_Epl_CN *)rp->op)->InputAreaSize = input_area_offset + 
	input_area_chansize - ((pwr_sClass_Epl_CN *)rp->op)->InputAreaOffset;
      ((pwr_sClass_Epl_CN *)rp->op)->OutputAreaSize = output_area_offset + 
	output_area_chansize - ((pwr_sClass_Epl_CN *)rp->op)->OutputAreaOffset;
      if(rp->next == NULL) {
	((pwr_sClass_Epl_CN *)rp->op)->InputAreaSize += 
	  pwr_Align(input_area_offset + input_area_chansize, 4) - (input_area_offset + input_area_chansize);
	((pwr_sClass_Epl_CN *)rp->op)->OutputAreaSize += 
	  pwr_Align(output_area_offset + output_area_chansize, 4) - (output_area_offset + output_area_chansize);	
      }
    }		
  }

	
  // This is the calculated in- and outputarea size
  local->input_area_size = pwr_Align(input_area_offset + input_area_chansize, 4);
  local->output_area_size = pwr_Align(output_area_offset + output_area_chansize, 4);
	
  // Show agent in- and output area size
  op->InputAreaSize = local->input_area_size;
  op->OutputAreaSize = local->output_area_size;
	
  struct sched_param          schedParam;

  // adjust process priority
  // push nice level in case we have no RTPreempt
  if (nice (-20) == -1) {
    errh_Error("%s() couldn't set nice value! (%s)", __func__, strerror(errno));
  }
  //schedParam.sched_priority = MIN(sched_get_priority_max(SCHED_FIFO), 
  //				  sched_get_priority_min(SCHED_FIFO) + op->Priority);
  schedParam.__sched_priority = op->Priority;
  if (pthread_setschedparam(pthread_self(), SCHED_RR, &schedParam) != 0) {
    errh_Error("%s() couldn't set thread scheduling parameters! %d", __func__, schedParam.__sched_priority);
  }
    
  // binds all openPOWERLINK threads to the second CPU core
  cpu_set_t                   affinity;

  CPU_ZERO(&affinity);
  CPU_SET(1, &affinity);
  sched_setaffinity(0, sizeof(cpu_set_t), &affinity);
		
  // Initialize target specific stuff
  EplTgtInit();

  EPL_MEMSET(&EplApiInitParam, 0, sizeof (EplApiInitParam));
  EplApiInitParam.m_uiSizeOfStruct = sizeof (EplApiInitParam);
  EplApiInitParam.m_pEventUserArg = ap;

  // Get devicename from attribute in agent
  EplApiInitParam.m_HwParam.m_pszDevName = op->Device;

  // Get nodeid from attribute in agent
  EplApiInitParam.m_uiNodeId = op->NodeId;
  
  EplApiInitParam.m_dwIpAddress = ntohl( inet_addr( op->IpAddress));

  // write 00:00:00:00:00:00 to MAC address, so that the driver uses the real hardware address 
  EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr, sizeof (EplApiInitParam.m_abMacAddress));

  EplApiInitParam.m_fAsyncOnly = FALSE;

  EplApiInitParam.m_dwFeatureFlags            = -1;
  // required for error detection
  EplApiInitParam.m_dwCycleLen                = uiCycleLen_g;
  // const     
  EplApiInitParam.m_uiIsochrTxMaxPayload      = 256;
  // const              
  EplApiInitParam.m_uiIsochrRxMaxPayload      = 256;
  // const; only required for IdentRes              
  EplApiInitParam.m_dwPresMaxLatency          = 50000; 
  // required for initialisation (+28 bytes)           
  EplApiInitParam.m_uiPreqActPayloadLimit     = 36;
  // required for initialisation of Pres frame (+28 bytes)               
  EplApiInitParam.m_uiPresActPayloadLimit     = 36;
  // const; only required for IdentRes               
  EplApiInitParam.m_dwAsndMaxLatency          = 150000;
  // required for error detection           
  EplApiInitParam.m_uiMultiplCycleCnt         = 0;
  // required to set up max frame size                
  EplApiInitParam.m_uiAsyncMtu                = 1500;
  // required for sync             
  EplApiInitParam.m_uiPrescaler               = 2;                
  EplApiInitParam.m_dwLossOfFrameTolerance    = 500000;
  EplApiInitParam.m_dwAsyncSlotTimeout        = 3000000;
  EplApiInitParam.m_dwWaitSocPreq             = 150000;
  // NMT_DeviceType_U32
  EplApiInitParam.m_dwDeviceType              = -1;
  // NMT_IdentityObject_REC.VendorId_U32               
  EplApiInitParam.m_dwVendorId                = -1;
  // NMT_IdentityObject_REC.ProductCode_U32               
  EplApiInitParam.m_dwProductCode             = -1;
  // NMT_IdentityObject_REC.RevisionNo_U32               
  EplApiInitParam.m_dwRevisionNumber          = -1;
  // NMT_IdentityObject_REC.SerialNo_U32               
  EplApiInitParam.m_dwSerialNumber            = -1;              

  EplApiInitParam.m_dwSubnetMask              = ntohl( inet_addr( op->IpNetmask));
  EplApiInitParam.m_dwDefaultGateway          = 0;
  EPL_MEMCPY(EplApiInitParam.m_sHostname, sHostname, sizeof(EplApiInitParam.m_sHostname));
  EplApiInitParam.m_uiSyncNodeId              = EPL_C_ADR_SYNC_ON_SOA;
  EplApiInitParam.m_fSyncOnPrcNode            = FALSE;

  // set callback functions
  EplApiInitParam.m_pfnCbEvent = (tEplApiCbEvent)AppCbEvent;

  EplApiInitParam.m_pfnObdInitRam = EplObdInitRam;
  EplApiInitParam.m_pfnCbSync  = AppCbSync;

  // initialize POWERLINK stack
  EplRet = EplApiInitialize(&EplApiInitParam);
  if(EplRet != kEplSuccessful) {
    errh_Error("EplApiInitialize() failed (Error:0x%x!", EplRet);
    goto Exit;
  }

  EplRet = EplApiSetCdcFilename(cdc_file);
  if(EplRet != kEplSuccessful) {
    goto Exit;
  }
  
  // Allocate memory for the in- and outputareas
  if( local->output_area_size > 0)
    AppProcessImageIn_g = malloc(local->output_area_size);
  if( local->input_area_size > 0) {
    AppProcessImageOut_g = malloc(local->input_area_size);
  }

  // Save pointer to in- and outputareas in THIS agent object
  local->input_area = AppProcessImageOut_g;
  local->output_area = AppProcessImageIn_g;
	
  if( local->inputResetEnabled && local->input_area_size > 0)
    local->tmp_area = malloc(local->input_area_size);
  else
    local->tmp_area = local->input_area;
		
  AppProcessImageCopyJob_g.m_fNonBlocking = FALSE;
  AppProcessImageCopyJob_g.m_uiPriority = 0;
  AppProcessImageCopyJob_g.m_In.m_pPart = AppProcessImageIn_g;
  AppProcessImageCopyJob_g.m_In.m_uiOffset = 0;
  AppProcessImageCopyJob_g.m_In.m_uiSize = local->output_area_size;
  AppProcessImageCopyJob_g.m_Out.m_pPart = AppProcessImageOut_g;
  AppProcessImageCopyJob_g.m_Out.m_uiOffset = 0;
  AppProcessImageCopyJob_g.m_Out.m_uiSize = local->input_area_size;

  EplRet = EplApiProcessImageAlloc(local->output_area_size, local->input_area_size, 2, 2);
  if (EplRet != kEplSuccessful) {
    goto Exit;
  }

  EplRet = EplApiProcessImageSetup();
  if (EplRet != kEplSuccessful) {
    goto Exit;
  }

  // start processing
  EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset);
  if (EplRet != kEplSuccessful) {
    IoAgentClose(NULL, NULL);
    goto Exit;
  }
    
  errh_Success ("Powerlink init successfull");
  return IO__SUCCESS;
    

 Exit:
  errh_Error("IoCardInit: returns 0x%X", EplRet);
  return IO__SUCCESS;

}
static tEplKernel EplApiProcessImageExchangeIntUserPages(
    tEplApiProcessImageCopyJobInt* pCopyJob_p)
{
    tEplKernel      Ret = kEplSuccessful;
    unsigned int    nIndex;
    struct page**   ppPage;
    unsigned long   ulOffset;
    unsigned long   ulLength;
    unsigned long   ulSize;
    void*           pPIVar;
    tEplApiProcessImagePart* pPart;
    void*           pVirtUserPart;

    // copy input image
    ppPage = pCopyJob_p->m_Event.m_pCompletion->m_apPageIn;

    pPart = &pCopyJob_p->m_CopyJob.m_In;

    if ((pPart->m_uiSize > 0)
            && (pPart->m_pPart != NULL)
            && (EplApiProcessImageInstance_g.m_In.m_pImage != NULL)
            && ((pPart->m_uiOffset + pPart->m_uiSize)
                <= EplApiProcessImageInstance_g.m_In.m_uiSize))
    {
        pPIVar = ((BYTE*) EplApiProcessImageInstance_g.m_In.m_pImage)
                 + pPart->m_uiOffset;

        ulOffset = ((unsigned long)pPart->m_pPart) & (PAGE_SIZE - 1);

        ulLength = 0;

        for (nIndex = 0; nIndex < EPL_API_PI_PAGE_COUNT; nIndex++)
        {
            if (ppPage[nIndex] == NULL)
            {
                break;
            }

            ulSize = min ((PAGE_SIZE - ulOffset), pPart->m_uiSize - ulLength);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
            pVirtUserPart = kmap_atomic(ppPage[nIndex], KM_USER0);
#else
            pVirtUserPart = kmap_atomic(ppPage[nIndex]);
#endif

            EPL_MEMCPY(pPIVar,
                       pVirtUserPart + ulOffset,
                       ulSize);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
            kunmap_atomic(pVirtUserPart, KM_USER0);
#else
            kunmap_atomic(pVirtUserPart);
#endif

            pPIVar += ulSize;
            ulLength += ulSize;
            ulOffset = 0;

            if (ulLength >= pPart->m_uiSize)
            {
                break;
            }
        }
    }

    // copy output image
    ppPage = pCopyJob_p->m_Event.m_pCompletion->m_apPageOut;

    pPart = &pCopyJob_p->m_CopyJob.m_Out;

    if ((pPart->m_uiSize > 0)
            && (pPart->m_pPart != NULL)
            && (EplApiProcessImageInstance_g.m_Out.m_pImage != NULL)
            && ((pPart->m_uiOffset + pPart->m_uiSize)
                <= EplApiProcessImageInstance_g.m_Out.m_uiSize))
    {
        pPIVar = ((BYTE*) EplApiProcessImageInstance_g.m_Out.m_pImage)
                 + pPart->m_uiOffset;

        ulOffset = ((unsigned long)pPart->m_pPart) & (PAGE_SIZE - 1);

        ulLength = 0;

        for (nIndex = 0; nIndex < EPL_API_PI_PAGE_COUNT; nIndex++)
        {
            if (ppPage[nIndex] == NULL)
            {
                break;
            }

            ulSize = min ((PAGE_SIZE - ulOffset), pPart->m_uiSize - ulLength);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
            pVirtUserPart = kmap_atomic(ppPage[nIndex], KM_USER0);
#else
            pVirtUserPart = kmap_atomic(ppPage[nIndex]);
#endif

            EPL_MEMCPY(pVirtUserPart + ulOffset,
                       pPIVar,
                       ulSize);

#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
            kunmap_atomic(pVirtUserPart, KM_USER0);
#else
            kunmap_atomic(pVirtUserPart);
#endif
            pPIVar += ulSize;
            ulLength += ulSize;
            ulOffset = 0;

            if (ulLength >= pPart->m_uiSize)
            {
                break;
            }
        }
    }

    return Ret;
}
static tEplKernel EplApiProcessImageExchangeInt(
    tEplApiProcessImageCopyJob* pCopyJob_p)
{
    tEplKernel      Ret = kEplSuccessful;

    if (pCopyJob_p->m_In.m_uiSize > 0)
    {
        if ((pCopyJob_p->m_In.m_pPart != NULL)
                && (EplApiProcessImageInstance_g.m_In.m_pImage != NULL)
                && ((pCopyJob_p->m_In.m_uiOffset + pCopyJob_p->m_In.m_uiSize)
                    <= EplApiProcessImageInstance_g.m_In.m_uiSize))
        {
            void*   pPIVar = ((BYTE*) EplApiProcessImageInstance_g.m_In.m_pImage)
                             + pCopyJob_p->m_In.m_uiOffset;

#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
            int     iErr;

            iErr = copy_from_user(pPIVar,
                                  pCopyJob_p->m_In.m_pPart,
                                  pCopyJob_p->m_In.m_uiSize);
            if (iErr != 0)
            {
                PRINTF("%s: copy_from_user(%p, %p, %u) returned %i\n",
                       __func__,
                       pPIVar,
                       pCopyJob_p->m_In.m_pPart,
                       pCopyJob_p->m_In.m_uiSize,
                       iErr);

                Ret = kEplApiPIInvalidPIPointer;
                goto Exit;
            }
#else
            EPL_MEMCPY(pPIVar,
                       pCopyJob_p->m_In.m_pPart,
                       pCopyJob_p->m_In.m_uiSize);
#endif
        }
    }

    if (pCopyJob_p->m_Out.m_uiSize > 0)
    {
        if ((pCopyJob_p->m_Out.m_pPart != NULL)
                && (EplApiProcessImageInstance_g.m_Out.m_pImage != NULL)
                && ((pCopyJob_p->m_Out.m_uiOffset + pCopyJob_p->m_Out.m_uiSize)
                    <= EplApiProcessImageInstance_g.m_Out.m_uiSize))
        {
            void*   pPIVar = ((BYTE*) EplApiProcessImageInstance_g.m_Out.m_pImage)
                             + pCopyJob_p->m_Out.m_uiOffset;

#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
            int     iErr;

            iErr = copy_to_user(pCopyJob_p->m_Out.m_pPart,
                                pPIVar,
                                pCopyJob_p->m_Out.m_uiSize);
            if (iErr != 0)
            {
                PRINTF("%s: copy_to_user(%p, %p, %u) returned %i\n",
                       __func__,
                       pCopyJob_p->m_Out.m_pPart,
                       pPIVar,
                       pCopyJob_p->m_Out.m_uiSize,
                       iErr);

                Ret = kEplApiPIInvalidPIPointer;
                goto Exit;
            }
#else
            EPL_MEMCPY(pCopyJob_p->m_Out.m_pPart,
                       pPIVar,
                       pCopyJob_p->m_Out.m_uiSize);
#endif
        }
    }

#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
Exit:
#endif
    return Ret;
}
예제 #13
0
//---------------------------------------------------------------------------
//
// Function:        EplLinInit
//
// Description:     Entry point of kernel module
////
//
// Parameters:      N/A
//
//
// Returns:         Return code
//
//---------------------------------------------------------------------------
static  int  __init  EplLinInit (void)
{
tEplKernel          EplRet;
static tEplApiInitParam EplApiInitParam = {0};
char*               sHostname = HOSTNAME;
BOOL                fApiInit = FALSE;
BOOL                fLinProcInit =FALSE;

    atomic_set(&AtomicShutdown_g, TRUE);

    // open character device from debugfs to disable tracing when necessary
    hAppFdTracingEnabled_g = open("/sys/kernel/debug/tracing/tracing_enabled", O_WRONLY, 0666);

    // get node ID from insmod command line
    EplApiInitParam.m_uiNodeId = uiNodeId_g;

    if (EplApiInitParam.m_uiNodeId == EPL_C_ADR_INVALID)
    {   // invalid node ID set
        // set default node ID
        EplApiInitParam.m_uiNodeId = NODEID;
    }

    uiNodeId_g = EplApiInitParam.m_uiNodeId;

    // calculate IP address
    EplApiInitParam.m_dwIpAddress = (0xFFFFFF00 & IP_ADDR) | EplApiInitParam.m_uiNodeId;

    EplApiInitParam.m_fAsyncOnly = FALSE;

    EplApiInitParam.m_uiSizeOfStruct = sizeof (EplApiInitParam);
    EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr, sizeof (EplApiInitParam.m_abMacAddress));
    EplApiInitParam.m_dwFeatureFlags = (DWORD) ~0UL;
    EplApiInitParam.m_dwCycleLen = uiCycleLen_g;     // required for error detection
    EplApiInitParam.m_uiIsochrTxMaxPayload = 100; // const
    EplApiInitParam.m_uiIsochrRxMaxPayload = 100; // const
    EplApiInitParam.m_dwPresMaxLatency = 50000;  // const; only required for IdentRes
    EplApiInitParam.m_uiPreqActPayloadLimit = 36; // required for initialisation (+28 bytes)
    EplApiInitParam.m_uiPresActPayloadLimit = 36; // required for initialisation of Pres frame (+28 bytes)
    EplApiInitParam.m_dwAsndMaxLatency = 150000;   // const; only required for IdentRes
    EplApiInitParam.m_uiMultiplCycleCnt = 0;  // required for error detection
    EplApiInitParam.m_uiAsyncMtu = 1500;         // required to set up max frame size
    EplApiInitParam.m_uiPrescaler = 2;         // required for sync
    EplApiInitParam.m_dwLossOfFrameTolerance = 500000;
    EplApiInitParam.m_dwAsyncSlotTimeout = 3000000;
    EplApiInitParam.m_dwWaitSocPreq = 150000;
    EplApiInitParam.m_dwDeviceType = (DWORD) ~0UL;      // NMT_DeviceType_U32
    EplApiInitParam.m_dwVendorId = (DWORD) ~0UL;        // NMT_IdentityObject_REC.VendorId_U32
    EplApiInitParam.m_dwProductCode = (DWORD) ~0UL;     // NMT_IdentityObject_REC.ProductCode_U32
    EplApiInitParam.m_dwRevisionNumber = (DWORD) ~0UL;  // NMT_IdentityObject_REC.RevisionNo_U32
    EplApiInitParam.m_dwSerialNumber = (DWORD) ~0UL;    // NMT_IdentityObject_REC.SerialNo_U32

    EplApiInitParam.m_dwSubnetMask = SUBNET_MASK;
    EplApiInitParam.m_dwDefaultGateway = 0;
    EPL_MEMCPY(EplApiInitParam.m_sHostname, sHostname, sizeof(EplApiInitParam.m_sHostname));
    EplApiInitParam.m_uiSyncNodeId = EPL_C_ADR_SYNC_ON_SOA;
    EplApiInitParam.m_fSyncOnPrcNode = FALSE;

    // set callback functions
    EplApiInitParam.m_pfnCbEvent = AppCbEvent;
    EplApiInitParam.m_pfnCbSync  = AppCbSync;
    EplApiInitParam.m_pfnObdInitRam = EplObdInitRam;

    printk("\n\n Hello, I'm a simple POWERLINK node running as %s!\n  (build: %s / %s)\n\n",
            (uiNodeId_g == EPL_C_ADR_MN_DEF_NODE_ID ?
                "Managing Node" : "Controlled Node"),
            __DATE__, __TIME__);

    // initialize the Linux a wait queue for shutdown of this module
    init_waitqueue_head(&WaitQueueShutdown_g);

    // initialize the procfs device
    EplRet = EplLinProcInit();
    if (EplRet != kEplSuccessful)
    {
        PRINTF("EplLinProcInit failed!\n");
        goto Exit;
    }
    fLinProcInit = TRUE;

    // initialize POWERLINK stack
    EplRet = EplApiInitialize(&EplApiInitParam);
    if(EplRet != kEplSuccessful)
    {
        PRINTF("EplApiInitialize failed!\n");
        goto Exit;
    }
    fApiInit = TRUE;

    EplRet = EplApiSetCdcFilename(pszCdcFilename_g);
    if(EplRet != kEplSuccessful)
    {
        goto Exit;
    }

    PRINTF("Initializing process image...\n");
    PRINTF("Size of input process image: %ld\n", sizeof(AppProcessImageIn_g));
    PRINTF("Size of output process image: %ld\n", sizeof (AppProcessImageOut_g));

    AppProcessImageCopyJob_g.m_fNonBlocking = FALSE;
    AppProcessImageCopyJob_g.m_uiPriority = 0;
    AppProcessImageCopyJob_g.m_In.m_pPart = &AppProcessImageIn_g;
    AppProcessImageCopyJob_g.m_In.m_uiOffset = 0;
    AppProcessImageCopyJob_g.m_In.m_uiSize = sizeof (AppProcessImageIn_g);
    AppProcessImageCopyJob_g.m_Out.m_pPart = &AppProcessImageOut_g;
    AppProcessImageCopyJob_g.m_Out.m_uiOffset = 0;
    AppProcessImageCopyJob_g.m_Out.m_uiSize = sizeof (AppProcessImageOut_g);

    EplRet = EplApiProcessImageAlloc(sizeof (AppProcessImageIn_g), sizeof (AppProcessImageOut_g), 2, 2);
    if (EplRet != kEplSuccessful)
    {
        goto Exit;
    }

    EplRet = EplApiProcessImageSetup();
    if (EplRet != kEplSuccessful)
    {
        goto Exit;
    }

    // start the NMT state machine
    EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset);
    atomic_set(&AtomicShutdown_g, FALSE);

Exit:
    PRINTF("EplLinInit(): returns 0x%X\n", EplRet);
    if (EplRet != kEplSuccessful)
    {
        if (fApiInit != FALSE)
        {
            EplApiShutdown();
        }
        if (fLinProcInit != FALSE)
        {
            EplLinProcFree();
        }

        return -ENODEV;
    }
    else
    {
        return 0;
    }
}
예제 #14
0
tEplKernel EplDllkCalAsyncSend(tEplFrameInfo * pFrameInfo_p, tEplDllAsyncReqPriority Priority_p)
{
tEplKernel  Ret = kEplSuccessful;
tEplEvent       Event;
#if EPL_USE_SHAREDBUFF != FALSE
tShbError   ShbError;

    switch (Priority_p)
    {
        case kEplDllAsyncReqPrioNmt:    // NMT request priority
            ShbError = ShbCirWriteDataBlock (EplDllkCalInstance_g.m_ShbInstanceTxNmt, pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
            // returns kShbOk, kShbExceedDataSizeLimit, kShbBufferFull, kShbInvalidArg
            break;

        default:    // generic priority
            ShbError = ShbCirWriteDataBlock (EplDllkCalInstance_g.m_ShbInstanceTxGen, pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
            // returns kShbOk, kShbExceedDataSizeLimit, kShbBufferFull, kShbInvalidArg
            break;

    }

    // error handling
    switch (ShbError)
    {
        case kShbOk:
            break;

        case kShbExceedDataSizeLimit:
            Ret = kEplDllAsyncTxBufferFull;
            break;

        case kShbBufferFull:
            Ret = kEplDllAsyncTxBufferFull;
            break;

        case kShbInvalidArg:
        default:
            Ret = kEplNoResource;
            break;
    }

#else

    switch (Priority_p)
    {
        case kEplDllAsyncReqPrioNmt:    // NMT request priority
            if (EplDllkCalInstance_g.m_uiFrameSizeNmt == 0)
            {
                EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameNmt, pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
                EplDllkCalInstance_g.m_uiFrameSizeNmt = pFrameInfo_p->m_uiFrameSize;
            }
            else
            {
                Ret = kEplDllAsyncTxBufferFull;
                goto Exit;
            }
            break;

        default:    // generic priority
            if (EplDllkCalInstance_g.m_uiFrameSizeGen == 0)
            {
                EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameGen, pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
                EplDllkCalInstance_g.m_uiFrameSizeGen = pFrameInfo_p->m_uiFrameSize;
            }
            else
            {
                Ret = kEplDllAsyncTxBufferFull;
                goto Exit;
            }
            break;
    }

#endif

    // post event to DLL
    Event.m_EventSink = kEplEventSinkDllk;
    Event.m_EventType = kEplEventTypeDllkFillTx;
    EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
    Event.m_pArg = &Priority_p;
    Event.m_uiSize = sizeof(Priority_p);
    Ret = EplEventkPost(&Event);

#if EPL_USE_SHAREDBUFF == FALSE
Exit:
#endif

    return Ret;
}
예제 #15
0
int openPowerlink(void)
{
    const BYTE              abMacAddr[] = {MAC_ADDR};
    static tEplApiInitParam EplApiInitParam = {0};
	// needed for process var
	tEplObdSize         	ObdSize;
	tEplKernel 				EplRet;
	unsigned int			uiVarEntries;

    fShutdown_l = FALSE;

	////////////////////////
	// setup th EPL Stack //
	////////////////////////

	// set EPL init parameters
    EplApiInitParam.m_uiSizeOfStruct = sizeof (EplApiInitParam);

#ifdef NODESWITCH_SPI_BASE
    // read node-ID from hex switch on baseboard, which is connected via SPI shift register
    IOWR_ALTERA_AVALON_SPI_TXDATA(NODESWITCH_SPI_BASE, 0xFF);   // generate pulse for latching inputs
    while ((IORD_ALTERA_AVALON_SPI_STATUS(NODESWITCH_SPI_BASE) & ALTERA_AVALON_SPI_STATUS_RRDY_MSK) == 0)
    {   // wait
    }
    EplApiInitParam.m_uiNodeId = IORD_ALTERA_AVALON_SPI_RXDATA(NODESWITCH_SPI_BASE);
#endif
#ifdef NODESWITCH_PIO_BASE
    EplApiInitParam.m_uiNodeId = IORD_ALTERA_AVALON_PIO_DATA(NODESWITCH_PIO_BASE);
#endif

    if (EplApiInitParam.m_uiNodeId == EPL_C_ADR_INVALID)
    {
        EplApiInitParam.m_uiNodeId = NODEID; // defined at the top of this file!
    }

    EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr, sizeof(EplApiInitParam.m_abMacAddress));
    EplApiInitParam.m_abMacAddress[5] = (BYTE) EplApiInitParam.m_uiNodeId;

    // calculate IP address
    EplApiInitParam.m_dwIpAddress = (0xFFFFFF00 & IP_ADDR) | EplApiInitParam.m_uiNodeId;
	EplApiInitParam.m_uiIsochrTxMaxPayload = 256;
	EplApiInitParam.m_uiIsochrRxMaxPayload = 256;
	EplApiInitParam.m_dwPresMaxLatency = 2000;
	EplApiInitParam.m_dwAsndMaxLatency = 2000;
	EplApiInitParam.m_fAsyncOnly = FALSE;
	EplApiInitParam.m_dwFeatureFlags = -1;
	EplApiInitParam.m_dwCycleLen = CYCLE_LEN;
	EplApiInitParam.m_uiPreqActPayloadLimit = 36;
	EplApiInitParam.m_uiPresActPayloadLimit = 36;
	EplApiInitParam.m_uiMultiplCycleCnt = 0;
	EplApiInitParam.m_uiAsyncMtu = 1500;
	EplApiInitParam.m_uiPrescaler = 2;
	EplApiInitParam.m_dwLossOfFrameTolerance = 500000;
	EplApiInitParam.m_dwAsyncSlotTimeout = 3000000;
	EplApiInitParam.m_dwWaitSocPreq = 0;
	EplApiInitParam.m_dwDeviceType = -1;
	EplApiInitParam.m_dwVendorId = -1;
	EplApiInitParam.m_dwProductCode = -1;
	EplApiInitParam.m_dwRevisionNumber = -1;
	EplApiInitParam.m_dwSerialNumber = -1;
	EplApiInitParam.m_dwSubnetMask = SUBNET_MASK;
	EplApiInitParam.m_dwDefaultGateway = 0;
    EplApiInitParam.m_dwApplicationSwDate = 1;       // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
	EplApiInitParam.m_pfnCbEvent = AppCbEvent;
    EplApiInitParam.m_pfnCbSync  = AppCbSync;
    EplApiInitParam.m_pfnObdInitRam = EplObdInitRam;
    EplApiInitParam.m_dwSyncResLatency = EPL_C_DLL_T_IFG;

	// initialize EPL stack
    printf("init EPL Stack with node-ID 0x%02X:\n", EplApiInitParam.m_uiNodeId);
	EplRet = EplApiInitialize(&EplApiInitParam);
	if(EplRet != kEplSuccessful) {
        printf("init EPL Stack... error %X\n\n", EplRet);
		goto Exit;
    }
    printf("init EPL Stack...ok\n\n");

	// link process variables used by CN to object dictionary
    printf("linking process vars:\n");
    ObdSize = sizeof(bButtonInputs_l);
    uiVarEntries = 1;
    EplRet = EplApiLinkObject(0x6000, &bButtonInputs_l, &uiVarEntries, &ObdSize, 0x01);
    if (EplRet != kEplSuccessful)
    {
        printf("linking process vars... error\n\n");
        goto ExitShutdown;
    }

    ObdSize = sizeof(abVirtualInputs_l[0]);
    uiVarEntries = 17;
    EplRet = EplApiLinkObject(0x2000, abVirtualInputs_l, &uiVarEntries, &ObdSize, 0x01);
    if (EplRet != kEplSuccessful)
    {
        printf("linking process vars... error\n\n");
        goto ExitShutdown;
    }

    ObdSize = sizeof(adwVirtualInputs_l[0]);
    uiVarEntries = 8;
    EplRet = EplApiLinkObject(0x2001, adwVirtualInputs_l, &uiVarEntries, &ObdSize, 0x01);
    if (EplRet != kEplSuccessful)
    {
        printf("linking process vars... error\n\n");
        goto ExitShutdown;
    }

    ObdSize = sizeof(wDigitalOutputs_l);
    uiVarEntries = 1;
    EplRet = EplApiLinkObject(0x6300, &wDigitalOutputs_l, &uiVarEntries, &ObdSize, 0x01);
    if (EplRet != kEplSuccessful)
    {
        printf("linking process vars... error\n\n");
        goto ExitShutdown;
    }

    ObdSize = sizeof(bLedOutputs_l);
    uiVarEntries = 1;
    EplRet = EplApiLinkObject(0x6200, &bLedOutputs_l, &uiVarEntries, &ObdSize, 0x01);
    if (EplRet != kEplSuccessful)
    {
        printf("linking process vars... error\n\n");
        goto ExitShutdown;
    }

    ObdSize = sizeof(abVirtualOutputs_l[0]);
    uiVarEntries = 15;
    EplRet = EplApiLinkObject(0x2200, abVirtualOutputs_l, &uiVarEntries, &ObdSize, 0x01);
    if (EplRet != kEplSuccessful)
    {
        printf("linking process vars... error\n\n");
        goto ExitShutdown;
    }

    ObdSize = sizeof(adwVirtualOutputs_l[0]);
    uiVarEntries = 8;
    EplRet = EplApiLinkObject(0x2201, adwVirtualOutputs_l, &uiVarEntries, &ObdSize, 0x01);
    if (EplRet != kEplSuccessful)
    {
        printf("linking process vars... error\n\n");
        goto ExitShutdown;
    }
	printf("linking process vars... ok\n\n");

	// start the EPL stack
    printf("start EPL Stack...\n");
	EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset);
    if (EplRet != kEplSuccessful) {
        printf("start EPL Stack... error\n\n");
        goto ExitShutdown;
    }
    printf("start EPL Stack... ok\n\n");

    printf("NIOS II with openPowerlink is ready!\n\n");

#ifdef LED_PIO_BASE
    IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 0xFF);
#endif

    while(1)
    {
        EplApiProcess();
        if (fShutdown_l == TRUE)
            break;
    }

ExitShutdown:
    printf("Shutdown EPL Stack\n");
    EplApiShutdown(); //shutdown node

Exit:
	return EplRet;
}
//---------------------------------------------------------------------------
//
// Function:            main
//
// Description:         main function of demo application
//
// Parameters:
//
// Returns:
//---------------------------------------------------------------------------
int  main (int argc, char **argv)
{
    tEplKernel                  EplRet = kEplSuccessful;
    static tEplApiInitParam     EplApiInitParam;
    char*                       sHostname = HOSTNAME;
    char                        cKey = 0;

#ifdef CONFIG_POWERLINK_USERSTACK
    // variables for Pcap
    char                        sErr_Msg[ PCAP_ERRBUF_SIZE ];
    char                        devName[128];
    pcap_if_t *                 alldevs;
    pcap_if_t *                 seldev;
    int                         i = 0;
    int                         inum;
#endif

    int                         opt;

#if (TARGET_SYSTEM == _LINUX_)
    /* get command line parameters */
    while ((opt = getopt(argc, argv, "c:l:")) != -1)
    {
        switch (opt)
        {
        case 'c':
            uiCycleLen_g = strtoul(optarg, NULL, 10);
            break;

        case 'l':
            pLogFile_g = optarg;
            break;

        default: /* '?' */
            fprintf (stderr, "Usage: %s [-c CYCLE_TIME] [-l LOGFILE]\n", argv[0]);
            goto Exit;
        }
    }
#endif

#ifdef CONFIG_POWERLINK_USERSTACK

#if (TARGET_SYSTEM == _LINUX_)
    struct sched_param          schedParam;

    /* adjust process priority */
    if (nice (-20) == -1)         // push nice level in case we have no RTPreempt
    {
        EPL_DBGLVL_ERROR_TRACE("%s() couldn't set nice value! (%s)\n", __func__, strerror(errno));
    }
    schedParam.__sched_priority = MAIN_THREAD_PRIORITY;
    if (pthread_setschedparam(pthread_self(), SCHED_RR, &schedParam) != 0)
    {
        EPL_DBGLVL_ERROR_TRACE("%s() couldn't set thread scheduling parameters! %d\n",
                __func__, schedParam.__sched_priority);
    }

    /* Initialize target specific stuff */
    EplTgtInit();

#elif (TARGET_SYSTEM == _WIN32_)

    // activate realtime priority class
    SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
    // lower the priority of this thread
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE);

#endif // (TARGET_SYSTEM == _WIN32_)

#endif // CONFIG_POWERLINK_USERSTACK

#if (TARGET_SYSTEM == _LINUX_)
#ifdef SET_CPU_AFFINITY
    {
        /* binds all openPOWERLINK threads to the second CPU core */
        cpu_set_t                   affinity;

        CPU_ZERO(&affinity);
        CPU_SET(1, &affinity);
        sched_setaffinity(0, sizeof(cpu_set_t), &affinity);
    }
#endif
#endif


    /* Enabling ftrace for debugging */
    FTRACE_OPEN();
    FTRACE_ENABLE(TRUE);

    /*
    EPL_DBGLVL_ALWAYS_TRACE("%s(): Main Thread Id:%ld\n", __func__,
                             syscall(SYS_gettid));
                             */
    printf("----------------------------------------------------\n");
    printf("openPOWERLINK console MN DEMO application\n");
    printf("----------------------------------------------------\n");

    EPL_MEMSET(&EplApiInitParam, 0, sizeof (EplApiInitParam));
    EplApiInitParam.m_uiSizeOfStruct = sizeof (EplApiInitParam);

#ifdef CONFIG_POWERLINK_USERSTACK

    /* Retrieve the device list on the local machine */
    if (pcap_findalldevs(&alldevs, sErr_Msg) == -1)
    {
        fprintf(stderr, "Error in pcap_findalldevs: %s\n", sErr_Msg);
        EplRet = kEplNoResource;
        goto Exit;
    }

    PRINTF("--------------------------------------------------\n");
    PRINTF("List of Ethernet Cards Found in this System: \n");
    PRINTF("--------------------------------------------------\n");

     /* Print the list */
    for (seldev = alldevs; seldev != NULL; seldev = seldev->next)
    {
        PRINTF("%d. ", ++i);

        if (seldev->description)
        {
            PRINTF("%s\n      %s\n", seldev->description, seldev->name);
        }
        else
        {
            PRINTF("%s\n", seldev->name);
        }
    }

    if (i == 0)
    {
        PRINTF("\nNo interfaces found! Make sure pcap library is installed.\n");
        EplRet = kEplNoResource;
        goto Exit;
    }

    PRINTF("--------------------------------------------------\n");
    PRINTF("Select the interface to be used for POWERLINK (1-%d):",i);
    if (scanf("%d", &inum) == EOF)
    {
        pcap_freealldevs(alldevs);
        EplRet = kEplNoResource;
        goto Exit;
    }
    PRINTF("--------------------------------------------------\n");
    if ((inum < 1) || (inum > i))
    {
        PRINTF("\nInterface number out of range.\n");
        /* Free the device list */
        pcap_freealldevs(alldevs);
        EplRet = kEplNoResource;
        goto Exit;
    }

    /* Jump to the selected adapter */
    for (seldev = alldevs, i = 0;
         i < (inum - 1);
         seldev = seldev->next, i++)
    {   // do nothing
    }

    strncpy(devName, seldev->name, 127);
    // pass selected device name to Edrv
    EplApiInitParam.m_HwParam.m_pszDevName = devName;

#endif

    EplApiInitParam.m_uiNodeId = uiNodeId_g = NODEID;
    EplApiInitParam.m_dwIpAddress = (0xFFFFFF00 & IP_ADDR) | EplApiInitParam.m_uiNodeId;

    /* write 00:00:00:00:00:00 to MAC address, so that the driver uses the real hardware address */
    EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr, sizeof (EplApiInitParam.m_abMacAddress));

    EplApiInitParam.m_fAsyncOnly = FALSE;

    EplApiInitParam.m_dwFeatureFlags            = -1;
    EplApiInitParam.m_dwCycleLen                = uiCycleLen_g;     // required for error detection
    EplApiInitParam.m_uiIsochrTxMaxPayload      = 256;              // const
    EplApiInitParam.m_uiIsochrRxMaxPayload      = 256;              // const
    EplApiInitParam.m_dwPresMaxLatency          = 50000;            // const; only required for IdentRes
    EplApiInitParam.m_uiPreqActPayloadLimit     = 36;               // required for initialisation (+28 bytes)
    EplApiInitParam.m_uiPresActPayloadLimit     = 36;               // required for initialisation of Pres frame (+28 bytes)
    EplApiInitParam.m_dwAsndMaxLatency          = 150000;           // const; only required for IdentRes
    EplApiInitParam.m_uiMultiplCycleCnt         = 0;                // required for error detection
    EplApiInitParam.m_uiAsyncMtu                = 1500;             // required to set up max frame size
    EplApiInitParam.m_uiPrescaler               = 2;                // required for sync
    EplApiInitParam.m_dwLossOfFrameTolerance    = 500000;
    EplApiInitParam.m_dwAsyncSlotTimeout        = 3000000;
    EplApiInitParam.m_dwWaitSocPreq             = 150000;
    EplApiInitParam.m_dwDeviceType              = -1;               // NMT_DeviceType_U32
    EplApiInitParam.m_dwVendorId                = -1;               // NMT_IdentityObject_REC.VendorId_U32
    EplApiInitParam.m_dwProductCode             = -1;               // NMT_IdentityObject_REC.ProductCode_U32
    EplApiInitParam.m_dwRevisionNumber          = -1;               // NMT_IdentityObject_REC.RevisionNo_U32
    EplApiInitParam.m_dwSerialNumber            = -1;               // NMT_IdentityObject_REC.SerialNo_U32

    EplApiInitParam.m_dwSubnetMask              = SUBNET_MASK;
    EplApiInitParam.m_dwDefaultGateway          = 0;
    EPL_MEMCPY(EplApiInitParam.m_sHostname, sHostname, sizeof(EplApiInitParam.m_sHostname));
    EplApiInitParam.m_uiSyncNodeId              = EPL_C_ADR_SYNC_ON_SOA;
    EplApiInitParam.m_fSyncOnPrcNode            = FALSE;

    // set callback functions
    EplApiInitParam.m_pfnCbEvent = AppCbEvent;

#ifdef CONFIG_POWERLINK_USERSTACK
    EplApiInitParam.m_pfnObdInitRam = EplObdInitRam;
    EplApiInitParam.m_pfnCbSync  = AppCbSync;
#else
    EplApiInitParam.m_pfnCbSync = NULL;
#endif


    printf("\n\nHello, I'm a Userspace POWERLINK node running as %s!\n  (build: %s / %s)\n\n",
            (uiNodeId_g == EPL_C_ADR_MN_DEF_NODE_ID ?
                "Managing Node" : "Controlled Node"),
            __DATE__, __TIME__);

    // initialize POWERLINK stack
    printf ("Initializing openPOWERLINK stack...\n");
    EplRet = EplApiInitialize(&EplApiInitParam);
    if(EplRet != kEplSuccessful)
    {
        printf("EplApiInitialize() failed (Error:0x%x!\n", EplRet);
        goto Exit;
    }

    // initialize application
    printf ("Initializing openPOWERLINK application...\n");
    EplRet = AppInit();
    if(EplRet != kEplSuccessful)
    {
        printf("ApiInit() failed!\n");
        goto Exit;
    }


#ifdef CONFIG_POWERLINK_USERSTACK
    /* At this point, we don't need any more the device list. Free it */
    pcap_freealldevs(alldevs);

    EplRet = EplApiSetCdcFilename(pszCdcFilename_g);
    if(EplRet != kEplSuccessful)
    {
        goto Exit;
    }
#else
    // create event thread
    if (pthread_create(&eventThreadId, NULL,
                   &powerlinkEventThread, NULL) != 0)
    {
        goto Exit;
    }

    // create sync thread
    if (pthread_create(&syncThreadId, NULL,
                   &powerlinkSyncThread, NULL) != 0)
    {
        goto Exit;
    }
#endif

    printf("Initializing process image...\n");
    printf("Size of input process image: %ld\n", sizeof(AppProcessImageIn_g));
    printf("Size of output process image: %ld\n", sizeof (AppProcessImageOut_g));
    AppProcessImageCopyJob_g.m_fNonBlocking = FALSE;
    AppProcessImageCopyJob_g.m_uiPriority = 0;
    AppProcessImageCopyJob_g.m_In.m_pPart = &AppProcessImageIn_g;
    AppProcessImageCopyJob_g.m_In.m_uiOffset = 0;
    AppProcessImageCopyJob_g.m_In.m_uiSize = sizeof (AppProcessImageIn_g);
    AppProcessImageCopyJob_g.m_Out.m_pPart = &AppProcessImageOut_g;
    AppProcessImageCopyJob_g.m_Out.m_uiOffset = 0;
    AppProcessImageCopyJob_g.m_Out.m_uiSize = sizeof (AppProcessImageOut_g);

    EplRet = EplApiProcessImageAlloc(sizeof (AppProcessImageIn_g), sizeof (AppProcessImageOut_g), 2, 2);
    if (EplRet != kEplSuccessful)
    {
        goto Exit;
    }

    EplRet = EplApiProcessImageSetup();
    if (EplRet != kEplSuccessful)
    {
        goto Exit;
    }

    // start processing
    EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset);
    if (EplRet != kEplSuccessful)
    {
        goto ExitShutdown;
    }

    printf("\n-------------------------------\n");
    printf("Press Esc to leave the program\n");
    printf("Press r to reset the node\n");
    printf("-------------------------------\n\n");
    // wait for key hit
    while (cKey != 0x1B)
    {
        if( EplTgtKbhit() )
        {
            cKey    = (BYTE) EplTgtGetch();

            switch (cKey)
            {
                case 'r':
                {
                    EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset);
                    if (EplRet != kEplSuccessful)
                    {
                        goto ExitShutdown;
                    }
                    break;
                }

                case 'c':
                {
                    EplRet = EplApiExecNmtCommand(kEplNmtEventNmtCycleError);
                    if (EplRet != kEplSuccessful)
                    {
                        goto ExitShutdown;
                    }
                    break;
                }

                default:
                {
                    break;
                }
            }
        }

        EplTgtMilliSleep( 1500 );
    }

    FTRACE_ENABLE(FALSE);

ExitShutdown:
    // halt the NMT state machine
    // so the processing of POWERLINK frames stops
    EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff);

    // delete process image
    EplRet = EplApiProcessImageFree();

    // delete instance for all modules
    EplRet = EplApiShutdown();

Exit:
    PRINTF("main(): returns 0x%X\n", EplRet);

#if (TARGET_SYSTEM == _WIN32_)
    PRINTF("Press Enter to quit!\n");
    EplTgtGetch();
#endif

    return EplRet;
}
tEplKernel EplPdokConfigureChannel(tEplPdoChannelConf* pChannelConf_p)
{
    tEplKernel      Ret = kEplSuccessful;
    tEplPdoChannel* pDestPdoChannel;

    if (pChannelConf_p->m_fTx == FALSE)
    {   // RPDO
#if EPL_NMT_MAX_NODE_ID > 0
        tEplDllNodeOpParam  NodeOpParam;

        NodeOpParam.m_OpNodeType = kEplDllNodeOpTypeFilterPdo;
#endif

        if (pChannelConf_p->m_uiChannelId >= EplPdokInstance_g.m_Allocation.m_uiRxPdoChannelCount)
        {
            Ret = kEplPdoNotExist;
            goto Exit;
        }

        if (pChannelConf_p->m_PdoChannel.m_uiMappObjectCount > tabentries(*EplPdokInstance_g.m_paRxObject))
        {
            Ret = kEplPdoErrorMapp;
            goto Exit;
        }

        pDestPdoChannel = &EplPdokInstance_g.m_pRxPdoChannel[pChannelConf_p->m_uiChannelId];

#if EPL_NMT_MAX_NODE_ID > 0
        if ((pDestPdoChannel->m_uiNodeId != EPL_PDO_INVALID_NODE_ID)
                && (pDestPdoChannel->m_uiNodeId != EPL_PDO_PREQ_NODE_ID))
        {   // disable old PRes filter in DLL
            NodeOpParam.m_uiNodeId = pDestPdoChannel->m_uiNodeId;

            Ret = EplDllkDeleteNode(&NodeOpParam);
            if (Ret != kEplSuccessful)
            {
                goto Exit;
            }
        }
#endif // EPL_NMT_MAX_NODE_ID > 0

        // copy channel configuration to local structure
        EPL_MEMCPY(pDestPdoChannel,
                   &pChannelConf_p->m_PdoChannel,
                   sizeof (pChannelConf_p->m_PdoChannel));

        EPL_MEMCPY(&EplPdokInstance_g.m_paRxObject[pChannelConf_p->m_uiChannelId],
                   &pChannelConf_p->m_aMappObject[0],
                   (pChannelConf_p->m_PdoChannel.m_uiMappObjectCount
                    * sizeof (pChannelConf_p->m_aMappObject[0])));

#if EPL_NMT_MAX_NODE_ID > 0
        if ((pDestPdoChannel->m_uiNodeId != EPL_PDO_INVALID_NODE_ID)
                && (pDestPdoChannel->m_uiNodeId != EPL_PDO_PREQ_NODE_ID))
        {   // enable new PRes filter in DLL
            NodeOpParam.m_uiNodeId = pDestPdoChannel->m_uiNodeId;

            Ret = EplDllkAddNode(&NodeOpParam);
            if (Ret != kEplSuccessful)
            {
                goto Exit;
            }
        }
#endif // EPL_NMT_MAX_NODE_ID > 0

    }
    else
    {   // TPDO
        if (pChannelConf_p->m_uiChannelId >= EplPdokInstance_g.m_Allocation.m_uiTxPdoChannelCount)
        {
            Ret = kEplPdoNotExist;
            goto Exit;
        }

        if (pChannelConf_p->m_PdoChannel.m_uiMappObjectCount > tabentries(*EplPdokInstance_g.m_paTxObject))
        {
            Ret = kEplPdoErrorMapp;
            goto Exit;
        }

        // copy channel configuration to local structure
        EPL_MEMCPY(&EplPdokInstance_g.m_pTxPdoChannel[pChannelConf_p->m_uiChannelId],
                   &pChannelConf_p->m_PdoChannel,
                   sizeof (pChannelConf_p->m_PdoChannel));

        EPL_MEMCPY(&EplPdokInstance_g.m_paTxObject[pChannelConf_p->m_uiChannelId],
                   &pChannelConf_p->m_aMappObject[0],
                   (pChannelConf_p->m_PdoChannel.m_uiMappObjectCount
                    * sizeof (pChannelConf_p->m_aMappObject[0])));

    }

Exit:
    return Ret;
}
예제 #18
0
tEplKernel PUBLIC EplTimeruSetTimerMs(  tEplTimerHdl*   pTimerHdl_p,
                                        unsigned long   ulTimeMs_p,
                                        tEplTimerArg    Argument_p)
{
tTimerEntry*    pNewEntry;
tTimerEntry**   ppEntry;
tEplKernel      Ret;


    Ret = kEplSuccessful;

    // check pointer to handle
    if(pTimerHdl_p == NULL)
    {
        Ret = kEplTimerInvalidHandle;
        goto Exit;
    }

    // fetch entry from free timer list
    EplTimeruEnterCriticalSection(TIMERU_FREE_LIST);
    pNewEntry = EplTimeruInstance_g.m_pFreeListFirst;
    if (pNewEntry != NULL)
    {
        EplTimeruInstance_g.m_pFreeListFirst = pNewEntry->m_pNext;
        EplTimeruInstance_g.m_uiFreeEntries--;
        if (EplTimeruInstance_g.m_uiMinFreeEntries > EplTimeruInstance_g.m_uiFreeEntries)
        {
            EplTimeruInstance_g.m_uiMinFreeEntries = EplTimeruInstance_g.m_uiFreeEntries;
        }
    }
    EplTimeruLeaveCriticalSection(TIMERU_FREE_LIST);

    if (pNewEntry == NULL)
    {   // sorry, no free entry
        Ret = kEplTimerNoTimerCreated;
        goto Exit;
    }

    *pTimerHdl_p = (tEplTimerHdl) pNewEntry;
    EPL_MEMCPY(&pNewEntry->m_TimerArg, &Argument_p, sizeof(tEplTimerArg));

    // insert timer entry in timer list
    EplTimeruEnterCriticalSection(TIMERU_TIMER_LIST);

    // calculate timeout based on start time
    pNewEntry->m_dwTimeoutMs = (EplTimeruGetTickCountMs() - EplTimeruInstance_g.m_dwStartTimeMs) + ulTimeMs_p;

    ppEntry = &EplTimeruInstance_g.m_pTimerListFirst;
    while (*ppEntry != NULL)
    {
        if ((*ppEntry)->m_dwTimeoutMs > pNewEntry->m_dwTimeoutMs)
        {
            (*ppEntry)->m_dwTimeoutMs -= pNewEntry->m_dwTimeoutMs;
            break;
        }
        pNewEntry->m_dwTimeoutMs -= (*ppEntry)->m_dwTimeoutMs;
        ppEntry = &(*ppEntry)->m_pNext;
    }
    // insert before **ppEntry
    pNewEntry->m_pNext = *ppEntry;
    *ppEntry = pNewEntry;
    EplTimeruLeaveCriticalSection(TIMERU_TIMER_LIST);

#if (TARGET_SYSTEM == _WIN32_)
	if (ppEntry == &EplTimeruInstance_g.m_pTimerListFirst)
    {
        SetEvent( EplTimeruInstance_g.m_ahEvents[TIMERU_EVENT_WAKEUP] );
    }
#endif

Exit:
    return Ret;

}
//---------------------------------------------------------------------------
//
// Function:    EplSdoTimeruThreadms
//
// Description: function to process timer as thread
//
//
//
// Parameters:  lpParameter = pointer to structur of type tEplTimeruThread
//
//
// Returns:     DWORD = Errorcode
//
//
// State:
//
//---------------------------------------------------------------------------
DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter)
{
	tEplKernel Ret;
	tEplTimeruThread *pThreadData;
	HANDLE aHandles[2];
	BOOL fReturn;
	LARGE_INTEGER TimeoutTime;
	unsigned long ulEvent;
	tEplEvent EplEvent;
	tEplTimeruThread ThreadData;
	tEplTimerEventArg TimerEventArg;

	Ret = kEplSuccessful;

	// get pointer to data
	pThreadData = (tEplTimeruThread *) lpParameter;
	// copy thread data
	EPL_MEMCPY(&ThreadData, pThreadData, sizeof(ThreadData));
	pThreadData = &ThreadData;

	// leave critical section
	LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);

	// create waitable timer
	aHandles[1] = CreateWaitableTimer(NULL, FALSE, NULL);
	if (aHandles[1] == NULL) {
		Ret = kEplTimerNoTimerCreated;
		goto Exit;
	}
	// set timer
	// set timeout interval -> needed to be negativ
	// -> because relative timeout
	// -> multiply by 10000 for 100 ns timebase of function
	TimeoutTime.QuadPart = (((long long)pThreadData->ulTimeout) * -10000);
	fReturn = SetWaitableTimer(aHandles[1],
				   &TimeoutTime, 0, NULL, NULL, FALSE);
	if (fReturn == 0) {
		Ret = kEplTimerNoTimerCreated;
		goto Exit;
	}
	// save delte event handle in handle array
	aHandles[0] = pThreadData->DelteHandle;

	// wait for one of the events
	ulEvent = WaitForMultipleObjects(2, &aHandles[0], FALSE, INFINITE);
	if (ulEvent == WAIT_OBJECT_0) {	// delte event

		// close handels
		CloseHandle(aHandles[1]);
		// terminate thread
		goto Exit;
	} else if (ulEvent == (WAIT_OBJECT_0 + 1)) {	// timer event
		// call event function
		TimerEventArg.m_TimerHdl =
		    (tEplTimerHdl) pThreadData->DelteHandle;
		TimerEventArg.m_ulArg = pThreadData->TimerArgument.m_ulArg;

		EplEvent.m_EventSink = pThreadData->TimerArgument.m_EventSink;
		EplEvent.m_EventType = kEplEventTypeTimer;
		EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime));
		EplEvent.m_pArg = &TimerEventArg;
		EplEvent.m_uiSize = sizeof(TimerEventArg);

		Ret = EplEventuPost(&EplEvent);

		// close handels
		CloseHandle(aHandles[1]);
		// terminate thread
		goto Exit;

	} else {		// error
		ulEvent = GetLastError();
		TRACE1("Error in WaitForMultipleObjects Errorcode: 0x%x\n",
		       ulEvent);
		// terminate thread
		goto Exit;
	}

      Exit:
	return Ret;
}
예제 #20
0
/**
********************************************************************************
\brief	Constructor

Constructs a POWERLINK object.

\param		pMainWindow_p	        pointer to main window
\param          uiNodeId_p              node ID of the POWERLINK node
\param          devName_p               device name of the network interface
*******************************************************************************/
EplApi::EplApi(MainWindow *pMainWindow_p, unsigned int uiNodeId_p, QString devName_p)
{
    const char*         sHostname = HOSTNAME;
    tEplKernel          EplRet;
    EplState*           pEplState;
    EplOutput*          pEplOutput;
    EplInput*           pEplInput;
    EplCnState*         pEplCnState;
    char                devName[256];

    pEplState = pMainWindow_p->getEplStateWidget();
    pEplOutput = pMainWindow_p->getEplOutputWidget();
    pEplInput = pMainWindow_p->getEplInputWidget();
    pEplCnState = pMainWindow_p->getEplCnStateWidget();

    pEplProcessThread = new EplProcessThread;
    QObject::connect(pEplProcessThread, SIGNAL(eplStatusChanged(int)),
                     pEplState, SLOT(setEplStatusLed(int)));
    QObject::connect(pEplProcessThread, SIGNAL(nmtStateChanged(const QString&)),
                     pEplState, SLOT(setNmtStateText(const QString &)));

    QObject::connect(pEplProcessThread, SIGNAL(nodeAppeared(int)),
                     pEplInput, SLOT(addNode(int)));
    QObject::connect(pEplProcessThread, SIGNAL(allNodesRemoved()),
                     pEplInput, SLOT(removeAllNodes()));
    QObject::connect(pEplProcessThread, SIGNAL(nodeDisappeared(int)),
                     pEplInput, SLOT(removeNode(int)));

    QObject::connect(pEplProcessThread, SIGNAL(nodeAppeared(int)),
                     pEplOutput, SLOT(addNode(int)));
    QObject::connect(pEplProcessThread, SIGNAL(nodeDisappeared(int)),
                     pEplOutput, SLOT(removeNode(int)));
    QObject::connect(pEplProcessThread, SIGNAL(allNodesRemoved()),
                     pEplOutput, SLOT(removeAllNodes()));

    QObject::connect(pEplProcessThread, SIGNAL(nodeAppeared(int)),
                     pEplCnState, SLOT(addNode(int)));
    QObject::connect(pEplProcessThread, SIGNAL(nodeDisappeared(int)),
                     pEplCnState, SLOT(removeNode(int)));
    QObject::connect(pEplProcessThread, SIGNAL(allNodesRemoved()),
                     pEplCnState, SLOT(removeAllNodes()));

    QObject::connect(pEplProcessThread, SIGNAL(nodeStatusChanged(int, int)),
                     pEplCnState, SLOT(setState(int, int)));

    pEplDataInOutThread = new EplDataInOutThread;
    QObject::connect(pEplDataInOutThread, SIGNAL(processImageOutChanged(unsigned int, unsigned int)),
                     pEplOutput, SLOT(setValue(unsigned int, unsigned int)));
    QObject::connect(pEplDataInOutThread, SIGNAL(processImageInChanged(unsigned int, unsigned int)),
                     pEplInput, SLOT(setLeds(unsigned int, unsigned int)));

    EPL_MEMSET(&EplApiInitParam, 0, sizeof (EplApiInitParam));
    EplApiInitParam.m_uiSizeOfStruct = sizeof (EplApiInitParam);


    EplApiInitParam.m_uiNodeId = uiNodeId_p;
    EplApiInitParam.m_dwIpAddress = (IP_ADDR & 0xFFFFFF00) | EplApiInitParam.m_uiNodeId;

    EplApiInitParam.m_fAsyncOnly = FALSE;

    EplApiInitParam.m_dwFeatureFlags = -1;
    EplApiInitParam.m_dwCycleLen = CYCLE_LEN;           // required for error detection
    EplApiInitParam.m_uiIsochrTxMaxPayload = 256;       // const
    EplApiInitParam.m_uiIsochrRxMaxPayload = 256;       // const
    EplApiInitParam.m_dwPresMaxLatency = 50000;         // const; only required for IdentRes
    EplApiInitParam.m_uiPreqActPayloadLimit = 36;       // required for initialisation (+28 bytes)
    EplApiInitParam.m_uiPresActPayloadLimit = 36;       // required for initialisation of Pres frame (+28 bytes)
    EplApiInitParam.m_dwAsndMaxLatency = 150000;        // const; only required for IdentRes
    EplApiInitParam.m_uiMultiplCycleCnt = 0;            // required for error detection
    EplApiInitParam.m_uiAsyncMtu = 1500;                // required to set up max frame size
    EplApiInitParam.m_uiPrescaler = 2;                  // required for sync
    EplApiInitParam.m_dwLossOfFrameTolerance = 500000;
    EplApiInitParam.m_dwAsyncSlotTimeout = 3000000;
    EplApiInitParam.m_dwWaitSocPreq = 150000;
    EplApiInitParam.m_dwDeviceType = -1;                // NMT_DeviceType_U32
    EplApiInitParam.m_dwVendorId = -1;                  // NMT_IdentityObject_REC.VendorId_U32
    EplApiInitParam.m_dwProductCode = -1;               // NMT_IdentityObject_REC.ProductCode_U32
    EplApiInitParam.m_dwRevisionNumber = -1;            // NMT_IdentityObject_REC.RevisionNo_U32
    EplApiInitParam.m_dwSerialNumber = -1;              // NMT_IdentityObject_REC.SerialNo_U32

    EplApiInitParam.m_dwSubnetMask = SUBNET_MASK;
    EplApiInitParam.m_dwDefaultGateway = 0;
    EPL_MEMCPY(EplApiInitParam.m_sHostname, sHostname, sizeof(EplApiInitParam.m_sHostname));
    EplApiInitParam.m_uiSyncNodeId = EPL_C_ADR_SYNC_ON_SOA;
    EplApiInitParam.m_fSyncOnPrcNode = FALSE;

    // set callback functions
    EplApiInitParam.m_pfnCbEvent = pEplProcessThread->getEventCbFunc();

    /* write 00:00:00:00:00:00 to MAC address, so that the driver uses the real hardware address */
    EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr, sizeof (EplApiInitParam.m_abMacAddress));

#ifdef CONFIG_POWERLINK_USERSTACK
    EplApiInitParam.m_HwParam.m_pszDevName = devName_p.toAscii().data();
    EplApiInitParam.m_pfnObdInitRam = EplObdInitRam;
    EplApiInitParam.m_pfnCbSync = pEplDataInOutThread->getSyncCbFunc();
#else
    // Sync call back function not required for init from user space
    EplApiInitParam.m_pfnCbSync = NULL;
#endif

    // init EPL
    EplRet = EplApiInitialize(&EplApiInitParam);
    if(EplRet != kEplSuccessful)
    {
        printf("%s: EplApiInitialize() failed\n", __FUNCTION__);

        QMessageBox::critical(0, "POWERLINK demo",
                              QString("Initialization of openPOWERLINK Stack failed.\n") +
                              "Error code: 0x"+ QString::number(EplRet, 16) +
                              "\nThe most common error source are an unsupported Ethernet controller or the kernel module is not loaded."
                              "\nFor further information please consult the manual.");
        goto Exit;
    }

#ifdef CONFIG_POWERLINK_USERSTACK
    EplRet = EplApiSetCdcFilename(pszCdcFilename_g);
    if(EplRet != kEplSuccessful)
    {
        goto Exit;
    }
#endif

    EplRet = pEplDataInOutThread->SetupProcessImage();
    if (EplRet != kEplSuccessful)
    {
        printf("%s: pEplDataInOutThread->SetupProcessImage() failed\n", __FUNCTION__);
        goto Exit;
    }
    printf("Setup Process Image Successfull\n");

    // start the EPL stack
    EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset);

    // start process thread
    pEplProcessThread->start();

#ifndef CONFIG_POWERLINK_USERSTACK
    // start data in out thread
    pEplDataInOutThread->start();
#endif


Exit:
    printf("%s: returns 0x%X\n", __FUNCTION__, EplRet);

}
예제 #21
0
//---------------------------------------------------------------------------
//
// Function:    openPowerlinkInit
//
// Description:
//    Initialize and start the openPOWERLINK demo application
//
// Parameters:
//    pszEthName = pointer to string with name of network interface to use
//
// Returns: int
//
//---------------------------------------------------------------------------
int openPowerlinkInit (char *pszEthName, unsigned int uiDevNumber)
{
    tEplKernel          EplRet;
    static tEplApiInitParam EplApiInitParam = {0};
    char*               sHostname = HOSTNAME;
    BOOL                fApiInit = FALSE;
    int                 tid;

    // Adjust task priorities of system tasks

    /* shell task is normally set to priority 1 which could disturb
     * openPOWERLINK if long-running commands are entered. Therefore
     * we lower the performance to 20
     */
    tid = taskIdSelf();
    printf ("Task ID: %d\n", tid);
    taskPrioritySet(tid, 20);

    /* The priority of the network stack task has to be increased (default:50)
     * in order to get network packets in time!
     */
    if ((tid = taskNameToId("tNet0")) != -1 )
    {
        taskPrioritySet(tid, 5);
    }

    // Initialize high-resolution timer library
    hrtimer_init(EPL_TASK_PRIORITY_HRTIMER, EPL_TASK_STACK_SIZE);

    // get node ID from insmod command line
    EplApiInitParam.m_uiNodeId = uiNodeId_g;

    if (EplApiInitParam.m_uiNodeId == EPL_C_ADR_INVALID)
    {   // invalid node ID set
        // set default node ID
        EplApiInitParam.m_uiNodeId = NODEID;
    }

    uiNodeId_g = EplApiInitParam.m_uiNodeId;

    // calculate IP address
    EplApiInitParam.m_dwIpAddress = (0xFFFFFF00 & IP_ADDR) |
                                    EplApiInitParam.m_uiNodeId;

    EplApiInitParam.m_fAsyncOnly = FALSE;

    // store the specified device name
    EplApiInitParam.m_HwParam.m_pszDevName = pszEthName;
    EplApiInitParam.m_HwParam.m_uiDevNumber = uiDevNumber;

    EplApiInitParam.m_uiSizeOfStruct = sizeof (EplApiInitParam);
    EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr,
               sizeof (EplApiInitParam.m_abMacAddress));
    EplApiInitParam.m_dwFeatureFlags = (DWORD) ~0UL;
    EplApiInitParam.m_dwCycleLen = uiCycleLen_g;  // required for error detection
    EplApiInitParam.m_uiIsochrTxMaxPayload = 100; // const
    EplApiInitParam.m_uiIsochrRxMaxPayload = 100; // const
    EplApiInitParam.m_dwPresMaxLatency = 50000;   // const; only required for IdentRes
    EplApiInitParam.m_uiPreqActPayloadLimit = 36; // required for initialisation (+28 bytes)
    EplApiInitParam.m_uiPresActPayloadLimit = 36; // required for initialisation of Pres frame (+28 bytes)
    EplApiInitParam.m_dwAsndMaxLatency = 150000;  // const; only required for IdentRes
    EplApiInitParam.m_uiMultiplCycleCnt = 0;      // required for error detection
    EplApiInitParam.m_uiAsyncMtu = 1500;          // required to set up max frame size
    EplApiInitParam.m_uiPrescaler = 2;            // required for sync
    EplApiInitParam.m_dwLossOfFrameTolerance = 500000;
    EplApiInitParam.m_dwAsyncSlotTimeout = 3000000;
    EplApiInitParam.m_dwWaitSocPreq = 0;
    EplApiInitParam.m_dwDeviceType = (DWORD) ~0UL;      // NMT_DeviceType_U32
    EplApiInitParam.m_dwVendorId = (DWORD) ~0UL;        // NMT_IdentityObject_REC.VendorId_U32
    EplApiInitParam.m_dwProductCode = (DWORD) ~0UL;     // NMT_IdentityObject_REC.ProductCode_U32
    EplApiInitParam.m_dwRevisionNumber = (DWORD) ~0UL;  // NMT_IdentityObject_REC.RevisionNo_U32
    EplApiInitParam.m_dwSerialNumber = (DWORD) ~0UL;    // NMT_IdentityObject_REC.SerialNo_U32
    EplApiInitParam.m_dwSubnetMask = SUBNET_MASK;
    EplApiInitParam.m_dwDefaultGateway = 0;
    EPL_MEMCPY(EplApiInitParam.m_sHostname, sHostname, sizeof(EplApiInitParam.m_sHostname));
    EplApiInitParam.m_uiSyncNodeId = EPL_C_ADR_SYNC_ON_SOA; // for fSyncOnPrcNode==TRUE, this means last PRC node
    EplApiInitParam.m_fSyncOnPrcNode = TRUE;

    // set callback functions
    EplApiInitParam.m_pfnCbEvent = AppCbEvent;
    EplApiInitParam.m_pfnCbSync  = AppCbSync;
    EplApiInitParam.m_pfnObdInitRam = EplObdInitRam;

    printf("\n\n Hello, I'm a VxWorks POWERLINK node running as %s!\n"
           "(build: %s / %s)\n\n",
            (uiNodeId_g == EPL_C_ADR_MN_DEF_NODE_ID ?
                "Managing Node" : "Controlled Node"),
            __DATE__, __TIME__);

    // initialize POWERLINK stack
    EplRet = EplApiInitialize(&EplApiInitParam);
    if(EplRet != kEplSuccessful)
    {
        goto Exit;
    }
    fApiInit = TRUE;

    // set CDC filename
    EplRet = EplApiSetCdcFilename(pszCdcFilename_g);
    if(EplRet != kEplSuccessful)
    {
    	printf ("Error set cdc filename!\n");
        goto Exit;
    }

    // initialize application
    printf ("Initializing openPOWERLINK application...\n");
    EplRet = AppInit();
    if(EplRet != kEplSuccessful)
    {
        printf("ApiInit() failed!\n");
        goto Exit;
    }

    // initialize process image
    printf("Initializing process image...\n");
    printf("Size of input process image: %ld\n", sizeof(AppProcessImageIn_g));
    printf("Size of output process image: %ld\n", sizeof (AppProcessImageOut_g));
    AppProcessImageCopyJob_g.m_fNonBlocking = FALSE;
    AppProcessImageCopyJob_g.m_uiPriority = 0;
    AppProcessImageCopyJob_g.m_In.m_pPart = &AppProcessImageIn_g;
    AppProcessImageCopyJob_g.m_In.m_uiOffset = 0;
    AppProcessImageCopyJob_g.m_In.m_uiSize = sizeof (AppProcessImageIn_g);
    AppProcessImageCopyJob_g.m_Out.m_pPart = &AppProcessImageOut_g;
    AppProcessImageCopyJob_g.m_Out.m_uiOffset = 0;
    AppProcessImageCopyJob_g.m_Out.m_uiSize = sizeof (AppProcessImageOut_g);

    EplRet = EplApiProcessImageAlloc(sizeof (AppProcessImageIn_g),
                                     sizeof (AppProcessImageOut_g), 2, 2);
    if (EplRet != kEplSuccessful)
    {
        goto Exit;
    }

    EplRet = EplApiProcessImageSetup();
    if (EplRet != kEplSuccessful)
    {
        goto Exit;
    }

    // start the NMT state machine
    EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset);

Exit:
    PRINTF("%s(): returns 0x%X\n", __func__, EplRet);
    if (EplRet != kEplSuccessful)
    {
        if (fApiInit != FALSE)
        {
            EplApiShutdown();
        }

        // Shutdown high-resolution timer library
        hrtimer_shutdown();
        fOpenPowerlinkIsRunning_g = FALSE;
        return -ENODEV;
    }
    else
    {
        fOpenPowerlinkIsRunning_g = TRUE;
        return 0;
    }
}