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.

[参考译文] Concerto F28M36x 偶尔会丢失总线数据包

Guru**** 2535750 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/720912/concerto-f28m36x-can-bus-packet-loss-occasionally

我们偶尔会看到 CAN 总线数据包丢失。 我们确实比较了波形、但它看起来良好情况和不良情况之间的差异不大。  

当我阅读应用报告 《控制器局域网(CAN)简介》时、我注意到 CAN 总线数据包用于短数据包。  

1) 1)我们使用的有效载荷似乎通过多个 CAN 总线数据包进行传输、这意味着一个高级数据包被斩波为3-4个 CAN 总线数据包。  

您是否在此问题上看到任何问题?

2) 2)我们还简化了 CAN 总线数据包、只需将一个高级数据包发送到接收器、然后接收器发回 ACK。  

总 CAN 总线数据包约为16个 CAN 总线数据包、持续时间~700ms。 在本例中、我们仍然看到问题?

3) 3) CAN 总线是否要求接收器端将整个 CAN 总线数据包作为 ACK 发送给发送器? 从应用报告中可以看到、接收端只需翻转 ACK 位即可通知发件人。  

但是、正如我从示波器中看到的、它看起来好像在一个 CAN 总线数据包之后、接收器端发送 ACK 作为 CAN 总线数据包、而不仅仅是简单的 TX 信号下降。 例如、在屏幕截图中。 红圈1应该是一个高级数据包、您可以看到来自 D0的第一个 TX、然后 D3切换一个 ACK 位(我从应用手册中的理解是、这是通知发送者的 ACK 位)。 但是、在这之后、我可以看到 D3发送了另一个 CAN 总线数据包。 CAN 总线协议是否需要这样做?

