当前位置: 首页 > news >正文

EtherCAT WatchDog

目录

  • 前言
  • DC看门狗
      • 如何触发OP to SafeOP的
      • 如何设置门限值的
      • 如何喂狗的
  • 本地看门狗
      • 如何触发OP to SafeOP的
      • 如何设置门限值的
      • 如何喂狗的

前言

  • EtherCAT设置看门狗的目的是,执行周期不正常的时候,将状态机由OP返回到SafeOP。比如轮询模式下APP部分拖了太长的时间,中断模式下协议栈之外的某个中断卡死导致过程数据更新周期异常
  • EtherCAT协议栈中的看门狗是软件实现的。门限值参数由ESC寄存器中提供,判断超限和回到SafeOP都要协议栈实现。

协议栈里有两种看门狗,分别是DC看门狗和本地看门狗。如果使用了DC的话协议栈会生成SM相关的看门狗代码,此时不需要再做本地看门狗了。(要手动修改ESC_SM_WD_SUPPORTED为1,才不会生成相关代码)

如果没有使用DC的话,手动修改ESC_SM_WD_SUPPORTED为0,协议栈会生成一个本地看门狗的代码
在这里插入图片描述

DC看门狗

在这里插入图片描述

在这里插入图片描述

如何触发OP to SafeOP的

变量定义:
Sync0WdCounter:sync0看门狗计数器
Sync0WdValue:sync0看门狗门限值
Sync1WdCounter:sync1看门狗计数器
Sync1WdValue:sync1看门狗门限值

EtherCAT要求提供一个1ms的定时器,对接函数如下

//此函数文件来自用户对接
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim == &htim3){ECAT_CheckTimer();}
}

ECAT_CheckTimer会调用DC_CheckWatchdog, DC_CheckWatchdog内容如下
简单来说就是判断Sync0WdCounter 是否超过 Sync0WdValue 门限值,超过了设置 bDcRunning = TRUE;,否则计数器自增

//ecatslv.c -> DC_CheckWatchdog()
void DC_CheckWatchdog(void)
{.../*If Sync0 watchdog is enabled and expired*/if((Sync0WdValue > 0) && (Sync0WdCounter >= Sync0WdValue)){/*Sync0 watchdog expired*/bDcRunning = FALSE;        }else{if(Sync0WdCounter < Sync0WdValue){Sync0WdCounter ++;}bDcRunning = TRUE;}.../*Check the Sync1 cycle if Sync1 Wd is enabled*/if(Sync1WdValue > 0){if(Sync1WdCounter < Sync1WdValue){Sync1WdCounter ++;}else{/*Sync1 watchdog expired*/bDcRunning = FALSE;}}}

为什么设置了bDcRunning = FALSE;就能让EtherCAT状态机回到SAFEOP呢?
MainLoop -> CheckIfEcatError中有如下代码

//ecatslv.c -> CheckIfEcatError
void CheckIfEcatError(void)
{...if(bDcSyncActive){if(bEcatOutputUpdateRunning){/*Slave is in OP state*/if(!bDcRunning){AL_ControlInd(STATE_SAFEOP, ALSTATUSCODE_FATALSYNCERROR);return;}else if(!bSmSyncSequenceValid){AL_ControlInd(STATE_SAFEOP, ALSTATUSCODE_SYNCERROR);return;}}}}

如何设置门限值的

cycleTimeSync0, shiftTimeSync1 分别从寄存器ESC_DC_SYNC0_CYCLETIME, ESC_DC_SYNC1_CYCLETIME中读取获得

Sync0WdValue 的门限值设置规则是

  • Sync0WdValue 是cycleTimeSync0 的二倍
  • Sync0WdValue 至少为1ms

Sync1WdValue的门限值设置规则是

  • 如果shiftTimeSync1 比cycleTimeSync0短,那么Sync1WdValue=Sync0WdValue
  • Sync1Cycle 是cycleTimeSync0和shiftTimeSync1 之和,Sync1WdValue是Sync1Cycle 的二倍
  • Sync1WdValue至少1ms
  • Sync1WdValue要在上述计算值上增加Sync0WdValue的一半。
    建议结合代码理解,上面的描述感觉不准确,比如最后的加一半MCU里可能会丢小数。
//ecatslv.c -> StartInputHandler()
UINT16 StartInputHandler(void)
{....// Cycle time for Sync0HW_EscReadDWord(cycleTimeSync0, ESC_DC_SYNC0_CYCLETIME_OFFSET);cycleTimeSync0 = SWAPDWORD(cycleTimeSync0);// Cycle time for Sync1HW_EscReadDWord(shiftTimeSync1, ESC_DC_SYNC1_CYCLETIME_OFFSET);shiftTimeSync1 = SWAPDWORD(shiftTimeSync1);..../*calculate the Sync0 Watchdog counter value the minimum value is 1 msif the sync0 cycle is greater 500us the Sync0 Wd value is 2*Sycn0 cycle */if(cycleTimeSync0 == 0){Sync0WdValue = 0;}else{UINT32 Sync0Cycle = cycleTimeSync0/100000;if(Sync0Cycle < 5){/*Sync0 cycle less than 500us*/Sync0WdValue = 1;}else{Sync0WdValue = (UINT16)(Sync0Cycle*2)/10;}}/* Calculate also the watchdog time for Sync1*/if ( (dcControl & ESC_DC_SYNC1_ACTIVE_MASK) != 0 ){if(shiftTimeSync1 < cycleTimeSync0){/* Sync 1 has the same cycle time than Sync0 (maybe with a shift (shiftTimeSync1 > 0))*/Sync1WdValue = Sync0WdValue;}else{/* Sync1 cycle is larger than Sync0 (e.g. subordinated Sync0 cycles) */UINT32 Sync1Cycle = (shiftTimeSync1  + cycleTimeSync0 )/100000;if(Sync1Cycle < 5){/*Sync0 cycle less than 500us*/Sync1WdValue = 1;}else{Sync1WdValue = (UINT16)((Sync1Cycle*2)/10);}/* add one Sync0 cycle because the Sync1 cycle starts on the next Sync0 after the Sync1 signal */Sync1WdValue += Sync0WdValue/2;}
}

