Ejemplo n.º 1
0
static int EplLinProcWrite(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
char            abBuffer[count + 1];
int             iErr;
int             iVal = 0;
tEplNmtEvent    NmtEvent;

    if (count > 0)
    {
        iErr = copy_from_user(abBuffer, buffer, count);
        if (iErr != 0)
        {
            return count;
        }
        abBuffer[count] = '\0';

        iErr = sscanf(abBuffer, "%i", &iVal);
    }
    if ((iVal <= 0) || (iVal > 0x2F))
    {
        NmtEvent = kEplNmtEventSwReset;
    }
    else
    {
        NmtEvent = (tEplNmtEvent) iVal;
    }
    // execute specified NMT command on write access of /proc/epl
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
    EplNmtuNmtEvent(NmtEvent);
#endif

    return count;
}
Ejemplo n.º 2
0
//---------------------------------------------------------------------------
//
// Function:    EplNmtuProcessEvent
//
// Description: processes events from event queue
//
//
//
// Parameters:  pEplEvent_p =   pointer to event
//
//
// Returns:     tEplKernel  = errorcode
//
//
// State:
//
//---------------------------------------------------------------------------
EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p)
{
	tEplKernel Ret;

	Ret = kEplSuccessful;

	// process event
	switch (pEplEvent_p->m_EventType) {
		// state change of NMT-Module
	case kEplEventTypeNmtStateChange:
		{
			tEplEventNmtStateChange *pNmtStateChange;

			// delete timer
			Ret =
			    EplTimeruDeleteTimer(&EplNmtuInstance_g.m_TimerHdl);

			pNmtStateChange =
			    (tEplEventNmtStateChange *) pEplEvent_p->m_pArg;

			// call cb-functions to inform higher layer
			if (EplNmtuInstance_g.m_pfnNmtChangeCb != NULL) {
				Ret =
				    EplNmtuInstance_g.
				    m_pfnNmtChangeCb(*pNmtStateChange);
			}

			if (Ret == kEplSuccessful) {	// everything is OK, so switch to next state if necessary
				switch (pNmtStateChange->m_NewNmtState) {
					// EPL stack is not running
				case kEplNmtGsOff:
					break;

					// first init of the hardware
				case kEplNmtGsInitialising:
					{
						Ret =
						    EplNmtuNmtEvent
						    (kEplNmtEventEnterResetApp);
						break;
					}

					// init of the manufacturer-specific profile area and the
					// standardised device profile area
				case kEplNmtGsResetApplication:
					{
						Ret =
						    EplNmtuNmtEvent
						    (kEplNmtEventEnterResetCom);
						break;
					}

					// init of the communication profile area
				case kEplNmtGsResetCommunication:
					{
						Ret =
						    EplNmtuNmtEvent
						    (kEplNmtEventEnterResetConfig);
						break;
					}

					// build the configuration with infos from OD
				case kEplNmtGsResetConfiguration:
					{
						unsigned int uiNodeId;

						// get node ID from OD
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
						uiNodeId =
						    EplObduGetNodeId
						    (EPL_MCO_PTR_INSTANCE_PTR);
#else
						uiNodeId = 0;
#endif
						//check node ID if not should be master or slave
						if (uiNodeId == EPL_C_ADR_MN_DEF_NODE_ID) {	// node shall be MN
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
							Ret =
							    EplNmtuNmtEvent
							    (kEplNmtEventEnterMsNotActive);
#else
							TRACE0
							    ("EplNmtuProcess(): no MN functionality implemented\n");
#endif
						} else {	// node shall be CN
							Ret =
							    EplNmtuNmtEvent
							    (kEplNmtEventEnterCsNotActive);
						}
						break;
					}

					//-----------------------------------------------------------
					// CN part of the state machine

					// node listens for EPL-Frames and check timeout
				case kEplNmtCsNotActive:
					{
						DWORD dwBuffer;
						tEplObdSize ObdSize;
						tEplTimerArg TimerArg;

						// create timer to switch automatically to BasicEthernet if no MN available in network

						// read NMT_CNBasicEthernetTimerout_U32 from OD
						ObdSize = sizeof(dwBuffer);
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
						Ret =
						    EplObduReadEntry
						    (EPL_MCO_PTR_INSTANCE_PTR_
						     0x1F99, 0x00, &dwBuffer,
						     &ObdSize);
#else
						Ret = kEplObdIndexNotExist;
#endif
						if (Ret != kEplSuccessful) {
							break;
						}
						if (dwBuffer != 0) {	// BasicEthernet is enabled
							// convert us into ms
							dwBuffer =
							    dwBuffer / 1000;
							if (dwBuffer == 0) {	// timer was below one ms
								// set one ms
								dwBuffer = 1;
							}
							TimerArg.m_EventSink =
							    kEplEventSinkNmtk;
							TimerArg.m_ulArg =
							    (unsigned long)
							    kEplNmtEventTimerBasicEthernet;
							Ret =
							    EplTimeruModifyTimerMs
							    (&EplNmtuInstance_g.
							     m_TimerHdl,
							     (unsigned long)
							     dwBuffer,
							     TimerArg);
							// potential error is forwarded to event queue which generates error event
						}
						break;
					}

					// node processes only async frames
				case kEplNmtCsPreOperational1:
					{
						break;
					}

					// node processes isochronous and asynchronous frames
				case kEplNmtCsPreOperational2:
					{
						Ret =
						    EplNmtuNmtEvent
						    (kEplNmtEventEnterReadyToOperate);
						break;
					}

					// node should be configured und application is ready
				case kEplNmtCsReadyToOperate:
					{
						break;
					}

					// normal work state
				case kEplNmtCsOperational:
					{
						break;
					}

					// node stopped by MN
					// -> only process asynchronous frames
				case kEplNmtCsStopped:
					{
						break;
					}

					// no EPL cycle
					// -> normal ethernet communication
				case kEplNmtCsBasicEthernet:
					{
						break;
					}

					//-----------------------------------------------------------
					// MN part of the state machine

#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
					// node listens for EPL-Frames and check timeout
				case kEplNmtMsNotActive:
					{
						DWORD dwBuffer;
						tEplObdSize ObdSize;
						tEplTimerArg TimerArg;

						// create timer to switch automatically to BasicEthernet/PreOp1 if no other MN active in network

						// check NMT_StartUp_U32.Bit13
						// read NMT_StartUp_U32 from OD
						ObdSize = sizeof(dwBuffer);
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
						Ret =
						    EplObduReadEntry
						    (EPL_MCO_PTR_INSTANCE_PTR_
						     0x1F80, 0x00, &dwBuffer,
						     &ObdSize);
#else
						Ret = kEplObdIndexNotExist;
#endif
						if (Ret != kEplSuccessful) {
							break;
						}

						if ((dwBuffer & EPL_NMTST_BASICETHERNET) == 0) {	// NMT_StartUp_U32.Bit13 == 0
							// new state PreOperational1
							TimerArg.m_ulArg =
							    (unsigned long)
							    kEplNmtEventTimerMsPreOp1;
						} else {	// NMT_StartUp_U32.Bit13 == 1
							// new state BasicEthernet
							TimerArg.m_ulArg =
							    (unsigned long)
							    kEplNmtEventTimerBasicEthernet;
						}

						// read NMT_BootTime_REC.MNWaitNotAct_U32 from OD
						ObdSize = sizeof(dwBuffer);
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
						Ret =
						    EplObduReadEntry
						    (EPL_MCO_PTR_INSTANCE_PTR_
						     0x1F89, 0x01, &dwBuffer,
						     &ObdSize);
#else
						Ret = kEplObdIndexNotExist;
#endif
						if (Ret != kEplSuccessful) {
							break;
						}
						// convert us into ms
						dwBuffer = dwBuffer / 1000;
						if (dwBuffer == 0) {	// timer was below one ms
							// set one ms
							dwBuffer = 1;
						}
						TimerArg.m_EventSink =
						    kEplEventSinkNmtk;
						Ret =
						    EplTimeruModifyTimerMs
						    (&EplNmtuInstance_g.
						     m_TimerHdl,
						     (unsigned long)dwBuffer,
						     TimerArg);
						// potential error is forwarded to event queue which generates error event
						break;
					}

					// node processes only async frames
				case kEplNmtMsPreOperational1:
					{
						DWORD dwBuffer = 0;
						tEplObdSize ObdSize;
						tEplTimerArg TimerArg;

						// create timer to switch automatically to PreOp2 if MN identified all mandatory CNs

						// read NMT_BootTime_REC.MNWaitPreOp1_U32 from OD
						ObdSize = sizeof(dwBuffer);
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
						Ret =
						    EplObduReadEntry
						    (EPL_MCO_PTR_INSTANCE_PTR_
						     0x1F89, 0x03, &dwBuffer,
						     &ObdSize);
						if (Ret != kEplSuccessful) {
							// ignore error, because this timeout is optional
							dwBuffer = 0;
						}
#endif
						if (dwBuffer == 0) {	// delay is deactivated
							// immediately post timer event
							Ret =
							    EplNmtuNmtEvent
							    (kEplNmtEventTimerMsPreOp2);
							break;
						}
						// convert us into ms
						dwBuffer = dwBuffer / 1000;
						if (dwBuffer == 0) {	// timer was below one ms
							// set one ms
							dwBuffer = 1;
						}
						TimerArg.m_EventSink =
						    kEplEventSinkNmtk;
						TimerArg.m_ulArg =
						    (unsigned long)
						    kEplNmtEventTimerMsPreOp2;
						Ret =
						    EplTimeruModifyTimerMs
						    (&EplNmtuInstance_g.
						     m_TimerHdl,
						     (unsigned long)dwBuffer,
						     TimerArg);
						// potential error is forwarded to event queue which generates error event
						break;
					}

					// node processes isochronous and asynchronous frames
				case kEplNmtMsPreOperational2:
					{
						break;
					}

					// node should be configured und application is ready
				case kEplNmtMsReadyToOperate:
					{
						break;
					}

					// normal work state
				case kEplNmtMsOperational:
					{
						break;
					}

					// no EPL cycle
					// -> normal ethernet communication
				case kEplNmtMsBasicEthernet:
					{
						break;
					}
#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)

				default:
					{
						TRACE1
						    ("EplNmtuProcess(): unhandled NMT state 0x%X\n",
						     pNmtStateChange->
						     m_NewNmtState);
					}
				}
			} else if (Ret == kEplReject) {	// application wants to change NMT state itself
				// it's OK
				Ret = kEplSuccessful;
			}

			EPL_DBGLVL_NMTU_TRACE0
			    ("EplNmtuProcessEvent(): NMT-State-Maschine announce change of NMT State\n");
			break;
		}

	default:
		{
			Ret = kEplNmtInvalidEvent;
		}

	}

//Exit:
	return Ret;
}