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.

[参考译文] MSPM0G3507:正确处理 CAN Rx

Guru**** 2614265 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1432915/mspm0g3507-handle-can-rx-correctly

器件型号:MSPM0G3507

工具与软件:

您好!

我有关于    从 中断处理程序接收 CAN RX 帧的一些问题。 (完整的 处理程序代码 包含在底部)。

该软件基于 CAN RX 的示例项目实施、它  在 FIFO 模式下运行。

   我想在您的帮助下澄清一些有点令人困惑的时刻。

首先、以下是在检查是否必要时进行的(我在 CAN Rx 的示例项目中看到过它)吗?

执行{

 DL_MCAN_getRxFIFOStatus (CANFD0、&Rx_FS);

} while (Rx_fs.filllv)=0);

我想如果我们收到 Rx 事件、则 Rx    FIFO 中已经存在消息、我无需轮询该消息。

其次。 如果 FIFO 中有多条消息被缓存、那么正确的读取方式是什么?

目前我只是这样做:


执行{
 DL_MCAN_readMsgRam (CANFD0、DL_MCAN_MEM_TYPE_FIFO、0U、rx_fs.num、&rx_msg);
 DL_MCAN_writeRxFIFOAck (CANFD0、Rx_fs.num、Rx_fs.getIdx);

 对于(int i = 0;i < rx_msg.dlc;i++){
  FRAME[i]= rx_msg.data[i];
 }
 can_rx_handler (rx_msg.id、frame、rx_msg.dlc);//处理接收的帧

 DL_MCAN_getRxFIFOStatus (CANFD0、&Rx_FS);
} while (RX_FS.LVL fill>0);

下面是处理程序的完整代码片段:

void CANFD0_IRQHandler (void){ 
uint32_t intr_status;
DL_MCAN_RxFIFOStatus Rx_FS
DL_MCAN_RxBufElement Rx_msg
uint8_t FRAME[8]

开关(DL_MCAN_getPendingInterrupt (CANFD0)){
案例 DL_MCAN_IIDX_LINE0
INTR_STATUS = DL_MCAN_getIntrStatus (CANFD0);
DL_MCAN_clearIntrStatus (CANFD0、intr_status、DL_MCAN_INTR_SRC_MCAN_LINE_0);

if ((intr_status 和 MCAN_IR_RF0N_MASK){
RX_FS.num = DL_MCAN_RX_FIFO_NUM_0
//等待消息位于 FIFO 中
执行
DL_MCAN_getRxFIFOStatus (CANFD0、&Rx_FS);
} while (Rx_fs.filllv)=0)

//读取 FIFO 为空
执行
DL_MCAN_readMsgRam (CANFD0、DL_MCAN_MEM_TYPE_FIFO0U、rx_fs.num、&rx_msg);
DL_MCAN_writeRxFIFOAck (CANFD0、Rx_fs.num、Rx_fs.getIdx);

对于(int i = 0;i < rx_msg.dlc;i++){
FRAME[i]= rx_msg.data[i]
}
can_rx_handler (rx_msg.id、frame、rx_msg.dlc);//处理接收的帧

DL_MCAN_getRxFIFOStatus (CANFD0、&Rx_FS);
} while (RX_FS.LVL fill>0);
}

if (intr_status 和 MCAN_IR_BO_MASK){
DL_MCAN_setOpMode (CANFD0、DL_MCAN_OPERATION_MODE_NORMAL);
}
休息

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

    让我来看看、但出于好奇、您现在是否测试过您的代码?

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

    当然我已经对它进行了测试。 这是可行的、但当我通过发送和接收尽可能多的 CAN 消息来对器件进行压力测试时、有时在执行检查时似乎会卡住、我问您:

    执行{

     DL_MCAN_getRxFIFOStatus (CANFD0、&Rx_FS);

    } while (Rx_fs.filllv)=0);

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

    它是否与 FIFO 过载有关? 我们之前已经对示例代码进行了应力测试、运行良好。

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

    您好!

    我不确定过载是什么意思。 如果您的意思是 RX FIFO 已满、则不应将 RX_FS.LVL fillbe 格式设置为大于0并且不会导致死锁?

    至于示例代码、它可以很好地工作、因为 CPU 利用率很低、因此可以快速读取 CAN 消息、而 Rx FIFO 永远不会填满。

    我尝试 确保不会 发生的临界情况是、当 CPU 还在处理其他更高优先级的事情、并且无法足够快地读取 CAN 消息时。  当它最终能够处理 CAN Rx 处理程序时、CAN Rx FIFO 可以满。 想象一下、我们读出1条 CAN 消息、而在处理这条消息时、我们在 FIFO 中收到另一条 CAN 消息、FIFO 中却装满了。 然后我们完成 对 CAN 消息的处理、并退出处理程序。 但由于 Rx FIFO 已满、因此我们 可能不会收到另一个 Rx 中断、或者我们在调用后仅读出一条消息(而 其他 FIFO 消息 尚未处理)。 我正在尝试确保在退出 CAN Rx 处理程序之前、我读出了 Rx FIFO 中的所有消息。 然后、我确信我处理了所有这些问题、并且没有任何东西会保持缓冲状态。

    在示例代码中、我们只读出1条 Rx 消息、我们在检查 我所询问的问题时使用该消息。

    您是否同意我的看法、即示例代码不包括我尝试解决的临界情况? 如果是、我应该如何实现 Rx 处理程序以正确实现它?

    我希望我的 阐述是 有意义的。

    此致、

    Mykola

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

    你好。 您是否有机会查看我的消息? 很遗憾、我们在 CAN Rx 处理程序方面仍然存在问题。 您是否能够建议如何  正确实现处理程序以正确使用 硬件  FIFO?