801 lines
30 KiB
C
801 lines
30 KiB
C
![]() |
/****************************************************************************
|
||
|
|
||
|
(c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
|
||
|
www.systec-electronic.com
|
||
|
|
||
|
Project: openPOWERLINK
|
||
|
|
||
|
Description: source file for error handler module
|
||
|
|
||
|
License:
|
||
|
|
||
|
Redistribution and use in source and binary forms, with or without
|
||
|
modification, are permitted provided that the following conditions
|
||
|
are met:
|
||
|
|
||
|
1. Redistributions of source code must retain the above copyright
|
||
|
notice, this list of conditions and the following disclaimer.
|
||
|
|
||
|
2. Redistributions in binary form must reproduce the above copyright
|
||
|
notice, this list of conditions and the following disclaimer in the
|
||
|
documentation and/or other materials provided with the distribution.
|
||
|
|
||
|
3. Neither the name of SYSTEC electronic GmbH nor the names of its
|
||
|
contributors may be used to endorse or promote products derived
|
||
|
from this software without prior written permission. For written
|
||
|
permission, please contact info@systec-electronic.com.
|
||
|
|
||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||
|
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||
|
COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||
|
POSSIBILITY OF SUCH DAMAGE.
|
||
|
|
||
|
Severability Clause:
|
||
|
|
||
|
If a provision of this License is or becomes illegal, invalid or
|
||
|
unenforceable in any jurisdiction, that shall not affect:
|
||
|
1. the validity or enforceability in that jurisdiction of any other
|
||
|
provision of this License; or
|
||
|
2. the validity or enforceability in other jurisdictions of that or
|
||
|
any other provision of this License.
|
||
|
|
||
|
-------------------------------------------------------------------------
|
||
|
|
||
|
$RCSfile: EplErrorHandlerk.c,v $
|
||
|
|
||
|
$Author: D.Krueger $
|
||
|
|
||
|
$Revision: 1.9 $ $Date: 2008/10/17 15:32:32 $
|
||
|
|
||
|
$State: Exp $
|
||
|
|
||
|
Build Environment:
|
||
|
GCC V3.4
|
||
|
|
||
|
-------------------------------------------------------------------------
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
2006/10/02 d.k.: start of the implementation
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
#include "kernel/EplErrorHandlerk.h"
|
||
|
#include "EplNmt.h"
|
||
|
#include "kernel/EplEventk.h"
|
||
|
#include "kernel/EplObdk.h" // function prototyps of the EplOBD-Modul
|
||
|
#include "kernel/EplDllk.h"
|
||
|
|
||
|
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
|
||
|
|
||
|
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0)
|
||
|
#error "EPL ErrorHandler module needs EPL module OBDK!"
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/***************************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/* G L O B A L D E F I N I T I O N S */
|
||
|
/* */
|
||
|
/* */
|
||
|
/***************************************************************************/
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
// const defines
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
// local types
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
DWORD m_dwCumulativeCnt; // subindex 1
|
||
|
DWORD m_dwThresholdCnt; // subindex 2
|
||
|
DWORD m_dwThreshold; // subindex 3
|
||
|
|
||
|
} tEplErrorHandlerkErrorCounter;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
tEplErrorHandlerkErrorCounter m_CnLossSoc; // object 0x1C0B
|
||
|
tEplErrorHandlerkErrorCounter m_CnLossPreq; // object 0x1C0D
|
||
|
tEplErrorHandlerkErrorCounter m_CnCrcErr; // object 0x1C0F
|
||
|
unsigned long m_ulDllErrorEvents;
|
||
|
|
||
|
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
|
||
|
tEplErrorHandlerkErrorCounter m_MnCrcErr; // object 0x1C00
|
||
|
tEplErrorHandlerkErrorCounter m_MnCycTimeExceed; // object 0x1C02
|
||
|
DWORD m_adwMnCnLossPresCumCnt[254]; // object 0x1C07
|
||
|
DWORD m_adwMnCnLossPresThrCnt[254]; // object 0x1C08
|
||
|
DWORD m_adwMnCnLossPresThreshold[254];// object 0x1C09
|
||
|
BOOL m_afMnCnLossPresEvent[254];
|
||
|
#endif
|
||
|
|
||
|
} tEplErrorHandlerkInstance;
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
// modul globale vars
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
static tEplErrorHandlerkInstance EplErrorHandlerkInstance_g;
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
// local function prototypes
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
static tEplKernel EplErrorHandlerkLinkErrorCounter(
|
||
|
tEplErrorHandlerkErrorCounter* pErrorCounter_p,
|
||
|
unsigned int uiIndex_p);
|
||
|
|
||
|
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
|
||
|
static tEplKernel EplErrorHandlerkLinkArray(
|
||
|
DWORD* pdwValue_p,
|
||
|
unsigned int uiValueCount_p,
|
||
|
unsigned int uiIndex_p);
|
||
|
#endif
|
||
|
|
||
|
/***************************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/* C L A S S <Epl-Kernelspace-Error-Handler> */
|
||
|
/* */
|
||
|
/* */
|
||
|
/***************************************************************************/
|
||
|
//
|
||
|
// Description:
|
||
|
//
|
||
|
//
|
||
|
/***************************************************************************/
|
||
|
|
||
|
//=========================================================================//
|
||
|
// //
|
||
|
// P U B L I C F U N C T I O N S //
|
||
|
// //
|
||
|
//=========================================================================//
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: EplErrorHandlerkInit
|
||
|
//
|
||
|
// Description: function initialize the first instance
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
//
|
||
|
// Returns: tEpKernel = errorcode
|
||
|
//
|
||
|
//
|
||
|
// State:
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
tEplKernel PUBLIC EplErrorHandlerkInit(void)
|
||
|
{
|
||
|
tEplKernel Ret;
|
||
|
|
||
|
|
||
|
Ret = EplErrorHandlerkAddInstance();
|
||
|
|
||
|
|
||
|
return Ret;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: EplErrorHandlerkAddInstance
|
||
|
//
|
||
|
// Description: function add one more instance
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
//
|
||
|
// Returns: tEpKernel = errorcode
|
||
|
//
|
||
|
//
|
||
|
// State:
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
tEplKernel PUBLIC EplErrorHandlerkAddInstance(void)
|
||
|
{
|
||
|
tEplKernel Ret;
|
||
|
|
||
|
Ret = kEplSuccessful;
|
||
|
|
||
|
// reset only event variable,
|
||
|
// all other instance members are reset by OD or may keep their current value
|
||
|
// d.k.: this is necessary for the cumulative counters, which shall not be reset
|
||
|
EplErrorHandlerkInstance_g.m_ulDllErrorEvents = 0;
|
||
|
|
||
|
// link counters to OD
|
||
|
// $$$ d.k. if OD resides in userspace, fetch pointer to shared memory,
|
||
|
// which shall have the same structure as the instance (needs to be declared globally).
|
||
|
// Other idea: error counter shall belong to the process image
|
||
|
// (reset of counters by SDO write are a little bit tricky).
|
||
|
|
||
|
Ret = EplErrorHandlerkLinkErrorCounter(
|
||
|
&EplErrorHandlerkInstance_g.m_CnLossSoc,
|
||
|
0x1C0B);
|
||
|
if (Ret != kEplSuccessful)
|
||
|
{
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
Ret = EplErrorHandlerkLinkErrorCounter(
|
||
|
&EplErrorHandlerkInstance_g.m_CnLossPreq,
|
||
|
0x1C0D);
|
||
|
// ignore return code, because object 0x1C0D is conditional
|
||
|
|
||
|
Ret = EplErrorHandlerkLinkErrorCounter(
|
||
|
&EplErrorHandlerkInstance_g.m_CnCrcErr,
|
||
|
0x1C0F);
|
||
|
if (Ret != kEplSuccessful)
|
||
|
{
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
|
||
|
Ret = EplErrorHandlerkLinkErrorCounter(
|
||
|
&EplErrorHandlerkInstance_g.m_MnCrcErr,
|
||
|
0x1C00);
|
||
|
if (Ret != kEplSuccessful)
|
||
|
{
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
Ret = EplErrorHandlerkLinkErrorCounter(
|
||
|
&EplErrorHandlerkInstance_g.m_MnCycTimeExceed,
|
||
|
0x1C02);
|
||
|
if (Ret != kEplSuccessful)
|
||
|
{
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
Ret = EplErrorHandlerkLinkArray(
|
||
|
EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt,
|
||
|
tabentries(EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt),
|
||
|
0x1C07);
|
||
|
if (Ret != kEplSuccessful)
|
||
|
{
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
Ret = EplErrorHandlerkLinkArray(
|
||
|
EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt,
|
||
|
tabentries(EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt),
|
||
|
0x1C08);
|
||
|
if (Ret != kEplSuccessful)
|
||
|
{
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
Ret = EplErrorHandlerkLinkArray(
|
||
|
EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold,
|
||
|
tabentries(EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold),
|
||
|
0x1C09);
|
||
|
if (Ret != kEplSuccessful)
|
||
|
{
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
Exit:
|
||
|
return Ret;
|
||
|
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: EplErrorHandlerkDelInstance
|
||
|
//
|
||
|
// Description: function delete instance an free the bufferstructure
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
//
|
||
|
// Returns: tEpKernel = errorcode
|
||
|
//
|
||
|
//
|
||
|
// State:
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
tEplKernel PUBLIC EplErrorHandlerkDelInstance()
|
||
|
{
|
||
|
tEplKernel Ret;
|
||
|
|
||
|
Ret = kEplSuccessful;
|
||
|
|
||
|
|
||
|
return Ret;
|
||
|
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: EplErrorHandlerkProcess
|
||
|
//
|
||
|
// Description: processes error events from DLL
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
// Parameters: pEvent_p = pointer to event-structur from buffer
|
||
|
//
|
||
|
//
|
||
|
// Returns: tEpKernel = errorcode
|
||
|
//
|
||
|
//
|
||
|
// State:
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
tEplKernel PUBLIC EplErrorHandlerkProcess(tEplEvent* pEvent_p)
|
||
|
{
|
||
|
tEplKernel Ret;
|
||
|
unsigned long ulDllErrorEvents;
|
||
|
tEplEvent Event;
|
||
|
tEplNmtEvent NmtEvent;
|
||
|
|
||
|
Ret = kEplSuccessful;
|
||
|
|
||
|
// check m_EventType
|
||
|
switch(pEvent_p->m_EventType)
|
||
|
{
|
||
|
case kEplEventTypeDllError:
|
||
|
{
|
||
|
tEplErrorHandlerkEvent* pErrHandlerEvent = (tEplErrorHandlerkEvent*)pEvent_p->m_pArg;
|
||
|
|
||
|
ulDllErrorEvents = pErrHandlerEvent->m_ulDllErrorEvents;
|
||
|
|
||
|
// check the several error events
|
||
|
if ((EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThreshold > 0)
|
||
|
&& ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_SOC) != 0))
|
||
|
{ // loss of SoC event occured
|
||
|
// increment cumulative counter by 1
|
||
|
EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwCumulativeCnt++;
|
||
|
// increment threshold counter by 8
|
||
|
EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt += 8;
|
||
|
if (EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt
|
||
|
>= EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThreshold)
|
||
|
{ // threshold is reached
|
||
|
// $$$ d.k.: generate error history entry E_DLL_LOSS_SOC_TH
|
||
|
|
||
|
// post event to NMT state machine
|
||
|
NmtEvent = kEplNmtEventNmtCycleError;
|
||
|
Event.m_EventSink = kEplEventSinkNmtk;
|
||
|
Event.m_EventType = kEplEventTypeNmtEvent;
|
||
|
Event.m_pArg = &NmtEvent;
|
||
|
Event.m_uiSize = sizeof (NmtEvent);
|
||
|
Ret = EplEventkPost(&Event);
|
||
|
}
|
||
|
EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
|
||
|
EPL_DLL_ERR_CN_LOSS_SOC;
|
||
|
}
|
||
|
|
||
|
if ((EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThreshold > 0)
|
||
|
&& ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_PREQ) != 0))
|
||
|
{ // loss of PReq event occured
|
||
|
// increment cumulative counter by 1
|
||
|
EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwCumulativeCnt++;
|
||
|
// increment threshold counter by 8
|
||
|
EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt += 8;
|
||
|
if (EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt
|
||
|
>= EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThreshold)
|
||
|
{ // threshold is reached
|
||
|
// $$$ d.k.: generate error history entry E_DLL_LOSS_PREQ_TH
|
||
|
|
||
|
// post event to NMT state machine
|
||
|
NmtEvent = kEplNmtEventNmtCycleError;
|
||
|
Event.m_EventSink = kEplEventSinkNmtk;
|
||
|
Event.m_EventType = kEplEventTypeNmtEvent;
|
||
|
Event.m_pArg = &NmtEvent;
|
||
|
Event.m_uiSize = sizeof (NmtEvent);
|
||
|
Ret = EplEventkPost(&Event);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ((EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt > 0)
|
||
|
&& ((ulDllErrorEvents & EPL_DLL_ERR_CN_RECVD_PREQ) != 0))
|
||
|
{ // PReq correctly received
|
||
|
// decrement threshold counter by 1
|
||
|
EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt--;
|
||
|
}
|
||
|
|
||
|
if ((EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThreshold > 0)
|
||
|
&& ((ulDllErrorEvents & EPL_DLL_ERR_CN_CRC) != 0))
|
||
|
{ // CRC error event occured
|
||
|
// increment cumulative counter by 1
|
||
|
EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwCumulativeCnt++;
|
||
|
// increment threshold counter by 8
|
||
|
EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt += 8;
|
||
|
if (EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt
|
||
|
>= EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThreshold)
|
||
|
{ // threshold is reached
|
||
|
// $$$ d.k.: generate error history entry E_DLL_CRC_TH
|
||
|
|
||
|
// post event to NMT state machine
|
||
|
NmtEvent = kEplNmtEventNmtCycleError;
|
||
|
Event.m_EventSink = kEplEventSinkNmtk;
|
||
|
Event.m_EventType = kEplEventTypeNmtEvent;
|
||
|
Event.m_pArg = &NmtEvent;
|
||
|
Event.m_uiSize = sizeof (NmtEvent);
|
||
|
Ret = EplEventkPost(&Event);
|
||
|
}
|
||
|
EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
|
||
|
EPL_DLL_ERR_CN_CRC;
|
||
|
}
|
||
|
|
||
|
if ((ulDllErrorEvents & EPL_DLL_ERR_INVALID_FORMAT) != 0)
|
||
|
{ // invalid format error occured (only direct reaction)
|
||
|
// $$$ d.k.: generate error history entry E_DLL_INVALID_FORMAT
|
||
|
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
|
||
|
if (pErrHandlerEvent->m_NmtState >= kEplNmtMsNotActive)
|
||
|
{ // MN is active
|
||
|
if (pErrHandlerEvent->m_uiNodeId != 0)
|
||
|
{
|
||
|
tEplHeartbeatEvent HeartbeatEvent;
|
||
|
|
||
|
// remove node from isochronous phase
|
||
|
Ret = EplDllkDeleteNode(pErrHandlerEvent->m_uiNodeId);
|
||
|
|
||
|
// inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN
|
||
|
HeartbeatEvent.m_uiNodeId = pErrHandlerEvent->m_uiNodeId;
|
||
|
HeartbeatEvent.m_NmtState = kEplNmtCsNotActive;
|
||
|
HeartbeatEvent.m_wErrorCode = EPL_E_DLL_INVALID_FORMAT;
|
||
|
Event.m_EventSink = kEplEventSinkNmtMnu;
|
||
|
Event.m_EventType = kEplEventTypeHeartbeat;
|
||
|
Event.m_uiSize = sizeof (HeartbeatEvent);
|
||
|
Event.m_pArg = &HeartbeatEvent;
|
||
|
Ret = EplEventkPost(&Event);
|
||
|
}
|
||
|
// $$$ and else should lead to InternComError
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
{ // CN is active
|
||
|
// post event to NMT state machine
|
||
|
NmtEvent = kEplNmtEventInternComError;
|
||
|
Event.m_EventSink = kEplEventSinkNmtk;
|
||
|
Event.m_EventType = kEplEventTypeNmtEvent;
|
||
|
Event.m_pArg = &NmtEvent;
|
||
|
Event.m_uiSize = sizeof (NmtEvent);
|
||
|
Ret = EplEventkPost(&Event);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
|
||
|
if ((EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThreshold > 0)
|
||
|
&& ((ulDllErrorEvents & EPL_DLL_ERR_MN_CRC) != 0))
|
||
|
{ // CRC error event occured
|
||
|
// increment cumulative counter by 1
|
||
|
EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwCumulativeCnt++;
|
||
|
// increment threshold counter by 8
|
||
|
EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt += 8;
|
||
|
if (EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt
|
||
|
>= EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThreshold)
|
||
|
{ // threshold is reached
|
||
|
// $$$ d.k.: generate error history entry E_DLL_CRC_TH
|
||
|
|
||
|
// post event to NMT state machine
|
||
|
NmtEvent = kEplNmtEventNmtCycleError;
|
||
|
Event.m_EventSink = kEplEventSinkNmtk;
|
||
|
Event.m_EventType = kEplEventTypeNmtEvent;
|
||
|
Event.m_pArg = &NmtEvent;
|
||
|
Event.m_uiSize = sizeof (NmtEvent);
|
||
|
Ret = EplEventkPost(&Event);
|
||
|
}
|
||
|
EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
|
||
|
EPL_DLL_ERR_MN_CRC;
|
||
|
}
|
||
|
|
||
|
if ((EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThreshold > 0)
|
||
|
&& ((ulDllErrorEvents & EPL_DLL_ERR_MN_CYCTIMEEXCEED) != 0))
|
||
|
{ // cycle time exceeded event occured
|
||
|
// increment cumulative counter by 1
|
||
|
EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwCumulativeCnt++;
|
||
|
// increment threshold counter by 8
|
||
|
EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt += 8;
|
||
|
if (EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt
|
||
|
>= EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThreshold)
|
||
|
{ // threshold is reached
|
||
|
// $$$ d.k.: generate error history entry E_DLL_CYCLE_EXCEED_TH
|
||
|
|
||
|
// post event to NMT state machine
|
||
|
NmtEvent = kEplNmtEventNmtCycleError;
|
||
|
Event.m_EventSink = kEplEventSinkNmtk;
|
||
|
Event.m_EventType = kEplEventTypeNmtEvent;
|
||
|
Event.m_pArg = &NmtEvent;
|
||
|
Event.m_uiSize = sizeof (NmtEvent);
|
||
|
Ret = EplEventkPost(&Event);
|
||
|
}
|
||
|
// $$$ d.k.: else generate error history entry E_DLL_CYCLE_EXCEED
|
||
|
EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
|
||
|
EPL_DLL_ERR_MN_CYCTIMEEXCEED;
|
||
|
}
|
||
|
|
||
|
if ((ulDllErrorEvents & EPL_DLL_ERR_MN_CN_LOSS_PRES) != 0)
|
||
|
{ // CN loss PRes event occured
|
||
|
unsigned int uiNodeId;
|
||
|
|
||
|
uiNodeId = pErrHandlerEvent->m_uiNodeId - 1;
|
||
|
if ((uiNodeId < tabentries(EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt))
|
||
|
&& (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold[uiNodeId] > 0))
|
||
|
{
|
||
|
// increment cumulative counter by 1
|
||
|
EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt[uiNodeId]++;
|
||
|
// increment threshold counter by 8
|
||
|
EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId] += 8;
|
||
|
if (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId]
|
||
|
>= EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold[uiNodeId])
|
||
|
{ // threshold is reached
|
||
|
tEplHeartbeatEvent HeartbeatEvent;
|
||
|
|
||
|
// $$$ d.k.: generate error history entry E_DLL_LOSS_PRES_TH
|
||
|
|
||
|
// remove node from isochronous phase
|
||
|
Ret = EplDllkDeleteNode(pErrHandlerEvent->m_uiNodeId);
|
||
|
|
||
|
// inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN
|
||
|
HeartbeatEvent.m_uiNodeId = pErrHandlerEvent->m_uiNodeId;
|
||
|
HeartbeatEvent.m_NmtState = kEplNmtCsNotActive;
|
||
|
HeartbeatEvent.m_wErrorCode = EPL_E_DLL_LOSS_PRES_TH;
|
||
|
Event.m_EventSink = kEplEventSinkNmtMnu;
|
||
|
Event.m_EventType = kEplEventTypeHeartbeat;
|
||
|
Event.m_uiSize = sizeof (HeartbeatEvent);
|
||
|
Event.m_pArg = &HeartbeatEvent;
|
||
|
Ret = EplEventkPost(&Event);
|
||
|
}
|
||
|
EplErrorHandlerkInstance_g.m_afMnCnLossPresEvent[uiNodeId] = TRUE;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// NMT event
|
||
|
case kEplEventTypeNmtEvent:
|
||
|
{
|
||
|
if ((*(tEplNmtEvent*)pEvent_p->m_pArg) == kEplNmtEventDllCeSoa)
|
||
|
{ // SoA event of CN -> decrement threshold counters
|
||
|
|
||
|
if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_SOC) == 0)
|
||
|
{ // decrement loss of SoC threshold counter, because it didn't occur last cycle
|
||
|
if (EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt > 0)
|
||
|
{
|
||
|
EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_CN_CRC) == 0)
|
||
|
{ // decrement CRC threshold counter, because it didn't occur last cycle
|
||
|
if (EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt > 0)
|
||
|
{
|
||
|
EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt--;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
|
||
|
else if ((*(tEplNmtEvent*)pEvent_p->m_pArg) == kEplNmtEventDllMeSoaSent)
|
||
|
{ // SoA event of MN -> decrement threshold counters
|
||
|
tEplDllkNodeInfo* pIntNodeInfo;
|
||
|
unsigned int uiNodeId;
|
||
|
|
||
|
Ret = EplDllkGetFirstNodeInfo(&pIntNodeInfo);
|
||
|
if (Ret != kEplSuccessful)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
// iterate through node info structure list
|
||
|
while (pIntNodeInfo != NULL)
|
||
|
{
|
||
|
uiNodeId = pIntNodeInfo->m_uiNodeId - 1;
|
||
|
if (uiNodeId < tabentries(EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt))
|
||
|
{
|
||
|
if (EplErrorHandlerkInstance_g.m_afMnCnLossPresEvent[uiNodeId] == FALSE)
|
||
|
{
|
||
|
if (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId] > 0)
|
||
|
{
|
||
|
EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId]--;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
EplErrorHandlerkInstance_g.m_afMnCnLossPresEvent[uiNodeId] = FALSE;
|
||
|
}
|
||
|
}
|
||
|
pIntNodeInfo = pIntNodeInfo->m_pNextNodeInfo;
|
||
|
}
|
||
|
|
||
|
if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_MN_CRC) == 0)
|
||
|
{ // decrement CRC threshold counter, because it didn't occur last cycle
|
||
|
if (EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt > 0)
|
||
|
{
|
||
|
EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_MN_CYCTIMEEXCEED) == 0)
|
||
|
{ // decrement cycle exceed threshold counter, because it didn't occur last cycle
|
||
|
if (EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt > 0)
|
||
|
{
|
||
|
EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt--;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
// reset error events
|
||
|
EplErrorHandlerkInstance_g.m_ulDllErrorEvents = 0L;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
// unknown type
|
||
|
default:
|
||
|
{
|
||
|
}
|
||
|
|
||
|
} // end of switch(pEvent_p->m_EventType)
|
||
|
|
||
|
|
||
|
return Ret;
|
||
|
|
||
|
}
|
||
|
|
||
|
//=========================================================================//
|
||
|
// //
|
||
|
// P R I V A T E F U N C T I O N S //
|
||
|
// //
|
||
|
//=========================================================================//
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: EplErrorHandlerkLinkErrorCounter
|
||
|
//
|
||
|
// Description: link specified error counter structure to OD entry
|
||
|
//
|
||
|
// Parameters: pErrorCounter_p = pointer to error counter structure
|
||
|
// uiIndex_p = OD index
|
||
|
//
|
||
|
// Returns: tEplKernel = error code
|
||
|
//
|
||
|
//
|
||
|
// State:
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
static tEplKernel EplErrorHandlerkLinkErrorCounter(
|
||
|
tEplErrorHandlerkErrorCounter* pErrorCounter_p,
|
||
|
unsigned int uiIndex_p)
|
||
|
{
|
||
|
tEplKernel Ret = kEplSuccessful;
|
||
|
tEplVarParam VarParam;
|
||
|
|
||
|
VarParam.m_pData = &pErrorCounter_p->m_dwCumulativeCnt;
|
||
|
VarParam.m_Size = sizeof(DWORD);
|
||
|
VarParam.m_uiIndex = uiIndex_p;
|
||
|
VarParam.m_uiSubindex = 0x01;
|
||
|
VarParam.m_ValidFlag = kVarValidAll;
|
||
|
Ret = EplObdDefineVar(&VarParam);
|
||
|
if (Ret != kEplSuccessful)
|
||
|
{
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
VarParam.m_pData = &pErrorCounter_p->m_dwThresholdCnt;
|
||
|
VarParam.m_Size = sizeof(DWORD);
|
||
|
VarParam.m_uiIndex = uiIndex_p;
|
||
|
VarParam.m_uiSubindex = 0x02;
|
||
|
VarParam.m_ValidFlag = kVarValidAll;
|
||
|
Ret = EplObdDefineVar(&VarParam);
|
||
|
if (Ret != kEplSuccessful)
|
||
|
{
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
VarParam.m_pData = &pErrorCounter_p->m_dwThreshold;
|
||
|
VarParam.m_Size = sizeof(DWORD);
|
||
|
VarParam.m_uiIndex = uiIndex_p;
|
||
|
VarParam.m_uiSubindex = 0x03;
|
||
|
VarParam.m_ValidFlag = kVarValidAll;
|
||
|
Ret = EplObdDefineVar(&VarParam);
|
||
|
if (Ret != kEplSuccessful)
|
||
|
{
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
Exit:
|
||
|
return Ret;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: EplErrorHandlerkLinkErrorCounter
|
||
|
//
|
||
|
// Description: link specified error counter structure to OD entry
|
||
|
//
|
||
|
// Parameters: pErrorCounter_p = pointer to error counter structure
|
||
|
// uiIndex_p = OD index
|
||
|
//
|
||
|
// Returns: tEplKernel = error code
|
||
|
//
|
||
|
//
|
||
|
// State:
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
|
||
|
static tEplKernel EplErrorHandlerkLinkArray(
|
||
|
DWORD* pdwValue_p,
|
||
|
unsigned int uiValueCount_p,
|
||
|
unsigned int uiIndex_p)
|
||
|
{
|
||
|
tEplKernel Ret = kEplSuccessful;
|
||
|
tEplVarParam VarParam;
|
||
|
tEplObdSize EntrySize;
|
||
|
BYTE bIndexEntries;
|
||
|
|
||
|
EntrySize = (tEplObdSize) sizeof(bIndexEntries);
|
||
|
Ret = EplObdReadEntry (
|
||
|
uiIndex_p,
|
||
|
0x00,
|
||
|
(void GENERIC*) &bIndexEntries,
|
||
|
&EntrySize );
|
||
|
|
||
|
if ((Ret != kEplSuccessful) || (bIndexEntries == 0x00))
|
||
|
{
|
||
|
// Object doesn't exist or invalid entry number
|
||
|
Ret = kEplObdIndexNotExist;
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
if (bIndexEntries < uiValueCount_p)
|
||
|
{
|
||
|
uiValueCount_p = bIndexEntries;
|
||
|
}
|
||
|
|
||
|
VarParam.m_Size = sizeof(DWORD);
|
||
|
VarParam.m_uiIndex = uiIndex_p;
|
||
|
VarParam.m_ValidFlag = kVarValidAll;
|
||
|
|
||
|
for (VarParam.m_uiSubindex = 0x01; VarParam.m_uiSubindex <= uiValueCount_p; VarParam.m_uiSubindex++)
|
||
|
{
|
||
|
VarParam.m_pData = pdwValue_p;
|
||
|
Ret = EplObdDefineVar(&VarParam);
|
||
|
if (Ret != kEplSuccessful)
|
||
|
{
|
||
|
goto Exit;
|
||
|
}
|
||
|
pdwValue_p++;
|
||
|
}
|
||
|
|
||
|
Exit:
|
||
|
return Ret;
|
||
|
}
|
||
|
#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
|
||
|
|
||
|
|
||
|
#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
|
||
|
|
||
|
// EOF
|
||
|
|