[EtherCAT]SSC从站协议栈中的中断配置参数和中断优先级设置

SSC Tool中的中断配置参数

EtherCAT从站协议栈SSC会使用到4个中断,其中ESC会产生PDI\SYNC0\SYNC1中断去通知MCU进行处理(HPM6E00与HPM5E00还支持产生Reset Out中断), 此外MCU还会产生1ms的tick时钟用做软件实现EtherCAT DC watchdog检查。

在SSC Tool中使用参数控制生成代码中的中断处理逻辑。

  • AL_EVENT_ENABLED: 使能PDI_TRQ处理逻辑
  • DC_SUPPORTED: 使能SYNC0_IRQ\SYNC1_IRQ处理逻辑
  • ECAT_TIMER_INT: 使能在1ms Timer中断中处理EtherCAT watchdog检查

通常以上3个参数都应该设置成1, 调整以上参数可以改变SSC的同步模式。 例如不使用PDI中断, 只使用SYNC0\1中断时, 可以设置AL_EVENT_ENABLED = 0,DC_SUPPORTED = 1, 此时协议栈会在SYNC中断中处理PDI通信任务。

ESC中断优先级设置

根据ETG建议,中断优先级是PDI > SYNC0\SYNC1 > Timer
实际使用中需要考虑SSC代码参数ECAT_TIMER_INT的设置, 调整Timer中断的优先级。

在EtherCAT数据帧到达从站(PDI事件)时刻与从站SYNC0/SYNC1时刻非常接近时,需要考虑是优先执行PDI_Isr()处理数据通信,还是优先执行Sync0_Isr()/Sync1_Isr()进行控制动作。

通常主站会保证EtherCAT数据帧到达从站(PDI)时刻与从站SYNC0/SYNC1时刻在时间上错开,只有主站在发出数据帧的周期抖动过大时才会出现PDI事件时刻与从站SYNC0/SYNC1时刻非常接近的情况。

在使能DC功能的情况下,主站发出数据帧的周期抖动过大,会出现0x1A的DC同步错误(bSmSyncSequenceValid为false), 即在当前DC周期,从站没有收到主站发来的有效数据帧。

当在生成SSC代码时设置ECAT_TIMER_INT = 1,代码会在1ms Timer中断中调用DC_CheckWatchdog()递增Sync0WdCounter变量, Sync0_Isr()/Sync0_Isr()执行时清零Sync0WdCounter变量,确保其不超出阈值。

由于在RV32平台Sync0WdCounter++指令不是单条原子指令,而是多条指令。当1ms中断中执行Sync0WdCounter++被Sync0_Isr()/Sync1_Isr()执行Sync0WdCounter = 0打断时,会触发竞态问题,造成Sync0WdCounter不能被正确清零, 进而触发0x2C错误, 参考《[EtherCAT]一种竞争态引起从站报错0x2C的分析》

ESC中断开启和关闭函数

SSC协议栈要求提供DISABLE_ESC_INT()和ENABLE_ESC_INT(),用于关闭和开启ESC中断。关闭ESC中断操作将会影响到ESC中断的响应。

DISABLE_ESC_INT会在以下情况被调用:

  1. 在ResetALEventMask()和SetALEventMask()中调用, 用于进入OP前的配置和状态转换过程, 正常工作后不会周期调用, 不用考虑对OP中ESC中断响应的影响。
  2. 在Freerun模式时, 在MainLoop中执行ECAT_Application()和PDO_InputMapping()前调用, Freerun模式不是推荐模式, 且在Freerun模式下本就不适用PDI和SYNC0\SYNC1中断, 所以也不考虑此情况的ESC中断响应问题。
  3. 当ECAT_TIMER_INT参数被设置成0时, 生成的协议栈代码会在MainLoop中周期执行ECAT_CheckTimer()->DC_CheckWatchdog(), 且DC_CheckWatchdog()中会有关闭和开启ESC中断的操作。

如若以上情况下周期性执行DC_CheckWatchdog()函数执行时,在关闭ESC中断和开启ESC中断之间被其他耗时的中断打断, 就会造成ESC的中断长时间处于未使能状态, 此时即使发生了PDI和SYNC0\1事件,相应中断也得不到立刻执行。

为避免以上情况, 应在SSC tool中设置ECAT_TIMER_INT = 1后生成协议栈代码,生成的代码会去掉DC_CheckWatchdog()中关闭和开启中断的操作,并将ECAT_CheckTimer()调用从MainLoop()中去掉。 此时应在在1ms tick中断中调用ECAT_CheckTimer()执行检查。 又为了避免1ms中断中执行DC_CheckWatchdog()与Sync0_Isr()/Sync1_Isr()的执行产生竞争, 需要设置1ms Timer中断的优先级 >= SYN0/SYNC1的中断优先级。

5
0

订阅

发表回复 0

Your email address will not be published. Required fields are marked *

captcha
Enter the characters shown in the image:
Reload

This CAPTCHA helps ensure that you are human. Please enter the requested characters.