feat(ethercat): 添加LAN9252睡眠挂起机制防止HBI访问冲突
添加了s_pmSuspended状态标志来管理LAN9252的电源管理模式,在芯片进入D1-D3 睡眠状态时阻止HBI访问以避免唤醒问题。同步修改了ethercat_sync中断处理程序, 在睡眠挂起期间跳过HBI相关操作确保芯片能够正常维持睡眠状态。 fix(spi): 提升SPI CS EXTI抢占优先级避免帧丢失 将SPI CS EXTI中断优先级从1提升至0,使其能够抢占PDI/SYNC1等关键中断,确 保SPI帧释放处理能够在微秒级完成,避免因延时导致的ESP32 CS间隔超时和帧 丢失问题。 feat(ssc): 实现OP输入新鲜度不变量监控机制 添加了输入映射序列号监控机制,当PDI路径中断时能够检测到输入数据冻结并 自动触发强制刷新,解决结构洞问题导致的输入数据停止更新现象。 chore(pdo): 更新PDO输入字节注释说明布局变更历史
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "comm/ethercat_sync.h"
|
||||
#include "comm/ethercat_can_bridge.h"
|
||||
#include "comm/esc_exmc_bus.h"
|
||||
#include "comm/esc_lan9252.h"
|
||||
|
||||
extern "C" {
|
||||
void MainLoop(void);
|
||||
@@ -284,6 +285,8 @@ bool TaskRunner::copyAdcSample(Adc::Sample *out)
|
||||
extern "C" uint32_t EcatDbg_ReadAlDiag(void);
|
||||
/* SSC 侧 AL Event Mask(0x204) 守护(dc_app.c, 1.5.48):缺位自愈+WARN,返回实际值/0xFFFF=不适用 */
|
||||
extern "C" uint32_t EcatDbg_GuardAleventMask(void);
|
||||
/* 1.6.33:OP 输入新鲜度不变量 — 输入 PDO 停更则主循环强制重写(根治假连接) */
|
||||
extern "C" void EcatDbg_OpInputFreshness(void);
|
||||
|
||||
/**
|
||||
* @brief 1.5.48/1.5.49 AL Event Mask(0x204) 守护 + SM2 事件楔死自愈 + 1.5.52 邮箱
|
||||
@@ -303,7 +306,9 @@ extern "C" uint32_t EcatDbg_GuardAleventMask(void);
|
||||
static void ethercatAleMaskGuard()
|
||||
{
|
||||
static uint32_t s_lastGuardMs = 0U;
|
||||
if (!EthercatSync::isActive()) {
|
||||
if (!EthercatSync::isActive() || EscLan9252::pmSuspended()) {
|
||||
/* 1.6.27:睡眠挂起期一并静默——守护内部读 SM 起止/长度与 0x204/0x220
|
||||
* 全是 HBI 访问,会把睡着的芯片叫醒 */
|
||||
return;
|
||||
}
|
||||
const uint32_t nowMs = g_scheduler.tick_1ms;
|
||||
@@ -321,7 +326,8 @@ static void ethercatAleMaskGuard()
|
||||
*/
|
||||
static void ethercatAlHeartbeat()
|
||||
{
|
||||
if (!EthercatSync::isActive()) {
|
||||
if (!EthercatSync::isActive() || EscLan9252::pmSuspended()) {
|
||||
/* 1.6.27:睡眠挂起期静默——读 0x0130/0x0220 即 HBI 访问,读即唤醒 */
|
||||
return;
|
||||
}
|
||||
const uint32_t alDiag = EcatDbg_ReadAlDiag();
|
||||
@@ -594,10 +600,19 @@ void TaskRunner::runPending()
|
||||
|
||||
/* SSC 协议栈主循环:AL 状态机 + 邮箱处理 + FreeRun PDO。
|
||||
* 每轮无条件调用,SSC 内部自行判断是否有待处理事件。
|
||||
* DC 模式下 PDO 交换由 SYNC0 ISR (Sync0_Isr) 完成,此处仅处理低优先级逻辑。 */
|
||||
MainLoop();
|
||||
* DC 模式下 PDO 交换由 SYNC0 ISR (Sync0_Isr) 完成,此处仅处理低优先级逻辑。
|
||||
* 1.6.27:ESC 睡眠(D1-D3)挂起期整段停调——MainLoop 每圈必读 0x220(AL 事件
|
||||
* 寄存器,经 HBI),而睡眠中任何 HBI 访问(含读)都会把芯片打回 D0,
|
||||
* 2026-09-12 实测休眠后 ~20s 即被"复活"。 */
|
||||
if (!EscLan9252::pmSuspended()) {
|
||||
MainLoop();
|
||||
/* 1.6.33:OP 输入新鲜度不变量。与 MainLoop 同拍调用——正常时
|
||||
* PDI_Isr 已在刷新,这里只做廉价 seq 比对;停更超 5ms 才强制重写。
|
||||
* 睡眠期与 MainLoop 一并跳过(读 HBI 会唤醒芯片)。 */
|
||||
EcatDbg_OpInputFreshness();
|
||||
}
|
||||
|
||||
/* 1.5.48:AL Event Mask(0x204) 守护——每圈入口执行,内部 1s 节流。
|
||||
/* 1.5.48:AL Event Mask(0x204) 守护——每圈入口执行,内部 250ms 节流。
|
||||
* 放 MainLoop 旁而非诊断任务:守护必须独立于诊断打印频率,
|
||||
* OP 等待期(12s)内从站进 SAFEOP 后 1s 内即介入自愈。 */
|
||||
ethercatAleMaskGuard();
|
||||
|
||||
Reference in New Issue
Block a user