非常感谢您的帮助。  

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

    1. 不会出现将大量数据“斩波”到多个数据包中的问题。 CAN 协议不知道(或无关)。 只要应用软件正确处理传输端的“斩波”并在接收端重新组装斩波数据,一切都应该正常。
    2. 它取决于帧大小(位/帧的数量)、位速率和传输的启动方式。 在启动下一轮传输之前、是否等待前一轮传输完成? 您的软件如何处理传输过程中的错误? 如果不知道所有这些、就很难确定。 基本要求是有足够的时间发送所有位。 然后您必须确定如何处理错误条件。
    3. 是的、只有 ACK 位发生翻转。 我对您的应用程序不了解、无法解释您发送的范围捕获。 但是、我担心您对 ACK 机制的理解不正确。 请查看我的 app.note (SPRA890A)的第4页、我在其中解释了该机制。 您在使用的时间/分部中看不到 ACK 机制(2 MS/div)。 您需要将其降低至几 us 的顺序(确切值取决于比特率)。 您应该将 Ch1连接到 CANTX 引脚、将 Ch2连接到 CANRX 引脚。 然后、您可以清楚地看到我在 app.note 中描述的内容。

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

    至于2、我不熟悉 CAN 总线。 我的理解是、一旦 ACK 位翻转、这意味着接收器正确接收数据包、如果有、发送器可以发送另一个数据包。 在我们的代码中、发件人似乎无法发送、但我不知道这是不是因为接收器不能正确翻转该位。 我将进一步了解这一点、并向您提供更多信息。  

    项目符号3。

    我对硬件中 ACK 位的理解如下所示。

    D3发送数据、接收端翻转 ACK 位以通知接收者。 我的理解是否正确?  

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

    您好、Haresh、  

    1. 它取决于帧大小(位/帧的数量)、位速率和传输的启动方式。 在启动下一轮传输之前、是否等待前一轮传输完成?

    [Chenkun]每个 CAN 总线数据包都在等待远程端发回 ACK、然后再发送另一个 CAN 总线数据包。  

    您的软件如何处理传输过程中的错误?

    [Chenkun]我想我们没有再变。 如果发件人无法从接收器接收到 ACK、我们将不会继续传输。  

    是否有任何描述如何处理错误的示例代码或文档?

    P.S 我在这里提到的 ACK 不是 ACK 位。 这是我们这边的软件 ACK 实现。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果在传输过程中出现错误、则重新传输是自动的(无代码干预)、除非使用 DAR 位在代码中关闭了自动重新传输。

    没有显示必须如何处理错误的示例代码/文档。 这完全是应用程序的域。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Haresh、  

    can.h 中定义的这个结构与下面的位寄存器屏幕截图之间有什么关系?

    从手册中可以看到、SJW 位默认应为0、但当我用这个结构读取它时、 unsigned int uSJW 为2、SW 不会在初始化时对任何设置进行编程。  

    typedef 结构

    //! 该值包含同步、传播和相位的总和
    //! 缓冲器1段、以时间份额为单位。 其有效值
    //! 设置范围为2至16。
    unsigned int uSyncPropPhase1Seg;

    //! 该值保存相位缓冲器2段的时间份额。 有效的
    //! 此设置的值范围为1到8。
    unsigned int uPhase2Seg;

    //! 该值保存时间份额中的重新同步跳转宽度。 。
    //! 此设置的有效值范围为1到4。
    unsigned int uSJW;

    //! 该值包含用于确定时间份额的 CAN_CLK 分频器。
    //! 此设置的有效值范围为1到1023。
    unsigned int uQuantumPrescaler;

    tCANBitClkParms;

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

    如果使用驱动程序 API CANBitRateSet(),则可以设置 SJW。

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

    您是指该 API、 CANBitTimingSet 吗?  

    该 API CANBitTimingSet  似乎对时序进行编程、而 不是对设置位速率的 CANBitRateSet 进行编程。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    除了 CANBitTimingSet()之外,它们都具有相同的功能,允许您自行配置每个 TSEG1、TSEG2等,而 CANBitRateSet()则根据源时钟速度和所需的比特率自动计算这些值。

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

    尊敬的 Chris:  

    感谢您提供信息。  

    我们进一步调试、并注意到我们有3个 PCB 通过 CAN 总线相互通信。  

    我们偶尔会看到一个电路板无法发送数据包、因为 CAN ES 寄存器(offset=0x04)中的 TxOK 位未置位。  

    如果未设置该位、则在150ms 后将出现超时。  

    调用 CANMessageSet、我假设硬件将负责传输。 软件不需要执行任何操作。 正确吗?

    2.是否有任何方法可以设置特定电路板的优先级? 这意味着、如果主器件尝试发送、它将获得高优先级发送。 因为如果主器件发生故障、该命令将不会发送到从器件、最终操作将失败。  

    一旦 超时、软件会调用 CANMessageClear (canBaseAddr、transport、CAN_TXMSG_obj)、并且我假设硬件存储器不包含任何数据、因此 HW 不会发送任何数据。 是这样吗?

    4、假设超时后、如果要重新传输该数据包、是否需要再次调用 CANMessageSet? 或者、只要我保持在这个等待循环中、这意味着、例如、如果在该位置位之前 SW 中没有超时、HW 应该尝试将数据包发送出去。  

    下面是代码片段

    基本上、我们调用突出显示的 API 并让硬件处理传输。  

    SW 将一直检查该位、直到它超时。  

    while (((cumulativeStatus & CAN_STATUS_TXOK)= 0){
    CANMessageSet (canBaseAddr、transport CAN_TXMSG_obj、&canRingBufEntry.msg、MSG_OBJ_TYPE_TX);
    TFWD 看门狗(CAN_SEND_TIMEOUT_MS);

    //cumulativeStatus 读取 HWREG (baseAddr + CAN_O_ES)并继续检查 TxOK 位

    while ((((cumulativeStatus & CAN_STATUS_TXOK)=0)&&
    !wd.exped(){
    Task_sleep (1);//Task_yield ();

    uint32_t elapsed = wd.Elapsed();
    如果((累积状态和 CAN_STATUS_TXOK)==0)


    DbgInfo("发送失败:cs=%x、cle =%x、wd.expired ()=%u、retries =%u"、cumulativeStatus、canLastError、wd.expired ()、retries);

    //清除邮件,使其不会继续发送
    CANMessageClear (canBaseAddr、transport、CAN_TXMSG_obj);

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

    1.正确
    2.是的、ID 值最低的 CAN 报文将"赢得"仲裁、并将获得总线访问权限
    3.这将禁用报文对象。 它不会传输任何数据。
    您必须使用 CANMessageSet 来重新传输。

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

    尊敬的 Chris:  

    相关信息  4、假设超时后、如果要重新传输该数据包、是否需要再次调用 CANMessageSet? 或者、只要我保持在这个等待循环中、这意味着、例如、如果在该位置位之前 SW 中没有超时、HW 应该尝试将数据包发送出去。  

    如果我 首先调用 CANMessageSet

    假设我实现为伪代码   

    CANMessageSet();  

    while (TxOk!=true)// TxOk 是寄存器位

    while (timeout!=true&TxOK!=true){

    睡眠()

    //如果我不调用 CANMessageClear ()

    //当 SW 等待该位被置位时,是否需要 再次调用 CANMessageSet()?

    根据您的答复,我在 超时后必须再次调用 CANMessageSet(),但我想知道这是否是因为我 之前调用了 CANMessageClear()。  

    基本上,如果在极端情况下没有超时,并且没有调用 CANMessageClear (),CAN 总线是否会在 调用 CANMessageSet 后尝试传输?

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

    如果不使用 CANMessageClear 禁用消息对象、并且启用了 CAN 控制寄存器中的自动重发送(DAR 位)、那么一旦 CAN 总线再次空闲、发送失败(由于丢失仲裁或错误)的消息将自动尝试通过 HW 重新发送。 如果禁用消息对象或未启用自动重发送,则必须使用 CANMessageSet()重试。

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

    尊敬的 Chris:  

    感谢您提供的信息、此时此刻、我认为问题是由于电路板之间的 TX 冲突造成的、因为我们有多个电路板尝试发送 CAN 总线数据包。  

    如果我们需要进一步的帮助、我们将打开新的 TT。  

    谢谢。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    即使多个电路板同时尝试发送、MSGID 字段的逐位仲裁也能确保具有最高优先级(以数字形式最小的 MSGID)的节点在仲裁过程中胜出、并且该过程不会造成破坏。 该协议旨在巧妙地处理这种情况。 这本身不应导致任何问题。 当然,两个节点不应尝试传输相同的 MSGID。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Haresh、
    您能否详细说明这一点:"当然,两个节点不应尝试传输相同的 MSGID。"?

    这是否意味着两个节点不应传输到同一个节点?

    例如、我有三个节点、node1、node2和 node3。
    这是否意味着 node1和 node2不能同时传输到 node3?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    CAN 是一种事件驱动的异步协议、旨在处理两个或多个节点可能同时开始传输的情况。 这就是 MSGID 的无损位仲裁应该执行的操作。 两个节点可以同时尝试传输到第三个节点、但不能使用相同的 MSGID。 考虑到有32个邮箱、发送模式可针对接收器中的不同邮箱。