分析协议栈代码,可以发现在运行过程中错误码0x1A\0x1B\0x2C是在CheckIfEcatError()函数中报出, 该函数在mainloop()中被调用,会周期性的执行,负责检查通信和同步变量,并设置AL status(Reg0x130)和AL status code(状态错误码 Reg0x134)。
///////////////////////////////////////////////////////////////////////////////////////// /** \brief Checks communication and synchronisation variables and update AL status / AL status code if an error has occurred *//////////////////////////////////////////////////////////////////////////////////////// void CheckIfEcatError(void) { /*if the watchdog is enabled check the process data watchdog in the ESC and set the AL status code 0x1B if the watchdog expired*/ if (EcatWdValue != 0) // 在从站初始化过程中赋值,默认是100ms { /*watchdog time is set => watchdog is active*/ UINT32 WdStatusOK = 0; HW_EscReadDWord(WdStatusOK, ESC_PD_WD_STATE); // 读0x440寄存器获取硬件WatchDog的状态 WdStatusOK = SWAPDWORD(WdStatusOK); if (!(WdStatusOK & ESC_PD_WD_TRIGGER_MASK) && (nPdOutputSize > 0)) // 当WatchDog溢出时 { /*The device is in OP state*/ if (bEcatOutputUpdateRunning ) { AL_ControlInd(STATE_SAFEOP, ALSTATUSCODE_SMWATCHDOG); //错误码 0x1B return; } else { bEcatFirstOutputsReceived = FALSE; } } } if(bDcSyncActive) { if(bEcatOutputUpdateRunning) { /*Slave is in OP state*/ if(!bDcRunning) //判断条件 { AL_ControlInd(STATE_SAFEOP, ALSTATUSCODE_FATALSYNCERROR); //错误码 0x2C return; } else if(!bSmSyncSequenceValid) // 判断条件 { AL_ControlInd(STATE_SAFEOP, ALSTATUSCODE_SYNCERROR); //错误码 0x1A return; } } } }
///////////////////////////////////////////////////////////////////////////////////////// /** \brief This function checks the current Sync state and set the local flags The analyse of the local flags is handled in "CheckIfEcatError" *//////////////////////////////////////////////////////////////////////////////////////// void DC_CheckWatchdog(void) { if(bDcSyncActive && bEcatInputUpdateRunning) { /*If Sync0 watchdog is enabled and expired*/ if((Sync0WdValue > 0) && (Sync0WdCounter >= Sync0WdValue)) //判断计数器是否超出阈值 { /*Sync0 watchdog expired*/ bDcRunning = FALSE; //超出阈值,设置bDcRunning为假 } else { if(Sync0WdCounter < Sync0WdValue) // 计数器未超出阈值 { Sync0WdCounter ++; // 计数器递增 } bDcRunning = TRUE; } //省略代码 } }
///////////////////////////////////////////////////////////////////////////////////////// /** \brief This function checks the current Sync state and set the local flags The analyse of the local flags is handled in "CheckIfEcatError" *//////////////////////////////////////////////////////////////////////////////////////// void DC_CheckWatchdog(void) { if(bDcSyncActive && bEcatInputUpdateRunning) { // 省略代码 if(bDcRunning) { /*ECATCHANGE_START(V5.13) ESM4*/ if((sErrorSettings.u16SyncErrorCounterLimit == 0) || (sSyncManOutPar.u16SmEventMissedCounter < sErrorSettings.u16SyncErrorCounterLimit)) /*ECATCHANGE_END(V5.13) ESM4*/ { bSmSyncSequenceValid = TRUE; /*Wait for PLL is active increment the Pll valid counter*/ if (i16WaitForPllRunningTimeout > 0) { i16WaitForPllRunningCnt++; } } else if (bSmSyncSequenceValid) // 条件1: ((sErrorSettings.u16SyncErrorCounterLimit != 0) && (sSyncManOutPar.u16SmEventMissedCounter >= sErrorSettings.u16SyncErrorCounterLimit)) { bSmSyncSequenceValid = FALSE; // 报错 /*Wait for PLL is active reset the Pll valid counter*/ if (i16WaitForPllRunningTimeout > 0) { i16WaitForPllRunningCnt = 0; } } } else if(bSmSyncSequenceValid) // 条件2: (!bDcRunning), 该条件是在ALSTATUSCODE_FATALSYNCERROR(0x2C)时产生的 { bSmSyncSequenceValid = FALSE; // 报错 } } }
PROTO UINT16 u16SmSync0Counter; /**< /brief Incremented by one on every Sync0 event and reset to 0 on every SM event. It is used to check the SM/Sync0 sequence */ PROTO UINT16 u16SmSync0Value; /**< /brief Allowed Sync0 events within one SM cycle. If 0 the Sequence check is disabled */ valid*/