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.

[参考译文] TMS320F28034:CANRML

Guru**** 2391415 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1291407/tms320f28034-canrml

器件型号:TMS320F28034

当在接收中断中读取 CANRML 寄存器时、接收信息往往会丢失。

原因是什么?

--

谢谢、此致

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    抱歉、我不理解您的问题。 您是否在问为什么信息经常丢失? 如果被启用、您要么更快地读取接收到的消息、要么用同一个 MSGID 打开更多邮箱(并且设定 OPC 位、这样消息在被读取前不被写覆盖)。 如果您是说在 ISR 中读取 CANRML 寄存器时、您不会看到该寄存器中设置的任何位、则可能是您不使用32位读取。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、当我读取  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;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Alan:

               如果您丢失了邮件,这意味着您读取邮件的速度不够快。 您的应用程序可能"忙"做"其它"事情、并且服务 CAN 接收中断的速度不够快、这可能导致消息被写覆盖、从而设置 RML 位。 有几种方法可以处理此问题:

    1. 确保在邮件到达后立即阅读(或至少在下一封邮件到达之前)。
    2. 打开应用允许的接收邮箱数量。 通过将邮箱的 OPC 位设置为1、您可以保护该邮箱不被覆盖。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢你的导游 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 上支持调试代码(或进行代码审核)。