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);

}
tEplKernel PUBLIC AppCbEvent
(
    tEplApiEventType        EventType_p,   // IN: event type (enum)
    tEplApiEventArg*        pEventArg_p,   // IN: event argument (union)
    void GENERIC*           pUserArg_p    //__attribute((unused))
)
{
    tEplKernel          EplRet = kEplSuccessful;
    UINT                uiVarLen;

    UNUSED_PARAMETER(pUserArg_p);

    // check if NMT_GS_OFF is reached
    switch (EventType_p)
    {
        case kEplApiEventNmtStateChange:
        {
            switch (pEventArg_p->m_NmtStateChange.m_NewNmtState)
            {
                case kEplNmtGsOff:
                {   // NMT state machine was shut down,
                    // because of user signal (CTRL-C) or critical EPL stack error
                    // -> also shut down EplApiProcess() and main()
                    EplRet = kEplShutdown;

                    printlog("Event:kEplNmtGsOff originating event = 0x%X (%s)\n", pEventArg_p->m_NmtStateChange.m_NmtEvent,
                             EplGetNmtEventStr(pEventArg_p->m_NmtStateChange.m_NmtEvent));
                    break;
                }

                case kEplNmtGsResetCommunication:
                {
                    // continue
                }

                case kEplNmtGsResetConfiguration:
                {
                    if (uiCycleLen_g != 0)
                    {
                        EplRet = EplApiWriteLocalObject(0x1006, 0x00, &uiCycleLen_g, sizeof (uiCycleLen_g));
                        uiCurCycleLen_g = uiCycleLen_g;
                    }
                    else
                    {
                        uiVarLen = sizeof(uiCurCycleLen_g);
                        EplApiReadLocalObject(0x1006, 0x00, &uiCurCycleLen_g, &uiVarLen);
                    }
                    // continue
                }

                case kEplNmtMsPreOperational1:
                {
                    printlog("AppCbEvent(0x%X) originating event = 0x%X (%s)\n",
                           pEventArg_p->m_NmtStateChange.m_NewNmtState,
                           pEventArg_p->m_NmtStateChange.m_NmtEvent,
                           EplGetNmtEventStr(pEventArg_p->m_NmtStateChange.m_NmtEvent));

                    // continue
                }

                case kEplNmtGsInitialising:
                case kEplNmtGsResetApplication:
                case kEplNmtMsNotActive:
                case kEplNmtCsNotActive:
                case kEplNmtCsPreOperational1:
                {
                    break;
                }

                case kEplNmtCsOperational:
                case kEplNmtMsOperational:
                {
                    break;
                }

                default:
                {
                    break;
                }
            }

            break;
        }

        case kEplApiEventCriticalError:
        case kEplApiEventWarning:
        {   // error or warning occurred within the stack or the application
            // on error the API layer stops the NMT state machine

            printlog( "%s(Err/Warn): Source = %s (%02X) EplError = %s (0x%03X)\n",
                        __func__,
                        EplGetEventSourceStr(pEventArg_p->m_InternalError.m_EventSource),
                        pEventArg_p->m_InternalError.m_EventSource,
                        EplGetEplKernelStr(pEventArg_p->m_InternalError.m_EplError),
                        pEventArg_p->m_InternalError.m_EplError
                        );
            FTRACE_MARKER("%s(Err/Warn): Source = %s (%02X) EplError = %s (0x%03X)\n",
                        __func__,
                        EplGetEventSourceStr(pEventArg_p->m_InternalError.m_EventSource),
                        pEventArg_p->m_InternalError.m_EventSource,
                        EplGetEplKernelStr(pEventArg_p->m_InternalError.m_EplError),
                        pEventArg_p->m_InternalError.m_EplError
                        );
            // check additional argument
            switch (pEventArg_p->m_InternalError.m_EventSource)
            {
                case kEplEventSourceEventk:
                case kEplEventSourceEventu:
                {   // error occurred within event processing
                    // either in kernel or in user part
                    printlog(" OrgSource = %s %02X\n",  EplGetEventSourceStr(pEventArg_p->m_InternalError.m_Arg.m_EventSource),
                                                        pEventArg_p->m_InternalError.m_Arg.m_EventSource);
                    FTRACE_MARKER(" OrgSource = %s %02X\n",     EplGetEventSourceStr(pEventArg_p->m_InternalError.m_Arg.m_EventSource),
                                                                pEventArg_p->m_InternalError.m_Arg.m_EventSource);
                    break;
                }

                case kEplEventSourceDllk:
                {   // error occurred within the data link layer (e.g. interrupt processing)
                    // the DWORD argument contains the DLL state and the NMT event
                    printlog(" val = %X\n", pEventArg_p->m_InternalError.m_Arg.m_dwArg);
                    FTRACE_MARKER(" val = %X\n", pEventArg_p->m_InternalError.m_Arg.m_dwArg);
                    break;
                }

                default:
                {
                    printlog("\n");
                    break;
                }
            }
            break;
        }

        case kEplApiEventHistoryEntry:
        {   // new history entry

            printlog("%s(HistoryEntry): Type=0x%04X Code=0x%04X (0x%02X %02X %02X %02X %02X %02X %02X %02X)\n",
                    __func__,
                    pEventArg_p->m_ErrHistoryEntry.m_wEntryType,
                    pEventArg_p->m_ErrHistoryEntry.m_wErrorCode,
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[0],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[1],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[2],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[3],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[4],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[5],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[6],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[7]);
            FTRACE_MARKER("%s(HistoryEntry): Type=0x%04X Code=0x%04X (0x%02X %02X %02X %02X %02X %02X %02X %02X)\n",
                                __func__,
                                pEventArg_p->m_ErrHistoryEntry.m_wEntryType,
                                pEventArg_p->m_ErrHistoryEntry.m_wErrorCode,
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[0],
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[1],
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[2],
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[3],
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[4],
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[5],
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[6],
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[7]);
            break;
        }

        case kEplApiEventPdoChange:
        {
            unsigned int uiSubIndex;
            QWORD qwMappObject;

            printlog("%s(%sPDO=0x%X to node 0x%X with %d objects %s)\n",
                    __func__,
                    (pEventArg_p->m_PdoChange.m_fTx ? "T" : "R"),
                    pEventArg_p->m_PdoChange.m_uiPdoMappIndex,
                    pEventArg_p->m_PdoChange.m_uiNodeId,
                    pEventArg_p->m_PdoChange.m_uiMappObjectCount,
                    (pEventArg_p->m_PdoChange.m_fActivated ? "activated" : "deleted"));
            for (uiSubIndex = 1; uiSubIndex <= pEventArg_p->m_PdoChange.m_uiMappObjectCount; uiSubIndex++)
            {
                uiVarLen = sizeof(qwMappObject);
                EplRet = EplApiReadLocalObject(
                        pEventArg_p->m_PdoChange.m_uiPdoMappIndex,
                        uiSubIndex, &qwMappObject, &uiVarLen);
                if (EplRet != kEplSuccessful)
                {
                    printlog("  Reading 0x%X/%d failed with 0x%X\n",
                            pEventArg_p->m_PdoChange.m_uiPdoMappIndex,
                            uiSubIndex, EplRet);
                    continue;
                }
                printlog("  %d. mapped object 0x%X/%d\n",
                        uiSubIndex,
                        qwMappObject & 0x00FFFFULL,
                        (qwMappObject & 0xFF0000ULL) >> 16);
            }
            break;
        }

#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
        case kEplApiEventNode:
        {
            // check additional argument
            switch (pEventArg_p->m_Node.m_NodeEvent)
            {
                case kEplNmtNodeEventCheckConf:
                {
                    printlog("%s(Node=0x%X, CheckConf)\n", __func__, pEventArg_p->m_Node.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeEventUpdateConf:
                {
                    printlog("%s(Node=0x%X, UpdateConf)\n", __func__, pEventArg_p->m_Node.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeEventNmtState:
                {
                    printlog("%s(Node=0x%X, NmtState=%s)\n", __func__, pEventArg_p->m_Node.m_uiNodeId, EplGetNmtStateStr(pEventArg_p->m_Node.m_NmtState));

                    break;
                }

                case kEplNmtNodeEventError:
                {
                    printlog("%s (Node=0x%X): Error = %s (0x%.4X)\n", __func__,
                            pEventArg_p->m_Node.m_uiNodeId,
                            EplGetEmergErrCodeStr(pEventArg_p->m_Node.m_wErrorCode),
                            pEventArg_p->m_Node.m_wErrorCode);

                    break;
                }

                case kEplNmtNodeEventFound:
                {
                    printlog("%s(Node=0x%X, Found)\n", __func__, pEventArg_p->m_Node.m_uiNodeId);

                    break;
                }

                default:
                {
                    break;
                }
            }
            break;
        }

#endif

#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFM)) != 0)
       case kEplApiEventCfmProgress:
        {
            printlog("%s(Node=0x%X, CFM-Progress: Object 0x%X/%u, ", __func__, pEventArg_p->m_CfmProgress.m_uiNodeId, pEventArg_p->m_CfmProgress.m_uiObjectIndex, pEventArg_p->m_CfmProgress.m_uiObjectSubIndex);
            printlog("%lu/%lu Bytes", (ULONG) pEventArg_p->m_CfmProgress.m_dwBytesDownloaded, (ULONG) pEventArg_p->m_CfmProgress.m_dwTotalNumberOfBytes);
            if ((pEventArg_p->m_CfmProgress.m_dwSdoAbortCode != 0)
                || (pEventArg_p->m_CfmProgress.m_EplError != kEplSuccessful))
            {
                printlog(" -> SDO Abort=0x%lX, Error=0x%X)\n", (unsigned long) pEventArg_p->m_CfmProgress.m_dwSdoAbortCode,
                                                              pEventArg_p->m_CfmProgress.m_EplError);
            }
            else
            {
                printlog(")\n");
            }
            break;
        }

        case kEplApiEventCfmResult:
        {
            switch (pEventArg_p->m_CfmResult.m_NodeCommand)
            {
                case kEplNmtNodeCommandConfOk:
                {
                    printlog("%s(Node=0x%X, ConfOk)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfErr:
                {
                    printlog("%s(Node=0x%X, ConfErr)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfReset:
                {
                    printlog("%s(Node=0x%X, ConfReset)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfRestored:
                {
                    printlog("%s(Node=0x%X, ConfRestored)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                default:
                {
                    printlog("%s(Node=0x%X, CfmResult=0x%X)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId, pEventArg_p->m_CfmResult.m_NodeCommand);
                    break;
                }
            }
            break;
        }
#endif

        default:
            break;
    }

    return EplRet;
}
Beispiel #3
0
tEplKernel PUBLIC AppCbEvent(
    tEplApiEventType        eventType_p,   // IN: event type (enum)
    tEplApiEventArg*        pEventArg_p,   // IN: event argument (union)
    void GENERIC*           pUserArg_p)
{
tEplKernel          EplRet = kEplSuccessful;

    UNUSED_PARAMETER(pUserArg_p);

    // check if NMT_GS_OFF is reached
    switch (eventType_p)
    {
        case kEplApiEventNmtStateChange:
        {
            switch (pEventArg_p->m_NmtStateChange.m_NewNmtState)
            {
                case kEplNmtGsOff:
                {   // NMT state machine was shut down,
                    // because of user signal (CTRL-C) or critical EPL stack error
                    // -> also shut down EplApiProcess() and main()
                    EplRet = kEplShutdown;

                    PRINTF("%s(kEplNmtGsOff) originating event = 0x%X\n", __func__, pEventArg_p->m_NmtStateChange.m_NmtEvent);

                    // wake up EplLinExit()
                    atomic_set(&AtomicShutdown_g, TRUE);
                    wake_up_interruptible(&WaitQueueShutdown_g);
                    break;
                }

                case kEplNmtGsResetCommunication:
                {
                    // continue
                }

                case kEplNmtGsResetConfiguration:
                {
                    if (uiCycleLen_g != 0)
                    {
                        EplRet = EplApiWriteLocalObject(0x1006, 0x00, &uiCycleLen_g, sizeof (uiCycleLen_g));
                    }
                    // continue
                }

                case kEplNmtMsPreOperational1:
                {
                    PRINTF("%s(0x%X -> 0x%X) originating event = 0x%X\n",
                            __func__,
                           pEventArg_p->m_NmtStateChange.m_OldNmtState,
                           pEventArg_p->m_NmtStateChange.m_NewNmtState,
                           pEventArg_p->m_NmtStateChange.m_NmtEvent);

                    // continue
                }

                case kEplNmtGsInitialising:
                case kEplNmtGsResetApplication:
                case kEplNmtMsNotActive:
                case kEplNmtCsNotActive:
                case kEplNmtCsPreOperational1:
                {
                    break;
                }

                case kEplNmtCsOperational:
                case kEplNmtMsOperational:
                {
                    break;
                }

                default:
                {
                    break;
                }
            }

            break;
        }

        case kEplApiEventCriticalError:
        case kEplApiEventWarning:
        {   // error or warning occurred within the stack or the application
            // on error the API layer stops the NMT state machine

            PRINTF("%s(Err/Warn): Source=%02X EplError=0x%03X",
                    __func__,
                    pEventArg_p->m_InternalError.m_EventSource,
                    pEventArg_p->m_InternalError.m_EplError);
            // check additional argument
            switch (pEventArg_p->m_InternalError.m_EventSource)
            {
                case kEplEventSourceEventk:
                case kEplEventSourceEventu:
                {   // error occurred within event processing
                    // either in kernel or in user part
                    PRINTF(" OrgSource=%02X\n", pEventArg_p->m_InternalError.m_Arg.m_EventSource);
                    break;
                }

                case kEplEventSourceDllk:
                {   // error occurred within the data link layer (e.g. interrupt processing)
                    // the DWORD argument contains the DLL state and the NMT event
                    PRINTF(" val=%lX\n", (ULONG) pEventArg_p->m_InternalError.m_Arg.m_dwArg);
                    break;
                }

                case kEplEventSourceObdk:
                case kEplEventSourceObdu:
                {   // error occurred within OBD module
                    // either in kernel or in user part
                    PRINTF(" Object=0x%04X/%u\n", pEventArg_p->m_InternalError.m_Arg.m_ObdError.m_uiIndex, pEventArg_p->m_InternalError.m_Arg.m_ObdError.m_uiSubIndex);
                    break;
                }

                default:
                {
                    PRINTF("\n");
                    break;
                }
            }
            break;
        }

        case kEplApiEventHistoryEntry:
        {   // new history entry

            if ((pEventArg_p->m_ErrHistoryEntry.m_wErrorCode == EPL_E_DLL_CYCLE_EXCEED_TH)
                && (IS_FD_VALID(hAppFdTracingEnabled_g)))
            {
            mm_segment_t    old_fs;
            loff_t          pos;
            ssize_t         iRet;

                old_fs = get_fs();
                set_fs(KERNEL_DS);

                pos = hAppFdTracingEnabled_g->f_pos;
                iRet = vfs_write(hAppFdTracingEnabled_g, "0", 1, &pos);
                hAppFdTracingEnabled_g->f_pos = pos;
            }

            PRINTF("%s(HistoryEntry): Type=0x%04X Code=0x%04X (0x%02X %02X %02X %02X %02X %02X %02X %02X)\n",
                    __func__,
                    pEventArg_p->m_ErrHistoryEntry.m_wEntryType,
                    pEventArg_p->m_ErrHistoryEntry.m_wErrorCode,
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[0],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[1],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[2],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[3],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[4],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[5],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[6],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[7]);
            break;
        }

        case kEplApiEventNode:
        {
            // check additional argument
            switch (pEventArg_p->m_Node.m_NodeEvent)
            {
                case kEplNmtNodeEventCheckConf:
                {
                    PRINTF("%s(Node=0x%X, CheckConf)\n", __func__, pEventArg_p->m_Node.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeEventUpdateConf:
                {
                    PRINTF("%s(Node=0x%X, UpdateConf)\n", __func__, pEventArg_p->m_Node.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeEventNmtState:
                {
                    PRINTF("%s(Node=0x%X, NmtState=0x%X)\n", __func__, pEventArg_p->m_Node.m_uiNodeId, pEventArg_p->m_Node.m_NmtState);
                    break;
                }

                case kEplNmtNodeEventError:
                {
                    PRINTF("%s (Node=0x%X): Error = %s (0x%.4X)\n", __func__,
                            pEventArg_p->m_Node.m_uiNodeId,
                            EplGetEmergErrCodeStr(pEventArg_p->m_Node.m_wErrorCode),
                            pEventArg_p->m_Node.m_wErrorCode);
                    break;
                }

                case kEplNmtNodeEventFound:
                {
                    PRINTF("%s(Node=0x%X, Found)\n", __func__, pEventArg_p->m_Node.m_uiNodeId);
                    break;
                }

                default:
                {
                    break;
                }
            }
            break;
        }

#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFM)) != 0)
        case kEplApiEventCfmProgress:
        {
            PRINTF("%s(Node=0x%X, CFM-Progress: Object 0x%X/%u, ", __func__, pEventArg_p->m_CfmProgress.m_uiNodeId, pEventArg_p->m_CfmProgress.m_uiObjectIndex, pEventArg_p->m_CfmProgress.m_uiObjectSubIndex);
            PRINTF("%lu/%lu Bytes", (ULONG) pEventArg_p->m_CfmProgress.m_dwBytesDownloaded, (ULONG) pEventArg_p->m_CfmProgress.m_dwTotalNumberOfBytes);
            if ((pEventArg_p->m_CfmProgress.m_dwSdoAbortCode != 0)
                || (pEventArg_p->m_CfmProgress.m_EplError != kEplSuccessful))
            {
                PRINTF(" -> SDO Abort=0x%lX, Error=0x%X)\n", (unsigned long) pEventArg_p->m_CfmProgress.m_dwSdoAbortCode,
                                                              pEventArg_p->m_CfmProgress.m_EplError);
            }
            else
            {
                PRINTF(")\n");
            }
            break;
        }

        case kEplApiEventCfmResult:
        {
            switch (pEventArg_p->m_CfmResult.m_NodeCommand)
            {
                case kEplNmtNodeCommandConfOk:
                {
                    PRINTF("%s(Node=0x%X, ConfOk)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfErr:
                {
                    PRINTF("%s(Node=0x%X, ConfErr)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfReset:
                {
                    PRINTF("%s(Node=0x%X, ConfReset)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfRestored:
                {
                    PRINTF("%s(Node=0x%X, ConfRestored)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                default:
                {
                    PRINTF("%s(Node=0x%X, CfmResult=0x%X)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId, pEventArg_p->m_CfmResult.m_NodeCommand);
                    break;
                }
            }
            break;
        }
#endif

        default:
            break;
    }

    return EplRet;
}
tEplKernel PUBLIC AppCbEvent(
    tEplApiEventType        EventType_p,   // IN: event type (enum)
    tEplApiEventArg*        pEventArg_p,   // IN: event argument (union)
    void GENERIC*           pUserArg_p)
{
tEplKernel          EplRet = kEplSuccessful;

    UNUSED_PARAMETER(pUserArg_p);

    // check if NMT_GS_OFF is reached
    switch (EventType_p)
    {
        case kEplApiEventNmtStateChange:
        {
            switch (pEventArg_p->m_NmtStateChange.m_NewNmtState)
            {
                case kEplNmtGsOff:
                {   // NMT state machine was shut down,
                    // because of user signal (CTRL-C) or critical EPL stack error
                    // -> also shut down EplApiProcess() and main()
                    EplRet = kEplShutdown;

                    PRINTF("%s:kEplNmtGsOff originating event = 0x%X (%s)\n",
                            __func__, pEventArg_p->m_NmtStateChange.m_NmtEvent,
                            EplGetNmtEventStr(pEventArg_p->m_NmtStateChange.m_NmtEvent));
                    // wake up EplLinExit()
                    /*atomic_set(&AtomicShutdown_g, TRUE);
                    wake_up_interruptible(&WaitQueueShutdown_g);*/
                    break;
                }

                case kEplNmtGsResetCommunication:
                {
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFM)) == 0)
                DWORD   dwNodeAssignment;

                    // configure OD for MN in state ResetComm after reseting the OD
                    // TODO: setup your own network configuration here
                    dwNodeAssignment = (EPL_NODEASSIGN_NODE_IS_CN |
                                        EPL_NODEASSIGN_NODE_EXISTS); // 0x00000003L
                    EplRet = EplApiWriteLocalObject(0x1F81, 0x01, &dwNodeAssignment,
                                                    sizeof (dwNodeAssignment));
                    EplRet = EplApiWriteLocalObject(0x1F81, 0x20, &dwNodeAssignment,
                                                    sizeof (dwNodeAssignment));
                    EplRet = EplApiWriteLocalObject(0x1F81, 0x6E, &dwNodeAssignment,
                                                    sizeof (dwNodeAssignment));
                    EplRet = EplApiWriteLocalObject(0x1F81, 0xFE, &dwNodeAssignment,
                                                    sizeof (dwNodeAssignment));

                    // dwNodeAssignment |= EPL_NODEASSIGN_MANDATORY_CN;    // 0x0000000BL
                    // EplRet = EplApiWriteLocalObject(0x1F81, 0x6E, &dwNodeAssignment, sizeof (dwNodeAssignment));
                    dwNodeAssignment = (EPL_NODEASSIGN_MN_PRES |
                                    EPL_NODEASSIGN_NODE_EXISTS);       // 0x00010001L
                    EplRet = EplApiWriteLocalObject(0x1F81, 0xF0, &dwNodeAssignment,
                                                    sizeof (dwNodeAssignment));
#endif
                }

                case kEplNmtGsResetConfiguration:
                {
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFM)) != 0)
                    if (uiCycleLen_g != 0)
                    {
                        EplRet = EplApiWriteLocalObject(0x1006, 0x00,
                                                        &uiCycleLen_g,
                                                        sizeof (uiCycleLen_g));
                    }
#else
                    unsigned int uiSize;

                    // fetch object 0x1006 NMT_CycleLen_U32 from local OD
                    // (in little endian byte order) for configuration of
                    // remote CN
                    uiSize = 4;
                    EplRet = EplApiReadObject(NULL, 0, 0x1006, 0x00,
                                              &dw_le_CycleLen_g, &uiSize,
                                              kEplSdoTypeAsnd, NULL);
                    if (EplRet != kEplSuccessful)
                    {   // local OD access failed
                        break;
                    }
#endif
                }

                case kEplNmtMsPreOperational1:
                {
                    PRINTF("%s(0x%X) originating event = 0x%X (%s)\n",
                            __func__,
                           pEventArg_p->m_NmtStateChange.m_NewNmtState,
                           pEventArg_p->m_NmtStateChange.m_NmtEvent,
                           EplGetNmtEventStr(pEventArg_p->m_NmtStateChange.m_NmtEvent));

                    // continue
                }

                case kEplNmtGsInitialising:
                case kEplNmtGsResetApplication:
                case kEplNmtMsNotActive:
                case kEplNmtCsNotActive:
                case kEplNmtCsPreOperational1:
                {
                    break;
                }

                case kEplNmtCsOperational:
                case kEplNmtMsOperational:
                {
                    break;
                }

                default:
                {
                    break;
                }
            }

            break;
        }

        case kEplApiEventCriticalError:
        case kEplApiEventWarning:
        {   // error or warning occurred within the stack or the application
            // on error the API layer stops the NMT state machine

            PRINTF("%s(Err/Warn): Source=%02X EplError=0x%03X",
                    __func__,
                    pEventArg_p->m_InternalError.m_EventSource,
                    pEventArg_p->m_InternalError.m_EplError);
            // check additional argument
            switch (pEventArg_p->m_InternalError.m_EventSource)
            {
                case kEplEventSourceEventk:
                case kEplEventSourceEventu:
                {   // error occurred within event processing
                    // either in kernel or in user part
                    PRINTF(" OrgSource=%02X\n",
                            pEventArg_p->m_InternalError.m_Arg.m_EventSource);
                    break;
                }

                case kEplEventSourceDllk:
                {   // error occurred within the data link layer (e.g. interrupt processing)
                    // the DWORD argument contains the DLL state and the NMT event
                    PRINTF(" val=%lX\n",
                            (ULONG) pEventArg_p->m_InternalError.m_Arg.m_dwArg);
                    break;
                }

                case kEplEventSourceObdk:
                case kEplEventSourceObdu:
                {   // error occurred within OBD module
                    // either in kernel or in user part
                    PRINTF(" Object=0x%04X/%u\n",
                            pEventArg_p->m_InternalError.m_Arg.m_ObdError.m_uiIndex,
                            pEventArg_p->m_InternalError.m_Arg.m_ObdError.m_uiSubIndex);
                    break;
                }

                default:
                {
                    PRINTF("\n");
                    break;
                }
            }
            break;
        }

        case kEplApiEventHistoryEntry:
        {   // new history entry
            PRINTF("%s(HistoryEntry): Type=0x%04X Code=0x%04X (0x%02X %02X %02X %02X %02X %02X %02X %02X)\n",
                    __func__,
                    pEventArg_p->m_ErrHistoryEntry.m_wEntryType,
                    pEventArg_p->m_ErrHistoryEntry.m_wErrorCode,
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[0],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[1],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[2],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[3],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[4],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[5],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[6],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[7]);
            break;
        }

        case kEplApiEventNode:
        {
            // check additional argument
            switch (pEventArg_p->m_Node.m_NodeEvent)
            {
                case kEplNmtNodeEventCheckConf:
                {
                    PRINTF("%s(Node=0x%X, CheckConf)\n", __func__,
                            pEventArg_p->m_Node.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeEventUpdateConf:
                {
                    PRINTF("%s(Node=0x%X, UpdateConf)\n", __func__,
                            pEventArg_p->m_Node.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeEventNmtState:
                {
                    PRINTF("%s(Node=0x%X, NmtState=0x%X)\n", __func__,
                            pEventArg_p->m_Node.m_uiNodeId,
                            pEventArg_p->m_Node.m_NmtState);
                    break;
                }

                case kEplNmtNodeEventError:
                {
                    PRINTF("%s (Node=0x%X): Error = %s (0x%.4X)\n", __func__,
                            pEventArg_p->m_Node.m_uiNodeId,
                            EplGetEmergErrCodeStr(pEventArg_p->m_Node.m_wErrorCode),
                            pEventArg_p->m_Node.m_wErrorCode);
                    break;
                }

                case kEplNmtNodeEventFound:
                {
                    PRINTF("%s(Node=0x%X, Found)\n", __func__,
                            pEventArg_p->m_Node.m_uiNodeId);
                    break;
                }

                default:
                {
                    break;
                }
            }
            break;
        }

#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFM)) != 0)
        case kEplApiEventCfmProgress:
        {
            PRINTF("%s(Node=0x%X, CFM-Progress: Object 0x%X/%u, ",
                    __func__, pEventArg_p->m_CfmProgress.m_uiNodeId,
                    pEventArg_p->m_CfmProgress.m_uiObjectIndex,
                    pEventArg_p->m_CfmProgress.m_uiObjectSubIndex);
            PRINTF("%lu/%lu Bytes",
                    (ULONG) pEventArg_p->m_CfmProgress.m_dwBytesDownloaded,
                    (ULONG) pEventArg_p->m_CfmProgress.m_dwTotalNumberOfBytes);
            if ((pEventArg_p->m_CfmProgress.m_dwSdoAbortCode != 0)
                || (pEventArg_p->m_CfmProgress.m_EplError != kEplSuccessful))
            {
                PRINTF(" -> SDO Abort=0x%lX, Error=0x%X)\n",
                        (unsigned long) pEventArg_p->m_CfmProgress.m_dwSdoAbortCode,
                        pEventArg_p->m_CfmProgress.m_EplError);
            }
            else
            {
                PRINTF(")\n");
            }
            break;
        }

        case kEplApiEventCfmResult:
        {
            switch (pEventArg_p->m_CfmResult.m_NodeCommand)
            {
                case kEplNmtNodeCommandConfOk:
                {
                    PRINTF("%s(Node=0x%X, ConfOk)\n", __func__,
                            pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfErr:
                {
                    PRINTF("%s(Node=0x%X, ConfErr)\n", __func__,
                            pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfReset:
                {
                    PRINTF("%s(Node=0x%X, ConfReset)\n", __func__,
                            pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfRestored:
                {
                    PRINTF("%s(Node=0x%X, ConfRestored)\n", __func__,
                            pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                default:
                {
                    PRINTF("%s(Node=0x%X, CfmResult=0x%X)\n", __func__,
                            pEventArg_p->m_CfmResult.m_uiNodeId,
                            pEventArg_p->m_CfmResult.m_NodeCommand);
                    break;
                }
            }
            break;
        }
#endif

        default:
            break;
    }

    return EplRet;
}
tEplKernel PUBLIC AppCbEvent(
    tEplApiEventType        EventType_p,   // IN: event type (enum)
    tEplApiEventArg*        pEventArg_p,   // IN: event argument (union)
    void GENERIC*           pUserArg_p)
{
	tEplKernel          EplRet = kEplSuccessful;

    // check if NMT_GS_OFF is reached
    switch (EventType_p)
    {
        case kEplApiEventNmtStateChange:
        {
            switch (pEventArg_p->m_NmtStateChange.m_NewNmtState)
            {
                case kEplNmtGsOff:
                {   // NMT state machine was shut down,
                    // because of critical EPL stack error
                    // -> also shut down EplApiProcess() and main()
                    EplRet = kEplShutdown;
                    fShutdown_l = TRUE;

                    PRINTF2("%s(kEplNmtGsOff) originating event = 0x%X\n", __func__, pEventArg_p->m_NmtStateChange.m_NmtEvent);
                    break;
                }

                case kEplNmtGsInitialising:
                case kEplNmtGsResetApplication:
                case kEplNmtGsResetConfiguration:
                case kEplNmtCsPreOperational1:
                case kEplNmtCsBasicEthernet:
                case kEplNmtMsBasicEthernet:
                {
                    PRINTF3("%s(0x%X) originating event = 0x%X\n",
                            __func__,
                            pEventArg_p->m_NmtStateChange.m_NewNmtState,
                            pEventArg_p->m_NmtStateChange.m_NmtEvent);
                    break;
                }

                case kEplNmtGsResetCommunication:
                {
                BYTE    bNodeId = 0xF0;
                DWORD   dwNodeAssignment = EPL_NODEASSIGN_NODE_EXISTS;
                WORD    wPresPayloadLimit = 256;

                    PRINTF3("%s(0x%X) originating event = 0x%X\n",
                            __func__,
                            pEventArg_p->m_NmtStateChange.m_NewNmtState,
                            pEventArg_p->m_NmtStateChange.m_NmtEvent);

                    EplRet = EplApiWriteLocalObject(0x1F81, bNodeId, &dwNodeAssignment, sizeof (dwNodeAssignment));
                    if (EplRet != kEplSuccessful)
                    {
                        goto Exit;
                    }

                    bNodeId = 0x04;
                    EplRet = EplApiWriteLocalObject(0x1F81, bNodeId, &dwNodeAssignment, sizeof (dwNodeAssignment));
                    if (EplRet != kEplSuccessful)
                    {
                        goto Exit;
                    }

                    EplRet = EplApiWriteLocalObject(0x1F8D, bNodeId, &wPresPayloadLimit, sizeof (wPresPayloadLimit));
                    if (EplRet != kEplSuccessful)
                    {
                        goto Exit;
                    }

                    break;
                }

                case kEplNmtMsNotActive:
                    break;
                case kEplNmtCsNotActive:
                    break;
                    break;

                case kEplNmtCsOperational:
                    break;
                case kEplNmtMsOperational:
                    break;

                default:
                {
                    break;
                }
            }

            break;
        }

        case kEplApiEventCriticalError:
        case kEplApiEventWarning:
        {   // error or warning occurred within the stack or the application
            // on error the API layer stops the NMT state machine
            PRINTF3("%s(Err/Warn): Source=%02X EplError=0x%03X",
                    __func__,
                    pEventArg_p->m_InternalError.m_EventSource,
                    pEventArg_p->m_InternalError.m_EplError);
            // check additional argument
            switch (pEventArg_p->m_InternalError.m_EventSource)
            {
                case kEplEventSourceEventk:
                case kEplEventSourceEventu:
                {   // error occurred within event processing
                    // either in kernel or in user part
                    PRINTF1(" OrgSource=%02X\n", pEventArg_p->m_InternalError.m_Arg.m_EventSource);
                    break;
                }

                case kEplEventSourceDllk:
                {   // error occurred within the data link layer (e.g. interrupt processing)
                    // the DWORD argument contains the DLL state and the NMT event
                    PRINTF1(" val=%lX\n", pEventArg_p->m_InternalError.m_Arg.m_dwArg);
                    break;
                }

                default:
                {
                    PRINTF0("\n");
                    break;
                }
            }
            break;
        }

        case kEplApiEventHistoryEntry:
        {   // new history entry

            PRINTF("%s(HistoryEntry): Type=0x%04X Code=0x%04X (0x%02X %02X %02X %02X %02X %02X %02X %02X)\n",
                    __func__,
                    pEventArg_p->m_ErrHistoryEntry.m_wEntryType,
                    pEventArg_p->m_ErrHistoryEntry.m_wErrorCode,
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[0],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[1],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[2],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[3],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[4],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[5],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[6],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[7]);
            break;
        }

        case kEplApiEventLed:
        {   // status or error LED shall be changed

            switch (pEventArg_p->m_Led.m_LedType)
            {
#ifdef LED_STATUS_PIO_BASE
                case kEplLedTypeStatus:
                {
                    if (pEventArg_p->m_Led.m_fOn != FALSE)
                    {
                        IOWR_ALTERA_AVALON_PIO_DATA(LED_STATUS_PIO_BASE, 1);
                    }
                    else
                    {
                        IOWR_ALTERA_AVALON_PIO_DATA(LED_STATUS_PIO_BASE, 0);
                    }
                    break;
                }
#endif
#ifdef LED_ERROR_PIO_BASE
                case kEplLedTypeError:
                {
                    if (pEventArg_p->m_Led.m_fOn != FALSE)
                    {
                        IOWR_ALTERA_AVALON_PIO_DATA(LED_ERROR_PIO_BASE, 1);
                    }
                    else
                    {
                        IOWR_ALTERA_AVALON_PIO_DATA(LED_ERROR_PIO_BASE, 0);
                    }
                    break;
                }
#endif
                default:
                    break;
            }
            break;
        }

        default:
            break;
    }

Exit:
    return EplRet;
}
Beispiel #6
0
//---------------------------------------------------------------------------
//
// Function:    AppCbEvent
//
// Description: event callback function called by EPL API layer within
//              user part (low priority).
//
// Parameters:  EventType_p     = event type
//              pEventArg_p     = pointer to union, which describes
//                                the event in detail
//              pUserArg_p      = user specific argument
//
// Returns:     tEplKernel      = error code,
//                                kEplSuccessful = no error
//                                kEplReject = reject further processing
//                                otherwise = post error event to API layer
//
// State:
//
//---------------------------------------------------------------------------
tEplKernel PUBLIC AppCbEvent (
			      tEplApiEventType EventType_p,   // IN: event type (enum)
			      tEplApiEventArg* pEventArg_p,   // IN: event argument (union)
			      io_sAgent* pUserArg_p    
			      )
{
    
  UINT uiVarLen;
  tEplKernel EplRet = kEplSuccessful;
  pwr_sClass_Epl_MN *op = (pwr_sClass_Epl_MN *)pUserArg_p->op;
  io_sRack *rp;
	
  // check if NMT_GS_OFF is reached
  switch (EventType_p) {
  case kEplApiEventNmtStateChange: {
    op->NmtState = pEventArg_p->m_NmtStateChange.m_NewNmtState;
    op->Status = op->NmtState == pwr_eEplNmtState_EplNmtMsOperational ? IOM__EPL_OPER : IOM__EPL_NOOPER;
			
    switch (pEventArg_p->m_NmtStateChange.m_NewNmtState) {
    case kEplNmtGsOff: {
      // NMT state machine was shut down,
      // because of user signal (CTRL-C) or critical EPL stack error
      // -> also shut down EplApiProcess() and main()
      EplRet = kEplShutdown;
					
      errh_Fatal("Event:kEplNmtGsOff originating event = 0x%X (%s)", pEventArg_p->m_NmtStateChange.m_NmtEvent,
		 EplGetNmtEventStr(pEventArg_p->m_NmtStateChange.m_NmtEvent));
                    
      break;
    }

    case kEplNmtGsResetCommunication: {
      break;
    }

    case kEplNmtGsResetConfiguration: {
      if (uiCycleLen_g != 0) {
	EplRet = EplApiWriteLocalObject(0x1006, 0x00, &uiCycleLen_g, sizeof (uiCycleLen_g));
	uiCurCycleLen_g = uiCycleLen_g;
      }
      else {
	uiVarLen = sizeof(uiCurCycleLen_g);
	EplApiReadLocalObject(0x1006, 0x00, &uiCurCycleLen_g, &uiVarLen);
      }
      break;
    }
    case kEplNmtCsPreOperational1:
    case kEplNmtMsPreOperational1: {
      errh_Info("AppCbEvent(0x%X) originating event = 0x%X (%s)", pEventArg_p->m_NmtStateChange.m_NewNmtState, pEventArg_p->m_NmtStateChange.m_NmtEvent, EplGetNmtEventStr(pEventArg_p->m_NmtStateChange.m_NmtEvent));
      break;
    }
				
    case kEplNmtCsPreOperational2:
    case kEplNmtMsPreOperational2: {
      break;
    }
    case kEplNmtCsReadyToOperate:
    case kEplNmtMsReadyToOperate: {
      break;
    }
    case kEplNmtGsInitialising: {
      break;
    }
    case kEplNmtGsResetApplication: {
      break;
    }
    case kEplNmtMsNotActive:
    case kEplNmtCsNotActive: {
      break;
    }
    case kEplNmtCsOperational:
    case kEplNmtMsOperational: {
      break;
    }
    case kEplNmtCsBasicEthernet:
    case kEplNmtMsBasicEthernet: {
      break;
    }

    default: {
    }
    }
            

    break;
  }

  case kEplApiEventCriticalError:
  case kEplApiEventWarning: {   
    // error or warning occurred within the stack or the application
    // on error the API layer stops the NMT state machine
			
    errh_Error( "%s(Err/Warn): Source = %s (%02X) EplError = %s (0x%03X)",
		__func__,
		EplGetEventSourceStr(pEventArg_p->m_InternalError.m_EventSource),
		pEventArg_p->m_InternalError.m_EventSource,
		EplGetEplKernelStr(pEventArg_p->m_InternalError.m_EplError),
		pEventArg_p->m_InternalError.m_EplError);
            
    // check additional argument
    switch (pEventArg_p->m_InternalError.m_EventSource) {
    case kEplEventSourceEventk:
    case kEplEventSourceEventu: {   
      // error occurred within event processing
      // either in kernel or in user part
                    
      errh_Error(" OrgSource = %s %02X",  EplGetEventSourceStr(pEventArg_p->m_InternalError.m_Arg.m_EventSource),
		 pEventArg_p->m_InternalError.m_Arg.m_EventSource);
                    
      break;
    }

    case kEplEventSourceDllk: {   
      // error occurred within the data link layer (e.g. interrupt processing)
      // the DWORD argument contains the DLL state and the NMT event
                    
      errh_Error(" val = %X", pEventArg_p->m_InternalError.m_Arg.m_dwArg);
                    
      break;
    }

    default: {
      break;
    }
    }
    break;
  }

  case kEplApiEventHistoryEntry: {   
    // new history entry
			
    errh_Info("%s(HistoryEntry): Type=0x%04X Code=0x%04X (0x%02X %02X %02X %02X %02X %02X %02X %02X)",
	      __func__,
	      pEventArg_p->m_ErrHistoryEntry.m_wEntryType,
	      pEventArg_p->m_ErrHistoryEntry.m_wErrorCode,
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[0],
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[1],
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[2],
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[3],
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[4],
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[5],
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[6],
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[7]);
            
    break;
  }
        
  case kEplApiEventNode: {
    switch (pEventArg_p->m_Node.m_NodeEvent) {
    case kEplNmtNodeEventCheckConf: {
      errh_Info("%s(Node=0x%X, CheckConf)", __func__, pEventArg_p->m_Node.m_uiNodeId);
      break;
    }

    case kEplNmtNodeEventUpdateConf: {
      errh_Info("%s(Node=0x%X, UpdateConf)", __func__, pEventArg_p->m_Node.m_uiNodeId);
      break;
    }

    case kEplNmtNodeEventFound: {
                    
      break;
    }

    case kEplNmtNodeEventNmtState: {
      for ( rp = pUserArg_p->racklist; rp; rp = rp->next)
	if(((pwr_sClass_Epl_CN *)rp->op)->NodeId == pEventArg_p->m_Node.m_uiNodeId) {
	  ((pwr_sClass_Epl_CN *)rp->op)->NmtState = pEventArg_p->m_Node.m_NmtState;
		  
	}
					
      switch (pEventArg_p->m_Node.m_NmtState) {
      case kEplNmtGsOff:
      case kEplNmtGsInitialising:
      case kEplNmtGsResetApplication:
      case kEplNmtGsResetCommunication:
      case kEplNmtGsResetConfiguration:
      case kEplNmtCsNotActive: {                           
	break;
      }
      case kEplNmtCsPreOperational1:
      case kEplNmtCsPreOperational2:
      case kEplNmtCsReadyToOperate: {                            
	break;
      }
      case kEplNmtCsOperational: {                            
	break;
      }
      case kEplNmtCsBasicEthernet:
      case kEplNmtCsStopped:
      default: {                            
	break;
      }
      }
      break;
    }

    case kEplNmtNodeEventError: {
                    
      errh_Error("AppCbEvent (Node=0x%X): Error = %s (0x%.4X)",
		 pEventArg_p->m_Node.m_uiNodeId,
		 EplGetEmergErrCodeStr(pEventArg_p->m_Node.m_wErrorCode),
		 pEventArg_p->m_Node.m_wErrorCode);
      break;
    }

    default: {
      break;
    }
    }
    break;
  }

  case kEplApiEventCfmProgress: {
    errh_Info("%s(Node=0x%X, CFM-Progress: Object 0x%X/%u,  %lu/%lu Bytes", __func__, pEventArg_p->m_CfmProgress.m_uiNodeId, pEventArg_p->m_CfmProgress.m_uiObjectIndex, pEventArg_p->m_CfmProgress.m_uiObjectSubIndex, (ULONG) pEventArg_p->m_CfmProgress.m_dwBytesDownloaded, (ULONG) pEventArg_p->m_CfmProgress.m_dwTotalNumberOfBytes);

    if ((pEventArg_p->m_CfmProgress.m_dwSdoAbortCode != 0)
	|| (pEventArg_p->m_CfmProgress.m_EplError != kEplSuccessful)) {
      errh_Error(" -> SDO Abort=0x%lX, Error=0x%X)", (unsigned long) pEventArg_p->m_CfmProgress.m_dwSdoAbortCode,
		 pEventArg_p->m_CfmProgress.m_EplError);
    }
    else {
    }
    break;
  }

  case kEplApiEventCfmResult: {
    switch (pEventArg_p->m_CfmResult.m_NodeCommand) {
    case kEplNmtNodeCommandConfOk: {
      errh_Info("%s(Node=0x%X, ConfOk)", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
      break;
    }

    case kEplNmtNodeCommandConfErr: {
      errh_Info("%s(Node=0x%X, ConfErr)", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
      break;
    }

    case kEplNmtNodeCommandConfReset: {
      errh_Info("%s(Node=0x%X, ConfReset)", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
      break;
    }

    case kEplNmtNodeCommandConfRestored: {
      errh_Info("%s(Node=0x%X, ConfRestored)", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
      break;
    }

    default: {
      errh_Info("%s(Node=0x%X, CfmResult=0x%X)", __func__, pEventArg_p->m_CfmResult.m_uiNodeId, pEventArg_p->m_CfmResult.m_NodeCommand);
      break;
    }
    }
    break;
  }

  default:
    break;
  }

  return EplRet;
}