当在接收中断中读取 CANRML 寄存器时、接收信息往往会丢失。
原因是什么?
--
谢谢、此致
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
当在接收中断中读取 CANRML 寄存器时、接收信息往往会丢失。
原因是什么?
--
谢谢、此致
是的、当我读取 CANRML 寄存器时、发现这些消息经常丢失、最后、CAN 接收 ISR 在长时间运行后会丢失。 现在、在中断函数的末尾、我添加代码为 ECanaRegs.CANRMP.All = 0xFFFFFFFF、缺少消息。
下面是我在接收到的 ISR 中的代码:
void canRX_ISR (void)
{
uint8_t len;
uint8_t 邮箱;
uint32_t 位掩码;
CANFRAME canBuff;
结构 ecan_REGS ECanaShadow;
ECanaShadow.CANGIF1.all = ECanaRegs.CANGIF1.all;
邮箱= ECanaShadow.CANGIF1.bit.MIV1;
if (ECanaShadow.CANGIF1.bit.GMIF1 == 1)
{
位掩码=((uint32_t) 1 << mailbox);
ECanaShadow.CANRMP.all = ECanaRegs.CANRMP.all;
//可以接收 ISR
if (ECanaShadow.CANRMP.All 和位掩码)
{
ECanaRegs.CANRMP.all =位掩码;
if (mailbox => CAN_MBRX_MONITOR)
{
postCanToMonitor (邮箱);
}
否则、如果(mailbox => CAN_MBRX_RXP)
{
len = pCANRxReceiveHAL (&canBuff、邮箱);
postCanToRxp (rxp_over_can、&(canBuff.CanData[0])、len);
}
else if ((mailbox >= CAN_MBRX_PARA_BEGIN)&&(mailbox <= CAN_MBRX_PARA_END))
{
postCanToParallel (邮箱);
}
否则
{
//待定
}
ECanaShadow.CANRML.all = ECanaRegs.CANRML.all;
if (ECanaShadow.CANRML.ALL &((uint32_t) 1 << mailbox))
{
#if CAN_PROTOCOL_DIAGE_ENABLED == 1
canOverWriteCount++;
#endif
}
#if CAN_PROTOCOL_DIAGE_ENABLED == 1
canReceiveCount++;
#endif
}
}
ECanaRegs.CANRMP.All = 0xFFFFFFFF;
//启用未来的 CAN (PIE 组1)中断
PieCtrlRegs.PIEACK.all = PIEACK_group9;
}
感谢你的导游 Hareesh!
现在我打开更多的邮箱20到30用于 CAN 接收,并设置 OPC 位为邮箱21到30 ,而邮箱20保持 OPC 为0 ,这是正确的应用吗?
新代码如下所示、您能帮助检查代码是否正确吗?
谢谢!
void canRx_ISR(void) { uint8_t len; uint8_t mailbox; uint32_t bitMask; CANFRAME canBuff; struct ECAN_REGS ECanaShadow; ECanaShadow.CANGIF1.all = ECanaRegs.CANGIF1.all; mailbox = ECanaShadow.CANGIF1.bit.MIV1; bitMask = ((uint32_t)1 << mailbox); if(ECanaShadow.CANGIF1.bit.GMIF1 == 1) { // CAN receive ISR if(ECanaRegs.CANRMP.all & bitMask) { if( ECanaRegs.CANRML.all & bitMask) { #if CAN_PROTOCOL_DIAGNOSE_ENABLED ==1 canOverWriteCount++; #endif } ECanaRegs.CANRMP.all = bitMask; if(mailbox == CAN_MBRX_MONITOR) { postCanToMonitor(mailbox); } else if(mailbox == CAN_MBRX_RXP) { len = pCANRxReceiveHAL(&canBuff, mailbox); postCanToRxp(RXP_OVER_CAN, &(canBuff.CanData[0]), len); } else if((mailbox >= CAN_MBRX_PARA_BEGIN) && (mailbox <= CAN_MBRX_PARA_END)) { postCanToParallel(mailbox); } else { // TBD } if( ECanaRegs.CANRMP.all & bitMask) { #if CAN_PROTOCOL_DIAGNOSE_ENABLED ==1 canOverWriteCount++; #endif } #if CAN_PROTOCOL_DIAGNOSE_ENABLED ==1 canReceiveCount++; #endif } } ECanaRegs.CANRMP.all = bitMask; // Enable future CAN (PIE Group 1) interrupts PieCtrlRegs.PIEACK.all = PIEACK_GROUP9; }
根据 TRM:
当接收到一个消息时、消息控制器开始在邮箱编号最高的邮箱寻找一个匹配的标识符。 邮箱31的接收优先级最高。 读取数据后、RMP n (RMP.31-0)必须由 CPU 复位。 如果该邮箱已经接收到第二个消息并且接收消息等待位已经被设置、那么相应的消息丢失位(RML n)(RML.31-0)将被设置。 在这种情况下、如果写覆盖保护位 OPC n (OPC.31-0)被清除、那么存储的消息将被新数据写覆盖;否则、下一个邮箱将被检查。
在您的情况下、接收到的邮件将从 Mailbox30开始存储。 由于你为所有邮箱(除了20个)设置 OPC、这些邮箱将不会被覆盖。 由于针对 MBX20的 OPC = 0、MBX 有可能被写覆盖。 只要应用服务及时收到中断、就不应发生这种情况。 我们不能在 e2e 上支持调试代码(或进行代码审核)。