如何喂狗的

//ecatappl.c -> Sync0_Isr
void Sync0_Isr(void)
{Sync0WdCounter = 0;...
}void Sync1_Isr(void)
{Sync1WdCounter = 0;...
}

DC大概就这样

本地看门狗

在这里插入图片描述

在这里插入图片描述

如何触发OP to SafeOP的

变量定义:
EcatWdCounter :本地看门狗计数值
EcatWdValue :本地看门狗门限值

//此函数文件来自用户对接
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim == &htim3){ECAT_CheckTimer();}
}
//ecatappl.c -> ECAT_CheckTimer
void ECAT_CheckTimer(void)
{...ECAT_CheckWatchdog()
}

判断的套路与上面DC的一致,检查到超限就设置回到SafeOP

//ecatslv.c -> ECAT_CheckWatchdog
void ECAT_CheckWatchdog(void)
{if ( EcatWdValue != 0 ){// Watchdog is activeEcatWdCounter++;if ( EcatWdCounter >= EcatWdValue ){// Watchdog is expiredEcatWdCounter = 0;if (nPdOutputSize > 0){//handle only the expired PD watchdog if outputs are configuredif (bEcatOutputUpdateRunning){/* watchdog expired in OP */AL_ControlInd(STATE_SAFEOP, ALSTATUSCODE_SMWATCHDOG);}else{/* watchdog expired in SAFE-OP */bEcatFirstOutputsReceived = FALSE;}}}}
}

如何设置门限值的

wd:来自ESC_PD_WD_TIME寄存器,看门狗门限
wdiv:来自ESC_WD_DIVIDER_OFFSET,分频器
EcatWdValue = (wd * wdiv),再做一次圆整(没分析具体圆整到多少)

ecatslv.c -> StartInputHandler()中有下面内容

//ecatslv.c -> StartInputHandler()
UINT16 StartInputHandler(void)
{..../*get the watchdog time (register 0x420). if value is > 0 watchdog is active*/HW_EscReadWord(wd, ESC_PD_WD_TIME);wd = SWAPWORD(wd);if (nPdOutputSize > 0 &&  wd != 0 ){/*get watchdog divider (register 0x400)*/HW_EscReadWord(wdiv, ESC_WD_DIVIDER_OFFSET);wdiv = SWAPWORD(wdiv);if ( wdiv != 0 ){/* the ESC subtracts 2 in register 0x400 so it has to be added here */UINT32 d = wdiv+2;d *= wd;/* store watchdog in ms in variable EcatWdValue *//* watchdog value has to be rounded up */d = (INT32)(d + 24999);d /= 25000;EcatWdValue = (UINT16) d;}else{wd = 0;/* wd value has to be set to zero, if the wd is 0 */EcatWdValue = 0;}/* reset watchdog counter */EcatWdCounter = 0;}else{/* the watchdog is deactivated or slave has no output process data*/wdiv = 0;EcatWdValue = 0;}
}

如何喂狗的

void PDI_Isr(void)
{...EcatWdCounter = 0;}

除了PDI ISR,mainloop中也有,不赘述了

http://www.dtcms.com/a/322085.html

相关文章:

  • V4L2摄像头采集 + WiFi实时传输实战全流程
  • 深圳市天正达电子股份有限公司参展AUTO TECH China 2025 广州国际汽车技术展览会
  • std::transform
  • AI大模型专题:LLM大模型(Prompt提示词工程)
  • C语言实现经典扫雷游戏全解析
  • 使用观测云打造企业级监控告警中心
  • cudagraph 本质详解
  • Vue框架进阶
  • 宠智灵打造宠物AI开放平台:精准识别、灵活部署、生态共建
  • C++入门(上) -- 讲解超详细
  • 【狂神说java学习笔记】四:java流程控制(用户交互Scanner、顺序结构、if选择结构、switch选择结构)
  • isulad + harbor私有仓库登录
  • 大模型性能测试实战指南:从原理到落地的全链路解析
  • Claude使用报错 Error: Cannot find module ‘./yoga.wasm‘
  • 鸿蒙中使用tree
  • 系统集成项目管理工程师【第十一章 规划过程组】规划成本管理、成本估算、制定预算和规划质量管理篇
  • 安全基础DAY1-安全概述
  • Xiphos Q8 摄像头板 高性能图像处理板
  • 案例实战:机器学习预测粘度+耐热高分子筛选,聚合物研发效率倍增秘籍
  • 锯床自动长度检测与参数闭环补偿系统
  • 2025年环境工程与新能源科学国际会议(EENES 2025)
  • x265开源编码器源码框架深度解析
  • 知识图谱【2】
  • 五、SpringBoot工程打包与运行
  • SpringAI实现多用户记忆隔离
  • 【SpringAI】9.创建本地mcp服务(演示通过mcp实现联网搜索)
  • Git Commit 命令详解:版本控制的核心操作
  • $QAXHoneypot是什么文件夹
  • 2025 蓝桥杯C/C++国B 部分题解
  • DAY34打卡