![Greg Kroah-Hartman](/assets/img/avatar_default.png)
It's a start, still a mess... Cc: Daniel Krueger <daniel.krueger@systec-electronic.com> Cc: Ronald Sieber <Ronald.Sieber@systec-electronic.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
811 lines
26 KiB
C
811 lines
26 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
|