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.

[参考译文] CAN 模块故障

Guru**** 2434370 points
Other Parts Discussed in Thread: TMS320F28374D, CONTROLSUITE, C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/934250/can-module-problem

Thread 中讨论的其他器件:TMS320F28374DcontrolSUITEC2000WARE

最近、我们更改了 TMS320F28374D 的 CAN 配置、以使用200MHz 外设时钟使用1Mbps 波特率。

 

现在、我们使用了 TExaS API 来初始化 CPU1和 CPU2中的 CAN 外设。 Moore、我们完全调用了函数

 

CANBitRateSet (GST_CAN[e_CANPort].u32_CANAddrBase、200000000L、1000000L);

 

通过这种方式、CAN 速率自动设置、使用19 (实数19+1)的时钟预分频器和以下参数(红色)

 

tatic const uint16_t g_ui16CANBitValues []=

   0x1100、// TSEG2 2、TSEG1 2、SJW 1、除以5

   0x1200、// TSEG2 2、TSEG1 3、SJW 1、除以6

   0x2240、// TSEG2 3、TSEG1 3、SJW 2、分频7

   0x2340、// TSEG2 3、TSEG1 4、SJW 2、8分频

   0x3340、// TSEG2 4、TSEG1 4、SJW 2、9分频

   0x3440、// TSEG2 4、TSEG1 5、SJW 2、10分频

   0x3540、// TSEG2 4、TSEG1 6、SJW 2、分频11

   0x3640、// TSEG2 4、TSEG1 7、SJW 2、12分频

   0x3740 // TSEG2 4、TSEG1 8、SJW 2、分频13

};

 

然而、一旦发送单元连续发送4条消息、彼此相差1uec、有时 DSP 丢失了1条消息。

CAN 队列是14个消息的深度、因此我们没有解释我们为什么要面临这一问题。

 

可以帮帮我们吗?

 

P.S.按照 mana 中的示例、我们已经尝试将配置寄存器设置为0x0700而不是0x3440、但问题仍然存在。 有时 DSP 不会收到消息。

 

感谢你的帮助、

