示例#1
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);

}
示例#2
0
static int EplLinIoctl(struct inode *pDeviceFile_p,	// information about the device to open
		       struct file *pInstance_p,	// information about driver instance
		       unsigned int uiIoctlCmd_p,	// Ioctl command to execute
		       unsigned long ulArg_p)	// Ioctl command specific argument/parameter
{

	tEplKernel EplRet;
	int iErr;
	int iRet;

//    TRACE1("EPL: + EplLinIoctl (uiIoctlCmd_p=%d)...\n", uiIoctlCmd_p);

	iRet = -EINVAL;

	switch (uiIoctlCmd_p) {
		// ----------------------------------------------------------
	case EPLLIN_CMD_INITIALIZE:
		{
			tEplApiInitParam EplApiInitParam;

			iErr =
			    copy_from_user(&EplApiInitParam,
					   (const void *)ulArg_p,
					   sizeof(EplApiInitParam));
			if (iErr != 0) {
				iRet = -EIO;
				goto Exit;
			}

			EplApiInitParam.m_pfnCbEvent = EplLinCbEvent;
			EplApiInitParam.m_pfnCbSync = EplLinCbSync;

			EplRet = EplApiInitialize(&EplApiInitParam);

			uiEplState_g = EPL_STATE_RUNNING;

			iRet = (int)EplRet;
			break;
		}

		// ----------------------------------------------------------
	case EPLLIN_CMD_SHUTDOWN:
		{		// shutdown the threads

			// pass control to sync kernel thread, but signal termination
			atomic_set(&AtomicSyncState_g, EVENT_STATE_TERM);
			wake_up_interruptible(&WaitQueueCbSync_g);
			wake_up_interruptible(&WaitQueuePI_In_g);

			// pass control to event queue kernel thread
			atomic_set(&AtomicEventState_g, EVENT_STATE_TERM);
			wake_up_interruptible(&WaitQueueCbEvent_g);

			if (uiEplState_g == EPL_STATE_RUNNING) {	// post NmtEventSwitchOff
				EplRet =
				    EplApiExecNmtCommand(kEplNmtEventSwitchOff);

			}

			iRet = 0;
			break;
		}

		// ----------------------------------------------------------
	case EPLLIN_CMD_READ_LOCAL_OBJECT:
		{
			tEplLinLocalObject LocalObject;
			void *pData;

			iErr =
			    copy_from_user(&LocalObject, (const void *)ulArg_p,
					   sizeof(LocalObject));
			if (iErr != 0) {
				iRet = -EIO;
				goto Exit;
			}

			if ((LocalObject.m_pData == NULL)
			    || (LocalObject.m_uiSize == 0)) {
				iRet = (int)kEplApiInvalidParam;
				goto Exit;
			}

			pData = vmalloc(LocalObject.m_uiSize);
			if (pData == NULL) {	// no memory available
				iRet = -ENOMEM;
				goto Exit;
			}

			EplRet =
			    EplApiReadLocalObject(LocalObject.m_uiIndex,
						  LocalObject.m_uiSubindex,
						  pData, &LocalObject.m_uiSize);

			if (EplRet == kEplSuccessful) {
				iErr =
				    copy_to_user(LocalObject.m_pData, pData,
						 LocalObject.m_uiSize);

				vfree(pData);

				if (iErr != 0) {
					iRet = -EIO;
					goto Exit;
				}
				// return actual size (LocalObject.m_uiSize)
				iErr = put_user(LocalObject.m_uiSize,
						(unsigned int *)(ulArg_p +
								 (unsigned long)
								 &LocalObject.
								 m_uiSize -
								 (unsigned long)
								 &LocalObject));
				if (iErr != 0) {
					iRet = -EIO;
					goto Exit;
				}

			} else {
				vfree(pData);
			}

			iRet = (int)EplRet;
			break;
		}

		// ----------------------------------------------------------
	case EPLLIN_CMD_WRITE_LOCAL_OBJECT:
		{
			tEplLinLocalObject LocalObject;
			void *pData;

			iErr =
			    copy_from_user(&LocalObject, (const void *)ulArg_p,
					   sizeof(LocalObject));
			if (iErr != 0) {
				iRet = -EIO;
				goto Exit;
			}

			if ((LocalObject.m_pData == NULL)
			    || (LocalObject.m_uiSize == 0)) {
				iRet = (int)kEplApiInvalidParam;
				goto Exit;
			}

			pData = vmalloc(LocalObject.m_uiSize);
			if (pData == NULL) {	// no memory available
				iRet = -ENOMEM;
				goto Exit;
			}
			iErr =
			    copy_from_user(pData, LocalObject.m_pData,
					   LocalObject.m_uiSize);
			if (iErr != 0) {
				iRet = -EIO;
				goto Exit;
			}

			EplRet =
			    EplApiWriteLocalObject(LocalObject.m_uiIndex,
						   LocalObject.m_uiSubindex,
						   pData, LocalObject.m_uiSize);

			vfree(pData);

			iRet = (int)EplRet;
			break;
		}

	case EPLLIN_CMD_READ_OBJECT:
		{
			tEplLinSdoObject SdoObject;
			void *pData;
			tEplLinSdoBufHeader *pBufHeader;
			tEplSdoComConHdl *pSdoComConHdl;

			iErr =
			    copy_from_user(&SdoObject, (const void *)ulArg_p,
					   sizeof(SdoObject));
			if (iErr != 0) {
				iRet = -EIO;
				goto Exit;
			}

			if ((SdoObject.m_le_pData == NULL)
			    || (SdoObject.m_uiSize == 0)) {
				iRet = (int)kEplApiInvalidParam;
				goto Exit;
			}

			pBufHeader =
			    (tEplLinSdoBufHeader *)
			    vmalloc(sizeof(tEplLinSdoBufHeader) +
				    SdoObject.m_uiSize);
			if (pBufHeader == NULL) {	// no memory available
				iRet = -ENOMEM;
				goto Exit;
			}
			// initiate temporary buffer
			pBufHeader->m_pUserArg = SdoObject.m_pUserArg;	// original user argument pointer
			pBufHeader->m_pData = SdoObject.m_le_pData;	// original data pointer from app
			pData = pBufHeader + sizeof(tEplLinSdoBufHeader);

			if (SdoObject.m_fValidSdoComConHdl != FALSE) {
				pSdoComConHdl = &SdoObject.m_SdoComConHdl;
			} else {
				pSdoComConHdl = NULL;
			}

			EplRet =
			    EplApiReadObject(pSdoComConHdl,
					     SdoObject.m_uiNodeId,
					     SdoObject.m_uiIndex,
					     SdoObject.m_uiSubindex, pData,
					     &SdoObject.m_uiSize,
					     SdoObject.m_SdoType, pBufHeader);

			// return actual SDO handle (SdoObject.m_SdoComConHdl)
			iErr = put_user(SdoObject.m_SdoComConHdl,
					(unsigned int *)(ulArg_p +
							 (unsigned long)
							 &SdoObject.
							 m_SdoComConHdl -
							 (unsigned long)
							 &SdoObject));
			if (iErr != 0) {
				iRet = -EIO;
				goto Exit;
			}

			if (EplRet == kEplSuccessful) {
				iErr =
				    copy_to_user(SdoObject.m_le_pData, pData,
						 SdoObject.m_uiSize);

				vfree(pBufHeader);

				if (iErr != 0) {
					iRet = -EIO;
					goto Exit;
				}
				// return actual size (SdoObject.m_uiSize)
				iErr = put_user(SdoObject.m_uiSize,
						(unsigned int *)(ulArg_p +
								 (unsigned long)
								 &SdoObject.
								 m_uiSize -
								 (unsigned long)
								 &SdoObject));
				if (iErr != 0) {
					iRet = -EIO;
					goto Exit;
				}
			} else if (EplRet != kEplApiTaskDeferred) {	// error ocurred
				vfree(pBufHeader);
				if (iErr != 0) {
					iRet = -EIO;
					goto Exit;
				}
			}

			iRet = (int)EplRet;
			break;
		}

	case EPLLIN_CMD_WRITE_OBJECT:
		{
			tEplLinSdoObject SdoObject;
			void *pData;
			tEplLinSdoBufHeader *pBufHeader;
			tEplSdoComConHdl *pSdoComConHdl;

			iErr =
			    copy_from_user(&SdoObject, (const void *)ulArg_p,
					   sizeof(SdoObject));
			if (iErr != 0) {
				iRet = -EIO;
				goto Exit;
			}

			if ((SdoObject.m_le_pData == NULL)
			    || (SdoObject.m_uiSize == 0)) {
				iRet = (int)kEplApiInvalidParam;
				goto Exit;
			}

			pBufHeader =
			    (tEplLinSdoBufHeader *)
			    vmalloc(sizeof(tEplLinSdoBufHeader) +
				    SdoObject.m_uiSize);
			if (pBufHeader == NULL) {	// no memory available
				iRet = -ENOMEM;
				goto Exit;
			}
			// initiate temporary buffer
			pBufHeader->m_pUserArg = SdoObject.m_pUserArg;	// original user argument pointer
			pBufHeader->m_pData = SdoObject.m_le_pData;	// original data pointer from app
			pData = pBufHeader + sizeof(tEplLinSdoBufHeader);

			iErr =
			    copy_from_user(pData, SdoObject.m_le_pData,
					   SdoObject.m_uiSize);

			if (iErr != 0) {
				iRet = -EIO;
				goto Exit;
			}

			if (SdoObject.m_fValidSdoComConHdl != FALSE) {
				pSdoComConHdl = &SdoObject.m_SdoComConHdl;
			} else {
				pSdoComConHdl = NULL;
			}

			EplRet =
			    EplApiWriteObject(pSdoComConHdl,
					      SdoObject.m_uiNodeId,
					      SdoObject.m_uiIndex,
					      SdoObject.m_uiSubindex, pData,
					      SdoObject.m_uiSize,
					      SdoObject.m_SdoType, pBufHeader);

			// return actual SDO handle (SdoObject.m_SdoComConHdl)
			iErr = put_user(SdoObject.m_SdoComConHdl,
					(unsigned int *)(ulArg_p +
							 (unsigned long)
							 &SdoObject.
							 m_SdoComConHdl -
							 (unsigned long)
							 &SdoObject));
			if (iErr != 0) {
				iRet = -EIO;
				goto Exit;
			}

			if (EplRet != kEplApiTaskDeferred) {	// succeeded or error ocurred, but task not deferred
				vfree(pBufHeader);
			}

			iRet = (int)EplRet;
			break;
		}

		// ----------------------------------------------------------
	case EPLLIN_CMD_FREE_SDO_CHANNEL:
		{
			// forward SDO handle to EPL stack
			EplRet =
			    EplApiFreeSdoChannel((tEplSdoComConHdl) ulArg_p);

			iRet = (int)EplRet;
			break;
		}

#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
		// ----------------------------------------------------------
	case EPLLIN_CMD_MN_TRIGGER_STATE_CHANGE:
		{
			tEplLinNodeCmdObject NodeCmdObject;

			iErr =
			    copy_from_user(&NodeCmdObject,
					   (const void *)ulArg_p,
					   sizeof(NodeCmdObject));
			if (iErr != 0) {
				iRet = -EIO;
				goto Exit;
			}

			EplRet =
			    EplApiMnTriggerStateChange(NodeCmdObject.m_uiNodeId,
						       NodeCmdObject.
						       m_NodeCommand);
			iRet = (int)EplRet;
			break;
		}
#endif

		// ----------------------------------------------------------
	case EPLLIN_CMD_GET_EVENT:
		{
			tEplLinEvent Event;

			// save event structure
			iErr =
			    copy_from_user(&Event, (const void *)ulArg_p,
					   sizeof(Event));
			if (iErr != 0) {
				iRet = -EIO;
				goto Exit;
			}
			// save return code from application's event callback function
			RetCbEvent_g = Event.m_RetCbEvent;

			if (RetCbEvent_g == kEplShutdown) {
				// pass control to event queue kernel thread, but signal termination
				atomic_set(&AtomicEventState_g,
					   EVENT_STATE_TERM);
				wake_up_interruptible(&WaitQueueCbEvent_g);
				// exit with error -> EplApiProcess() will leave the infinite loop
				iRet = 1;
				goto Exit;
			}
			// pass control to event queue kernel thread
			atomic_set(&AtomicEventState_g, EVENT_STATE_IOCTL);
			wake_up_interruptible(&WaitQueueCbEvent_g);

			// fall asleep itself in own wait queue
			iErr = wait_event_interruptible(WaitQueueProcess_g,
							(atomic_read
							 (&AtomicEventState_g)
							 == EVENT_STATE_READY)
							||
							(atomic_read
							 (&AtomicEventState_g)
							 == EVENT_STATE_TERM));
			if (iErr != 0) {	// waiting was interrupted by signal
				// pass control to event queue kernel thread, but signal termination
				atomic_set(&AtomicEventState_g,
					   EVENT_STATE_TERM);
				wake_up_interruptible(&WaitQueueCbEvent_g);
				// exit with this error -> EplApiProcess() will leave the infinite loop
				iRet = iErr;
				goto Exit;
			} else if (atomic_read(&AtomicEventState_g) == EVENT_STATE_TERM) {	// termination in progress
				// pass control to event queue kernel thread, but signal termination
				wake_up_interruptible(&WaitQueueCbEvent_g);
				// exit with this error -> EplApiProcess() will leave the infinite loop
				iRet = 1;
				goto Exit;
			}
			// copy event to user space
			iErr =
			    copy_to_user(Event.m_pEventType, &EventType_g,
					 sizeof(EventType_g));
			if (iErr != 0) {	// not all data could be copied
				iRet = -EIO;
				goto Exit;
			}
			// $$$ d.k. perform SDO event processing
			if (EventType_g == kEplApiEventSdo) {
				void *pData;
				tEplLinSdoBufHeader *pBufHeader;

				pBufHeader =
				    (tEplLinSdoBufHeader *) pEventArg_g->m_Sdo.
				    m_pUserArg;
				pData =
				    pBufHeader + sizeof(tEplLinSdoBufHeader);

				if (pEventArg_g->m_Sdo.m_SdoAccessType ==
				    kEplSdoAccessTypeRead) {
					// copy read data to user space
					iErr =
					    copy_to_user(pBufHeader->m_pData,
							 pData,
							 pEventArg_g->m_Sdo.
							 m_uiTransferredByte);
					if (iErr != 0) {	// not all data could be copied
						iRet = -EIO;
						goto Exit;
					}
				}
				pEventArg_g->m_Sdo.m_pUserArg =
				    pBufHeader->m_pUserArg;
				vfree(pBufHeader);
			}

			iErr =
			    copy_to_user(Event.m_pEventArg, pEventArg_g,
					 min(sizeof(tEplApiEventArg),
					     Event.m_uiEventArgSize));
			if (iErr != 0) {	// not all data could be copied
				iRet = -EIO;
				goto Exit;
			}
			// return to EplApiProcess(), which will call the application's event callback function
			iRet = 0;

			break;
		}

		// ----------------------------------------------------------
	case EPLLIN_CMD_PI_SETUP:
		{
			EplRet = EplApiProcessImageSetup();
			iRet = (int)EplRet;

			break;
		}

		// ----------------------------------------------------------
	case EPLLIN_CMD_PI_IN:
		{
			tEplApiProcessImage ProcessImageIn;

			// save process image structure
			iErr =
			    copy_from_user(&ProcessImageIn,
					   (const void *)ulArg_p,
					   sizeof(ProcessImageIn));
			if (iErr != 0) {
				iRet = -EIO;
				goto Exit;
			}
			// pass control to event queue kernel thread
			atomic_set(&AtomicSyncState_g, EVENT_STATE_IOCTL);

			// fall asleep itself in own wait queue
			iErr = wait_event_interruptible(WaitQueuePI_In_g,
							(atomic_read
							 (&AtomicSyncState_g) ==
							 EVENT_STATE_READY)
							||
							(atomic_read
							 (&AtomicSyncState_g) ==
							 EVENT_STATE_TERM));
			if (iErr != 0) {	// waiting was interrupted by signal
				// pass control to sync kernel thread, but signal termination
				atomic_set(&AtomicSyncState_g,
					   EVENT_STATE_TERM);
				wake_up_interruptible(&WaitQueueCbSync_g);
				// exit with this error -> application will leave the infinite loop
				iRet = iErr;
				goto Exit;
			} else if (atomic_read(&AtomicSyncState_g) == EVENT_STATE_TERM) {	// termination in progress
				// pass control to sync kernel thread, but signal termination
				wake_up_interruptible(&WaitQueueCbSync_g);
				// exit with this error -> application will leave the infinite loop
				iRet = 1;
				goto Exit;
			}
			// exchange process image
			EplRet = EplApiProcessImageExchangeIn(&ProcessImageIn);

			// return to EplApiProcessImageExchangeIn()
			iRet = (int)EplRet;

			break;
		}

		// ----------------------------------------------------------
	case EPLLIN_CMD_PI_OUT:
		{
			tEplApiProcessImage ProcessImageOut;

			// save process image structure
			iErr =
			    copy_from_user(&ProcessImageOut,
					   (const void *)ulArg_p,
					   sizeof(ProcessImageOut));
			if (iErr != 0) {
				iRet = -EIO;
				goto Exit;
			}

			if (atomic_read(&AtomicSyncState_g) !=
			    EVENT_STATE_READY) {
				iRet = (int)kEplInvalidOperation;
				goto Exit;
			}
			// exchange process image
			EplRet =
			    EplApiProcessImageExchangeOut(&ProcessImageOut);

			// pass control to sync kernel thread
			atomic_set(&AtomicSyncState_g, EVENT_STATE_TERM);
			wake_up_interruptible(&WaitQueueCbSync_g);

			// return to EplApiProcessImageExchangeout()
			iRet = (int)EplRet;

			break;
		}

		// ----------------------------------------------------------
	case EPLLIN_CMD_NMT_COMMAND:
		{
			// forward NMT command to EPL stack
			EplRet = EplApiExecNmtCommand((tEplNmtEvent) ulArg_p);

			iRet = (int)EplRet;

			break;
		}

		// ----------------------------------------------------------
	default:
		{
			break;
		}
	}

      Exit:

//    TRACE1("EPL: - EplLinIoctl (iRet=%d)\n", iRet);
	return (iRet);

}
//---------------------------------------------------------------------------
//
// 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;
}
示例#4
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;
    }
}
示例#5
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;
    }
}
示例#6
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;
}
示例#7
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;

}