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.

[参考译文] EK-TM4C123GXL:CAN FIFO 模式

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/580779/ek-tm4c123gxl-can-fifo-mode

器件型号:EK-TM4C123GXL

大家好!

我有一个正在运行的 CANopen 堆栈、我已经为其开发了 Tiva 驱动程序。 我在 Tiva Launchpad (TM4C123G)上运行它、但是、目前在不使用 Tiva 硬件 FIFO 的情况下、它可以正常工作。

我想实现硬件缓冲器、但我找不到一个好的示例。 FIFO 的配置是清零的-这是可以的、但是中断的正确处理是可以的

对我来说有点困惑。

如果我理解正确...您会在每个 FIFO 成员对象接收时获得一个 CAN 中断。 但是、重点是什么  

将 FIFO 读数置于中断例程内? (如数据表第1059页所示:图17-3. FIFO 缓冲区中的报文对象)

如果每个 FIFO 成员都收到一个中断、并且您立即读取该中断、那么 FIFO 就没有机会填满。

上面的算法清楚地显示了在 ISR 内部读取消息的情况。

这对我来说毫无意义、但很显然、我在这里遗漏了一些东西...

如果您将 FIFO 读取数据放入主循环中、或者使用另一个计时器对其进行计时、那么 FIFO 就有机会填满...但此时 IRQ 的意义是什么

对于每个 FIFO 成员(也可以在 ISR 之外读取 FIFO 成员状态)。

感谢您的回答。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    有多种方法可以使用 CAN FIFO 模式。 如果为 FIFO 中的每个报文对象启用了接收中断、那么在丢失报文之前、您可以容忍中断被禁用的时间更长。 (对我来说、具有一个中断例程的时间太长、以至于在该时间周期内会接收到两条或更多 CAN 消息、这是一个非常长的中断例程。)

    由于可以为每个报文对象配置接收中断、因此只需在最后一个报文对象上启用接收中断、即 EOB 已设置的报文对象。 当您知道某个特定 ID (或 ID 范围)总是出现在组中、并且在接收到组的最后一个 ID 之前不想处理这些消息时、这将非常有用。

    关于 FIFO 模式的一个注意事项是、如果您在另一条消息进入时从 FIFO 读取消息、则不能保证消息按顺序存储。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,Bob!

    感谢您的回答。 但我面临不同的问题:

    当 MCU 无法足够快地处理 CAN 消息时、我必须有一个"通用"FIFO 来填补空白。  

    如果我只为 FIFO 中的最后一个项目设置中断、那么如果发送方在 FIFO 填满之前停止发送消息、我可能无法获得 FIFO 内容。

    您永远不会获得最后一个 FIFO 成员的 IRQ。

    数据表中的 TI 示例令我感到困惑、我找不到任何其他好示例。  

    如果 FIFO 的每个成员都有一个 IRQ、并且每次在 ISR 中读取它、那么它不再是一个缓冲区。 它将始终仅包含一个项目。

    我可以想象的唯一方法是:

    1、每个 FIFO 成员都有 IRQ

    2.跟踪使用多少个 FIFO 元素(在 ISR 内部、使用您获得的 FIFO 成员 IRQ)。 这样、ISR 就可以快速而短。

    3.在 main()中:-定期读取 FIFO,或以应用程序允许的速度读取 FIFO,当然,在读取 FIFO 时将其释放。

      这样 FIFO 就可以发挥功能(当读出速度慢时填充,当读出速度快时几乎为空)

    我自己的想法有问题:我所掌握的每个信息都指向另一种方法:在 ISR 中读取 FIFO -包括 TI 的示例流程图。

    正如我之前所说的、这就是我在这里缺少一些重要信息的原因、这些信息是 FIFO 的实际工作方式。 我不是那么的自我主义者,认为我是对的,其他人都是错的:)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Attila、
    我认为你没有遗漏任何东西。 在我上面提到的两种用例中、已实现的 FIFO 模式可能工作良好、但它并不适合您的用例(这是一种常见的用例)。 如果接收报文的顺序不重要、那么您建议的方法是在接收每个帧时使用中断来设置标志、然后在主任务循环中检查该标志并清空 FIFO、该方法将起作用。 如果顺序很重要、那么在收到接收中断时、您可能应该使用单个消息邮箱、将数据复制到 RAM 中的循环缓冲区并递增 FIFO 头指针。 然后在主循环中、当头指针与尾指针不匹配时、您可以从循环缓冲区中处理数据、在处理每个项目时递增尾指针。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你好,Bob!
    再次感谢! 这就是我需要的。 因此、CAN FIFO 比我之前看到的任何 FIFO 都更加不同寻常-它甚至不是真正的 FIFO -但只要你不尝试以不同的方式使用它、这是可以的。 我在任何地方都无法清楚地证明我的观点。
    由于 CANopen 堆栈本身具有自己的软件 FIFO、我想我会保持简单并使用一个邮箱。 虽然我还不知道能否快速达到一些相当好的 CAN 比特率(1Mbit)而不会出现任何问题。 时间和测试将决定。

    不过、TI 自己的 Tivaware 示例对普通用户来说具有很大的误导性。 数据表也没有改进这一点。 我花了大约2周的时间,你的支持终于掌握了这个缓冲区的真实性质——我不是这些东西的初学者。 您不会错过太多内容、只是更详细的注释和/或更详细的描述-或在示例中添加一些更常见的用例。
    TI 的文档质量仍处于最高水平。

    感谢您的支持。