Andrea Marcianesi。

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

    [引用]但是、一旦发送单元连续发送4条消息、彼此相差1uec、有时 DSP 丢失了一条消息。 [/报价]

    28374D 是接收器吗?

    [引述] CAN 队列的消息深度为14、因此我们不解释我们为什么要面临这一问题。 [/报价]

    您是否使用 FIFO 模式?

     

    请解释您的设置。 有多少个节点? 谁将传输给谁?

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

    您好、 Haresh、

    以下是我们的反馈:

    • CAN 网络由以下节点组成:
      • 28374D 内核1
      • 28374D 内核2.
      • Cortex M MCU
    • 28374D 使用 FIFO 模式来实现 CAN RX。
    • 在所描述的序列中、Cortex M 作为发送器工作、而28374D 内核1作为接收器工作。

    请随意询问其他详细信息。

    此致、

    Andrea  

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

     在 SPRZ412L 中、有一个项目"在 DCAN FIFO 模式期间、接收到的消息可能会在 FIFO 缓冲区中按顺序放置"。 我想知道你看到的是不是这种情况的表现。 您能否提供一些统计信息? 即、在您看到丢失的帧之前、将经过多少帧?

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

    在我们的情况下、丢失的帧实际上不会出现在 FIFO 中、因此这似乎不是一个失序问题。  

    在我们的测试期间、我们估计发送的消息的丢失率约为1-3%。

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

    安德烈

                   我有点困惑、为什么您在第一个帖子中处理不同的 CANBTR 值。 位时序值与"缺失"帧没有关联。 时序方面的任何问题都会立即表现为错误帧。 在100帧之间丢失帧不能是位时序问题。  

    您似乎只有两个节点、我假设您的总线长度相当短、并且总线已正确终止(请下载应用报告 http://www.ti.com/lit/sprace5 并查看提供的调试提示)。  

    我假设您已连接 CAN 总线分析仪、它会跟踪传输的帧数。 换言之、您可以确定"丢失"的帧确实在总线上传输。

    1. 您是否使用接受屏蔽过滤(从而接受多个消息 ID)?
    2. 或者、它是不是一遍又一遍地传输的相同 MSGID?
    3. 您是更改接收邮箱的 MSGID 还是在整个过程中都相同?
    4. 如果不使用 FIFO 模式、问题是否消失?
    5. 您的 CANBTR 值是多少?
    6. 您使用什么时钟源?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Hareesh、

    我将尝试预测一些解释、我负责此问题的同事将快速添加更多详细信息:

    • 您说我们只有2个节点、但我已经指定它们实际上是3个节点(即每个 DSP 内核1个 CAN 节点+ Cortex M 1个 CAN 节点)。
    • 我们非常确信丢失的 CAN 帧能够通过线路正确传播、因为我们在接收器节点(28374D 内核1)的 CAN RX 引脚上监控了数字信号。 下图显示了 ID 为0x1D210008的丢失帧、该帧由我们的总线分析器以及连接到总线(P-CAN)的外部监听器正确解码。

    到达 CAN RX 的帧看起来是正确的、但它仍然在 RX FIFO 中丢失、这就是我们认为外设时序配置错误的原因(即、CAN 传播时隙大小错误可能导致位采样错误)。

    总之、这只是我们的假设。

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

    早上好、Haresh、

    随附后、您将找到一个包含 CAN 配置的文本文件、适用于 CPU1和 CPU2。

    这将回答您的大部分问题。

    一些说明:

    1) 1)我们没有尝试删除 FIFO 模式:这是一项需要付出一定努力的测试、但目前我们没有时间。

    2) 2)时钟源是一个外部20Mhz 振荡器、我们在许多不同的其他项目中使用、采用相同的配置、因此我将排除这样的问题。

    非常感谢您的帮助、

    Andrea Marcianesi。

    e2e.ti.com/.../7357.CANerror.txt

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

    我很遗憾、通过查看您发送的代码片段、我无法找到我的问题的答案。 请提供1、2、3和5的答案。 您可以通过查看 CCS 中的 CANBTR 寄存器值来回答5。

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

    尊敬的 Hareesh:

    遗憾的是,为了设置所有 CAN 寄存器的值,我们使用了德州仪器(TI)的驱动程序 LIB,因此我们基本上不直接设置寄存器的值。 此外、在 CCS 8.1中、我们无法在调试窗口中看到这些寄存器的值。 因此、我们唯一需要查看这些寄存器值的方法是定义全局变量或读取代码。

    总之、以下是您的问题的答案:

    1. 您是否使用接受屏蔽过滤(从而接受多个消息 ID)?

            否 我们将 msg.ID 设置为 tro 0。

    1. 或者、它是不是一遍又一遍地传输的相同 MSGID?

          在 CAN 上、MSGID 被取消。

    1. 您是更改接收邮箱的 MSGID 还是在整个过程中都相同?

           我们不更改接收邮箱的 MSGID

    1. 如果不使用 FIFO 模式、问题是否消失?

           我们没有尝试过,因为这需要更改代码,而现在我们没有资源来更改代码。

    1. 您的 CANBTR 值是多少?

           我们使用 TI 驱动程序库函数 CANBitRateSet 来设置 CANBTR r3egister、使用以下调用

    CANBitRateSet (GST_CAN[e_CANPort].u32_CANAddrBase、200000000L、1000000L);

    读取 TI 函数时、应设置以下值

    0x3440、// TSEG2 4、TSEG1 5、SJW 2、10分频

    按照这种方式、CAN 速率自动设置、使用19 (实数19+1)的时钟预分频器获取以下数组中的值

    静态常量 uint16_t g_ui16CANBitValues []=

       0x1100、// TSEG2 2、TSEG1 2、SJW 1、除以5

       0x1200、// TSEG2 2、TSEG1 3、SJW 1、除以6

       0x2240、// TSEG2 3、TSEG1 3、SJW 2、分频7

       0x2340、// TSEG2 3、TSEG1 4、SJW 2、8分频

       0x3340、// TSEG2 4、TSEG1 4、SJW 2、9分频

       0x3440、// TSEG2 4、TSEG1 5、SJW 2、10分频

       0x3540、// TSEG2 4、TSEG1 6、SJW 2、分频11

       0x3640、// TSEG2 4、TSEG1 7、SJW 2、12分频

       0x3740 // TSEG2 4、TSEG1 8、SJW 2、分频13

    };

    1. 您使用什么时钟源?

    是一个外部20Mhz 振荡器、已在我们的项目中使用。 我们在内部为 CAN 模块使用200MHz 源。

     

    此致、

    Andrea Marcianesi。

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

    很抱歉我不明白。 您已使用14个报文对象配置了14级 FIFO。 您说您不使用过滤,并且您不更改接收邮箱的 MSGID。 假设接收邮箱的 MSGID 为0x1D210008、并且永不更改。 但您也会说" MSGID 在 CAN 上是不同的"。 这话什么意思?  

    CANBTR 寄存器是一个32位寄存器。 您可以使用 View->Registers 选项轻松查看寄存器的值。

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

    “很抱歉我不明白。 您已使用14个报文对象配置了14级 FIFO。 您说您不使用过滤,并且您不更改接收邮箱的 MSGID。 假设接收邮箱的 MSGID 为0x1D210008、并且永不更改。 但您也会说" MSGID 在 CAN 上是不同的"。 这话什么意思? "

    我是说 Cortex 发送的消息 ID 不是固定的。 它通过总线发送多条具有不同 ID 的消息。 DSP 没有掩码 ID、因此 IR 接收所有这些消息。 它没有接受屏蔽、被设置为接收所有 m、essages。

    " 您可以使用 View->Registers 选项轻松查看寄存器的值。"  

    实际上、在 CCS 8.1中、该选项不起作用。

    顺便说一下 、CANBTR 设置为 0x3440。

    此致、

    Andrea MArcianesi。

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

    好的。 当您说您不使用接受屏蔽滤波时、我感到困惑。 当接收 MBX 的 MSGID 是固定的并且它只接受那个 ID 时、就会出现这种情况。 在本例中、您确实使用了接受屏蔽。 但是、您已将所有位配置为"无关"、以便接收到任何 MSGID。

    您能描述一下如何处理消息接收吗? 我假设您在 FIFO 被填满时生成一个中断?

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

    更多问题:

    1. 您是否注意到 CANES 寄存器中设置了任何位(与错误相关)?
    2. 是否有可能"丢失"消息被新消息覆盖? 也就是说、消息确实已被接收、但在可以读取之前被覆盖了吗? 是否监控 MsgLst 位?
    3. 如果降低比特率、您是否会看到问题?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Haresh、

    在下面、我的回答是、

    您能描述一下如何处理消息接收吗?

    我们在主周期中对 FIFO 进行轮询、在最坏的情况下每600uec 一次(在大多数情况下、我们能够更快地对 FIFO 进行轮询)。

    在此过程中、我们清空所有邮箱。

    我假设您在 FIFO 被填满时生成一个中断?

    不、我们在主要 cyclie 中对 FIFO 进行轮询。

    您是否注意到 CANES 寄存器中设置了任何位(与错误相关)?

    没有、我们没有。 该消息不在 FIFO 中、即它。 CCS 8.1中的寄存器视图不起作用这一事实对我们没有帮助。

    是否有可能"丢失"消息被新消息覆盖? 也就是说、消息确实已被接收、但在可以读取之前被覆盖了吗?

    由于要填充14个邮箱 FIFO @1Mbps、因此无法实现最大600uS 的轮询周期。 此外、发送消息的 Cortex 会立即停止、如果 DSP 没有应答、则我们会冻结 DSP 中的 FIFO 和 FIFO、当我们散出消息时、这些 FIFO 没有满。

    是否监控 MsgLst 位?

    我们轮询 CAN_NDAT_21寄存器位。 在该寄存器中有一个位置位、我们读取相应邮箱中的消息。

    如果降低比特率、您是否会看到问题?

    我们没有尝试。 我们应该降低 DSP 和 Cortex 应用上的比特率、这样我们就不会尝试了。

    Andrea

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

    安德烈

    [引用]但是、一旦发送单元连续发送4条消息、彼此相差1微秒、有时 DSP 丢失了一条消息。[/引用]  

    您能解释一下"彼此相差1微秒"吗? 每帧之间的间隔是否为1us? 您已在以1Mbps 的速率传输数据。 每帧之间至少有一个11位隐性周期。 这1我们是从哪里来的? 这是否意味着您的总线负载为100%?  

    [引用]我们在主周期内轮询 FIFO、在最坏的情况下每600uec 一次(在大多数情况下、我们能够更快地轮询 FIFO)。 [/报价]

    您到底是如何轮询的? 假设平均长度为120位/帧、对于14帧、它大约为1680位、因此我们将查看1.68ms 以填充缓冲区(这些是非常近似的计算;我忽略填充位、IFS 等的影响)。 您提到您每隔600us 轮询一次 FIFO "最坏情况"。 "最坏情况"是什么意思? 您是否有一个每600us 生成一个轮询请求的 CPU 定时器中断?  

    [引用]无法通过电子方式填充14个邮箱 fifo @1Mbps、因此不能使用最大600uSec 的轮询周期。[/引用]

    根据我上面的计算、填充 FIFO 至少需要1.68ms。 既然您每隔600us 轮询一次 FIFO、您是否说 FIFO 不会溢出? 如果是、我是否可以说 FIFO 永远不会满、因为您每600us 轮询一次并清空一次?  

    [引用]此外、发送消息的 Cortex 会立即停止、如果 DSP 没有应答、那么我们会冻结 DSP 中的 FIFO 和 FIFO、当我们释放消息时、消息没有满。

    请澄清"没有回答"。 您是指 DCAN 生成的 ACK 吗? 也就是说、如果 MCU 没有从 Cortex ACK 帧、Cortex 会立即停止发送消息?  

    [引用]我们轮询 CAN_NDAT_21寄存器位。 在该寄存器中有一个位置位、我们读取相应邮箱中的消息。

    很抱歉、我无法理解您在这里想说什么。 请澄清。

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

    您好!

    我要重复以下几点:

    1. 然而、一旦发送单元连续发送4条消息、彼此相差1微秒、有时 DSP 丢失了1条消息。 >>这是我们的错误:故障序列中的帧间时间实际上约为14us (注意、这实际上是丢失帧之前的帧间时间)。 请在我之前的帖子中检查示波器快照。
    2. 请澄清"没有回答"。 您是指 DCAN 生成的 ACK 吗? 也就是说、如果 MCU 没有从 Cortex ACK 帧、Cortex 会立即停止发送消息? >>不是更复杂的情况:Cortex CAN 客户端实际上发送一个由4个帧组成的序列、形成一个单一协议数据包;如果 CAN RX 上丢失了1个或多个数据包帧、DSP 会丢弃数据包、不会向 Cortex 发送应答。

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

    您是否正在使用 IF3寄存器集?

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

    没有 Hareesh、我们不使用 IF3。

    "最坏情况"是什么意思? 您是否有一个每600us 生成一个轮询请求的 CPU 定时器中断?  

    不、我们每600us 传递一次相同的主点、因此在主函数中轮询 FIFO 的函数每600uec 执行一次。

    如果是、我是否可以说 FIFO 永远不会满、因为您每600us 轮询一次并清空一次?  

    是的

    您到底是如何轮询的?  


    我们轮询 CAN_NDAT_21寄存器位。 在该寄存器中有一个位置位、我们读取相应邮箱中的消息。

     

    Andrea

     

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

    安德烈

      最好将讨论脱机。 我已经通过 e2e 向您发送了友谊请求。 请接受、让我们为致电/WebEx 而努力。

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

    您好、Haresh、

    在 WebEx 上的电话之后、我想澄清一些要点:

    • 由于您假设帧丢失时没有来自 DSP 节点的 ACK、因此您能否确认接收器节点发送 ACK、而不管在移动设备上设置了接受屏蔽? 换言之:如果一个有效的 CAN 帧被接收、但是它的消息 ID 与接受屏蔽不匹配、那么在总线上发送 ACK?
    • 是否可以指定可以监视 MsgLost 标志的寄存器?

    提前感谢。

    Andrea

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

    安德烈

    [引用]由于假设帧丢失时没有来自 DSP 节点的 ACK、[/引用]

    是的、可以想象目标 CAN 节点没有 ACK (出于任何原因)。 但是、请记住、ACK 始终来自其他 CAN 节点和/或 CAN 总线分析仪。 如果没有节点提供 ACK、则发送节点将一直重复传输该帧。

    [报价]您能否确认接收器节点是否发送 ACK、而不考虑  在移动设备上设置的接受屏蔽? [/报价]

    是的。 我在应用报告(http://www.ti.com/lit/sprace5)的第3.1节中对此进行了清晰的解释

    [引用]换句话说:如果接收到有效的 CAN 帧、但其消息 ID 与接受屏蔽不匹配、则在总线上发送 ACK? [/报价]

    是的。

    [报价]是否可以指定可以  监视 MsgLost 标志的寄存器? [/报价]

    这可以通过 CAN_IF1MCTL 寄存器使用邮箱的 MsgLst 位进行监控。 但是、我确实怀疑帧是否被覆盖。 您的 FIFO 深度为14、在读取和清空 FIFO 之前、它很少被填满到4个以上。 您可以尝试以下操作:在读取 FIFO 的例程中切换 GPIO 引脚。 使用示波器、测量读取之间的最长时间间隔。

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

    Godd Hareesh 之夜

    这里是我们在意大利进行的一些测试的结果。

    在测试中、我们不会将 CAN 总线用于 Booster (CPU2)、这样、只有 Cortex 和逆变器(CPU1)在 CAN 总线中进行通信。 这样、只有逆变器才能向来自 Cortex 的消息提供 ACK。

    在 CPU1中、我们在进入 FIFO 轮询例程之前升高一个引脚、然后在退出例程并清空 FIFO 时降低该引脚。

    结果随附:蓝线表示由 Cortex 在 CAN 总线上发送的报文:3条报文的有效载荷为8字节、最后一条报文的有效载荷为6字节。

    黄线表示 FIFO 的轮询:您可以看到 FIFO 的轮询速度足够快、 但不幸的是,问题仍然存在,我们在 FIFO 上丢失了一条消息,因此 DSP 不会应答四条消息的序列,Cortex 进入超时状态并停止发送消息,我们可以冻结 DSP 上的 FIFO 状态,以便我们可以对其进行分析。

    更多信息:

    出现问题时、0x48004处的寄存器 CAN_BTR 设置为0x3453;

    0x4810C 处的寄存器 CAN_IF1MCTL 设置为0x0186

    错误为0x0018后、位置0x48004处的寄存器 CAN_ES 在第一次读取后变为0x0007

    错误为0x0000后、CAN_ERRC 位于0x48008处

    希望 明天我们将尝试降低波特率。

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

    您好、Haresh、

    我还尝试将 CAN 速率降低到1Msps、但问题仍然存在、我们会丢失来自 Cortex 的消息。

    但问题肯定不是问题所在:让我解释一下发生了什么。

    如果我们轮询 FIFO、当我们收到一系列消息时、就像我昨天所附图片中的情况一样、我们遇到了丢失一条消息的问题。

    如果我们收到所有4条消息、然后轮询 FIFO、那么我们就没有问题了。 我制作一个 DSP CPU1逆变器版本、每3毫秒轮询 FIFO。

    由于 Cortex 每500ms、@1Mbps 发送这4条消息、因此我们基本上不会在接收数据时轮询 FIFO。 这样我们就不会

    丢失消息。

    情况如下图所示

    显然、这不是解决方案、而只是一个测试、证明我们在接收邮件时轮询 FIFO 时出错。 基本上在接收例程中。 这不是物理问题或初始化问题。

    我附加了我们的接收例程(请参阅 code.c),我的假设是,当我们调用函数 CANMessageGet ()时会出现问题,该函数是德州仪器的 driver_lib 的一部分。 如果您可以阅读代码、我会留下一些注释、让您了解情况。

    那么问题是,如果我们在执行函数 CANMessageGet 时收到新消息,会发生什么情况?

    我认为在接收标志位和消息位之间可能会有一些严重的竞争、这可能导致消息丢失。

    这种情况下、您可以自行轻松重现:在接收消息帧时、持续发送消息帧并调用 CANMessageGet driver_lib 函数。 您将看到您可能会丢失一些 FIFO 消息。

     

    我认为这可以解决,因为对五国的民意调查和他的倒出似乎需要原子。

    此致、

    Andrea Marcianesi。

    在下面、我要附加的代码、但我看不到、因此我在下面报告了

    //这是我们调用的函数,用于轮询 main 中的接收 FIFO
    void Orion CAN_TxRx (void)

    //uint16_t * buffer_tmp;
    //这是清空 FIFO 的时间,您可以看到我们调用 funion CAN_Rx_orion(),直到函数 U16_CAN_RxAvailable()返回 true
    //函数 CAN_Rx_Orion ()包含一个"返回((CANStatusGet (GST_CAN[e_CANPort].u32_CANAddrBase、CAN_STS_NEWDAT)& RX_MAILBOL_FLAGS)!= 0);"。
    //所以,这基本上是我们清空 FIFO 的时间,因为我们一直呆在这里,直到收到要分析的消息。
    while (U16_CAN_RxAvailable (e_CAN_A))

    CAN_RX_Orion (e_CAN_A、&msg_id、msg_buffer、&msg_len);

    dataMw_powercom_CAN_FRAME_t CAN_FRAME ={
    .id.ID = msg_id、
    .PAYLOAD.p=(void *) msg_buffer、
    .PAYLOAD.SIZE = msg_len
    };

    CAN_FRAME.PAYLOAD.SIZE =(msg_len >> 1);
    dataMw_powercom_rx_CAN_frame ((st_dataMw_powercom_t*) dataMw_powercom_instance_get ()、&CAN_frame);

    if (U16_CAN_TxAvailable(e_CAN_A)=true)

    秘书长的报告
    //********* 斯沃托拉科达
    秘书长的报告

    dataMw_powercom_CAN_FRAME_t * CAN_FRAME = dataMw_powercom_TX_CAN_FRAME ((st_dataMw_powercom_t*) dataMw_powercom_instance_get ());
    if (CAN_FRAME!=空)

    //buffer_tmp =(uint16_t*) CAN_FRAME->PAYLOAD.p;
    MSG_id = CAN_FRAME->ID.ID;
    MSG_Len = CAN_FRAME->PAYLOAD.SIZE;


    CAN_Tx_Orion (e_CAN_A、msg_id、(uint16_t*) CAN_frame->PAYLOAD.p、(msg_len << 1));



    //我认为问题在函数 CAN_Rx_Orion 内部,更确切地说在函数 CANMessageGet ()中。
    //Somehow 如果出现新消息,在我们执行函数 CANMessageGet ()时,我们会释放此消息。

    void CAN_Rx_Orion (e_CAN e_CanPort、uint32_t * pu32_DestMsgId、uint16_t * pu16_DestDataBuffer、uint32_t * pu32_MsgLen)

    //#ifdef CPU1
    uint32_t u32_RxFlags;
    uint16_t i;
    uint16_t u16_Mailbox;
    uint16_t pu16_TmpRxBuffer[8];

    u32_RxFlags = CANStatusGet (GST_CAN[e_CANPort].u32_CANAddrBase、CAN_STS_NEWDAT)>> 1;
    u32_RxFlagBuffer[索引]=u32_RxFlags;
    if (index++==20)
    索引= 0;
    对于(I = 0;I < CAN_RX_FIFO_LEN;I++)

    U16_Mailbox = CAN_RX_START_ADDR + I;
    if (((u32_RxFlags &(1 << I))!= 0)
    中断;//Primo 元件验证 nella FIFO

    GST_CAN[e_CanPort].st_RxMsgObj->pucMsgData =(无符号字符*) pu16_TmpRxBuffer;
    CANMessageGet (GST_CAN[e_CanPort].u32_CandrBase、U16_Mailbox、GST_CAN[e_CanPort].st_RxMsgObj、true);

    /*
    * Rx 缓冲区是字对齐的;我们需要在字中转换 CAN 消息
    *对齐数组
    ***/
    __byte (((int*)&pu16_DestDataBuffer[0],0)=pu16_TmpRxBuffer[0];
    __byte (((int*)&pu16_DestDataBuffer[0],1)=pu16_TmpRxBuffer[1];
    __byte (((int*)&pu16_DestDataBuffer[1],0)=pu16_TmpRxBuffer[2];
    __byte (((int*)&pu16_DestDataBuffer[1],1)=pu16_TmpRxBuffer[3];
    __byte (((int*)&pu16_DestDataBuffer[2],0)=pu16_TmpRxBuffer[4];
    __byte (((int*)&pu16_DestDataBuffer[2],1)=pu16_TmpRxBuffer[5];
    __byte (((int*)&pu16_DestDataBuffer[3],0)=pu16_TmpRxBuffer[6];
    __byte (((int*)&pu16_DestDataBuffer[3],1)=pu16_TmpRxBuffer[7];


    *pu32_DestMsgId = GST_CAN[e_CanPort].st_RxMsgObj->ui32MsgID;
    *pu32_MsgLen = GST_CAN[e_CanPort].st_RxMsgObj->ui32MsgLen;
    //#endif

    e2e.ti.com/.../7144.code.c

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

    [引用]在 CPU1中、我们在进入 FIFO 轮询例程之前升高一个引脚、然后在退出例程并清空 FIFO 时降低该引脚。

    假设第一个波形中的黄色信号是在进入 FIFO 并退出 FIFO 之前切换的 GPIO 引脚。 捕获中的脉冲宽度不仅不同(我看到3种不同的脉冲宽度)、而且我看到切换以不同的速率发生、最小间隔小于200us。  

    [引用]我还尝试将 CAN 速率降低到1Msps、但问题仍然存在、我们会丢失 Cortex 的消息。[/引用]

    假设您想说500kbps、而不是1MSPS。  

    [引述]如果我们轮询 FIFO、当我们收到一系列消息时、就像我昨天所附图片中的情况一样、我们会遇到一条消息丢失的问题。 [/报价]

    这是一个有趣/重要的观察结果。  

    [引用]由于 Cortex 每500ms、@1Mbps 发送这4条消息、因此我们基本上不会在接收数据时轮询 FIFO。 这样、我们就永远不会丢失消息。 [/报价]

    由于来自 Cortex 的通信是异步发生的、因此如何确保代码在传输过程中绝对不轮询 FIFO?  

    此外、您还需要用中断替换轮询。 假设您在 FIFO 的最后一个邮箱被填满时生成一个中断,并在 cortex 的下一次传输开始之前对其进行服务,这是否能避免这种情况?

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

    早上好、Haresh、

    在下面的回答中。

    '我假设第一个波形中的黄色信号是在进入 FIFO 并退出 FIFO 之前被切换的 GPIO 引脚。 捕获中的脉冲宽度不仅不同(我看到3种不同的脉冲宽度)、而且我看到切换以不同的速率发生、最小间隔小于200us。 "

    是的、我在之前的电子邮件中写道:"黄线表示 CAN FIFO 的轮询:您可以看到、我们对 FIFO 的轮询速度足够快、 但不幸的是,问题仍然存在,我们在 FIFO 上丢失了一条消息,因此 DSP 不会应答四条消息的序列,Cortex 进入超时状态并停止发送消息,我们可以冻结 DSP 上的 FIFO 状态,以便我们可以对其进行分析。”

    假设您想说500kbps、而不是1MSPS。  

    是的。

    由于来自 Cortex 的通信是异步发生的、因此如何确保代码在传输过程中绝对不轮询 FIFO?  

    当然、我不确定、但我不可能在500 μ s 长的4条消息流中对 FIFO 进行2次轮询。 在本例中、我们一整天都没有遇到任何问题。 在我所附的第一张图片中、您可以看到我们在消息流式传输期间至少轮询 FIFO 2次、几秒钟后我们就会遇到问题。 我认为这意味着问题在于我们如何管理 FIFO、不能进行波特率配置或物理层错误等。

    此外、您还需要用中断替换轮询。 假设您在 FIFO 的最后一个邮箱被填满时生成一个中断,并在 cortex 的下一次传输开始之前对其进行服务,这是否能避免这种情况?

    我们决定尝试在计时器中断内轮询 FIFO。 实际上、我们有一个在 CPU1中运行的10kHz 计时器中断、但在这种情况下、我们不确定主周期中轮询路由的速率。 正如您在第一张图片中看到的、没有必要这样做、因为在出现错误的情况下、我轮询 FIFO 的速度足够快:软件中的 FIFO 长度从未克服收到3条消息、因此我确信我从未收到过任何书面消息。 此外、物理层不会显示错误、因为我向您写入了错误消息、它们是干净的。 因此、在中断中对 FIFO 进行轮询的测试毫无意义。

    我们可以尝试生成 FIFO 满中断、但我看到这样做有很多问题:

    1) 1) DSP 仅在 FIFO 满时才会应答:我们有协议消息长1个 CAN 消息、2个 CAN 消息、4个 CAN 消息、很难确定正确的长度。 假设我们将长度固定为4条 CAN 消息、DSP 将在 FIFO 为4之前不会应答、如果 cortex 发送协议消息2 CAN 消息的长度、DSP 将不会应答?

    2) 2)无法为我们引入通信中断:我已经告诉您、中断专用于需要准确调度的控制。 我们绝不会将中断用于通信目的。

    3) 3)我问您的同一个问题:由于来自 Cortex 的通信异步发生、如何确保您的代码在 从 cortex 开始下一次传输之前完全为中断提供服务? Cortex 和 DSP 之间没有握手。

    4) 4)假设您设置好了所有内容、并且软件正常工作:下一步是什么? 您可以了解问题在哪里? 我已经为您提供了一个简单的配置、使我们能够了解问题的位置。 如果您认为无法通过实际解决方案解决此问题(我们已经有4个产品使用此解决方案)、我们必须更改协议。

    我想避免深入了解  德州仪器的 driver_lib 中的函数 CANMessageGet、但对我来说、这是下一步。

    我查看德州仪器的最后一个驱动程序库版本、将我们使用的 CANMessageGet 软件与最新的 driver_lib 版本进行比较。 令我惊讶的是,当我们开始使用 driver_lib 时,软件位于文件夹下

    C:\ti\controlSUITE\device_support\F2837xD\V210\F2837xD_common\driverlib、

    现在它在下面  

    C:\ti\c2000Ware_3_02_00_00\device_support\f2837xd\common\de弃 用\driverlib

    函数 CANMessageGET()的实现没有改变,但您能解释一下“已弃用”的含义吗?

    感谢您的支持、

    此致、

    Andrea Marcianesi。

     

    P.S. 另一个问题:您是否了解如何在寄存器视图或 CCS 8.3.1调试器的存储器映射中读取 CAN 寄存器? 我想知道,谢谢。

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

    Andrea

    关于您对已弃用的 driverlib 的问题、这意味着我们不再对这些驱动程序执行更新、因此不建议在任何新开发中使用这些驱动程序。 我们有一个新的驱动程序库、我们将在 以下位置提供支持:C:\ti\c2000\C2000Ware_3_02_00_00\driverlib\f2837xd

    此致

    Chris

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

    安德烈

    我们将更详细地介绍 Driverlib 函数。 我们可以在下一次通话中讨论以下内容、因为这样做会更快。

    为什么第一幅图像中的脉冲宽度不同?

    第1个脉冲-这非常窄。 我认为这是因为 FIFO 是空的、所以没有需要读取的内容、代码很快就退出了 FIFO 读取例程。

    第2个和第3个脉冲-为什么它们这么宽、因为可能 FIFO 在这里仍然是空的? 为什么启动的 FIFO 读取如此接近先前的读取? 即< 200us? 谁/什么启动 FIFO 读取?

    第4个脉冲-当实际读取 FIFO 时、这是正确的脉冲宽度吗?  

    [引述]当然、我不确定、但我不可能在有4条500 μ s 长消息流的情况下对 FIFO 进行2次轮询。 在本例中、我们一整天都没有遇到任何问题。 在我所附的第一张图片中、您可以看到我们在消息流式传输期间至少轮询 FIFO 2次、几秒钟后我们就会遇到问题。 [/报价]

    这是否意味着只有在*轮询两次*时才会出现问题? 也就是说、当 FIFO 被填满时、如果您轮询一次、没有问题?

    [引用]我认为这意味着问题在于我们管理 FIFO 的方式、而不是 CAN 波特率配置、物理层错误等。 [/报价]

    完全同意。

    [引述]因此、我们在中断中对 FIFO 进行轮询的测试毫无意义。 [/报价]

    FIFO 是否始终一次读取和清空4条消息? 也就是说、当您轮询 FIFO 时、是否决定仅在接收到全部4个帧后才读取 FIFO 并将其清空? 或者、您是否读取了此时接收到的任何帧?

    使用中断的想法是确保在接收报文时不会读取 FIFO。

    [引用]1) DSP 仅在 FIFO 满时才会应答:我们有协议消息长1个 CAN 消息、2个 CAN 消息、4个 CAN 消息、很难确定正确的长度。 假设我们将长度固定为4条 CAN 消息、DSP 将在 FIFO 为4之前不会应答、如果 cortex 发送协议消息2 CAN 消息的长度、DSP 将不会应答? [/报价]

    那么、Cortex 可以在1、2或4帧内传输数据吗? 我当时的假设是每次都有4个帧。 如果将 FIFO 长度配置为4、并且只有2条消息到达、则 CPU 实际上不会收到警报。

    [引用]3)我问您的问题与您问的问题相同:由于来自 Cortex 的通信异步发生、您如何确保您的代码在从 cortex 开始下一次传输之前完全为中断提供服务? Cortex 和 DSP 之间没有握手。 [/报价]

    应用程序应确保在下一组帧到达之前为中断提供服务。 由于您已经澄清了帧长度不是恒定的、因此您要么必须为每个帧生成中断、要么像现在那样简单地轮询。  

    [引用]您是否了解如何在寄存器视图或 CCS 8.3.1调试器的存储器映射中读取 CAN 寄存器? [/报价]

    我没有。 我的 PC 中只有 CCS 版本9.3.0和10.0.0。

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

    只需关闭此线程:(调试已脱机)  

    问题出在 C:\ti\controlSUITE\device_support\F2837xD\V210\F2837xD_common\driverlib 目录中 CANMessageGet ()函数。  

    该函数中的最后一个参数设置为"true"。 这就产生了清除中断(由于应用程序使用轮询功能、中断本身不是必需的)以及 NEWDAT 位的效果。 由于 NEWBAT 位被清零、在邮箱被读取之前、一个新的帧被复制到该邮箱中。 此外、RxMsgLst 位也未设置。 将函数的最后一个参数设置为"false"可解决该问题。

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

    这解决了我的 TT。

    感谢您的支持。

    此致、

    Andrea Marcianesi