F29H859TU-Q1: F29 Can发送和Busoff中断处理问题

Part Number: F29H859TU-Q1

Hi,

     问题一:F29H85x,Busoff中断里只判断Mcan_IR寄存器,Busoff状态发生变化都会进中断,一次Busoff会进2次中断且都会报告给上层(即使第二次中断,Busoff的状态以及恢复,即MCan_PSR_BO为0),这不符合规范;但是Busff轮询处理的时候,会先判断MCan_PSR_BO寄存器,确认MCan_PSR_BO为1后再报告上层;中断静态代码是缺少MCan_PSR_BO状态判断的。

    image.png

     问题二:F29H85x,Mcal Can配置Tx邮箱类型为BASIC_CAN,CanHwObjectCount不为1,压测发送报文周期时,发现存在漏帧,是因为报文请求发送时,读取空闲object的索引,跟最终发送时使用的索引不一致,导致发出的报文不对;把CanHwObjectCount改为1,问题解决了,但是为什么CanHwObjectCount大于1时,有漏帧的问题。

     image.png

     image.png

     image.png

  • 感谢您对TI产品的关注! 关于你的咨询,我们正在确认您的问题,感谢您的耐心等待。

  • 你好,

    问题 1:在 F29H85x 中,Busoff 中断仅检查 Mcan_IR 寄存器。Busoff 状态的任何变化都会触发中断,导致每个 Busoff 中断产生两个中断,这两个中断都会向上层报告(即使在第二个中断期间,Busoff 状态也会恢复,即 MCan_PSR_BO 为 0)。这不符合规范。然而,在总线关闭轮询期间,首先会检查 MCan_PSR_BO 寄存器,只有在确认 MCan_PSR_BO 为 1 后,才会将报告发送到上层。静态中断代码缺少 MCan_PSR_BO 状态检查。

    中断路径中可能存在断点。MCAN 硬件会在总线关闭事件(PSR_BO 变为 1)和恢复事件(PSR_BO 变为 0)时都设置 IR 总线关闭标志,因此,如果 ISR 中没有 PSR_BO 检查,这两个事件都会被上报到上层。轮询路径通过在报告前检查 PSR_BO 是否等于 1 来正确处理这种情况——中断路径也应该这样做。我会将此问题转发给我们的 MCAL 专家,以便他们进行确认。同时,作为一种临时解决方案,您可以在应用程序级总线关闭回调中添加 PSR_BO == 1 检查,以过滤掉错误的恢复通知。

    问题 2:对于 F29H85x,当将 Mcal Can 邮箱类型配置为 BASIC_CAN 且 CanHwObjectCount 不为 1 时,在消息发送周期的负载测试期间,发现存在丢帧现象。这是因为请求发送消息时读取的空闲对象索引与最终发送时使用的索引不一致,导致消息错误。将 CanHwObjectCount 改为 1 解决了这个问题,但是为什么当 CanHwObjectCount 大于 1 时仍然会出现丢帧问题?

    在选择空闲的 TX 缓冲区和实际写入之间可能存在竞争条件。当 CanHwObjectCount > 1 时,驱动程序会在索引 X 处找到一个空闲缓冲区,但当 Can_WriteRamPriv() 执行时,来自另一个任务的并发发送请求可能已经占用了该缓冲区。因此,最终写入时使用的索引与最初选择的索引不匹配,导致消息错误或丢失。建议使用 CanHwObjectCount = 1,这样就只有一个缓冲区,索引也确定,从而避免竞争条件。我也会将此问题转发给 MCAL 团队,以便他们进行调查。

    问候,

    约瑟夫

    [/quote]
  • 你好,希望尽快确认以上2个问题,例如问题1,要是带上Autosar的话,肯定不会按照这个临时方案处理的。

  • 您好,我已经联系了专家,并将此问题分配给相关人员处理。

    问候,

    约瑟夫

  • 你好,

    以下转述MCAL专家提出的问题:

    请您提供以下信息,以便我们进一步分析问题?

    1. 您是否收到两次总线关闭中断,一次是总线关闭后,一次是恢复后?还是两次都是总线关闭后的中断?
    2. 当您配置了 CanHwObjectCount > 1 的 BASIC CAN 硬件对象时,请您描述一下您的负载测试条件,以便我们能够重现该问题:
      1. 您是否缺少发送帧或接收帧?丢失了多少条消息?
      2. 您的 TxProcessing 和 RxProcessing 类型是什么?
      3. 信息发送和接收的周期是什么?
      4. Tx FIFO 配置的深度是多少(即 CanHwObjectCount)?您是否还有其他专用的发送消息缓冲区?

    问候,

    约瑟夫

  • 您好,

        1.您是否收到两次总线关闭中断,一次是总线关闭后,一次是恢复后?还是两次都是总线关闭后的中断?

         答:中断函数Can_ProcessLine0ISR()进入2次,Busoff产生和恢复都会进入,Can_CheckBusOffPriv()也进了2次,这看一下代码也就知道了,手册也说了Mcan_IR的BO寄存器置位1是busoff状态发生改变都会置位,Can_ProcessLine0ISR()中断函数里面只判断了Mcan_IR寄存器,所以会进2次,Can_CheckBusOffPriv()也会进2次。

            

            

      2.当您配置了 CanHwObjectCount > 1 的 BASIC CAN 硬件对象时,请您描述一下您的负载测试条件,以便我们能够重现该问题:

    1. 您是否缺少发送帧或接收帧?丢失了多少条消息?
    2. 您的 TxProcessing 和 RxProcessing 类型是什么?
    3. 信息发送和接收的周期是什么?
    4. Tx FIFO 配置的深度是多少(即 CanHwObjectCount)?您是否还有其他专用的发送消息缓冲区?

         答:总线负载率在50%-60%之间,可以复现。

            1、can总线上Tx报文漏发一帧

            2、TxProcessing和Rxprocessing配置的都是interrupt

            3、Tx报文的周期,10ms周期2帧报文,25ms周期2帧报文,50ms周期1帧报文,100ms周期2帧报文,200ms周期3帧报文,漏帧报文的周期是200ms

            4、CanHwObjectCount为10,还有一个TxObject是另一路CAN。

  • 问题1:你的观察和修正都正确。我们应该检查这两项。canBusOffRecoveryStatus and MCAN_PSR_BO before triggering the notification in order to ensure only one bus off notification is triggered for every bus off event.
    问题 2:我们正在努力重现该问题,分析完成后会通知您。

  • 问题1:是否是等Mcal下个版本才能迭代。

  • 关于问题 2:

    我们尝试重现该场景,但没有发现任何已接受传输的消息丢失。收到的发送确认数与收到的接收指示数完全一致。
    请注意,在上述场景中,在第 200 毫秒时,将有 2 个 10 毫秒帧、2 个 25 毫秒帧、1 个 50 毫秒帧、2 个 100 毫秒帧和 3 个 200 毫秒帧,这使得已发起的传输总数达到 10 个帧,并且您的 TX FIFO 的深度(即CanHwObjectCount)也为 10。因此,在第 200 毫秒时,如果总线上有任何未发送的消息,则新消息可能无法获得缓冲区空间,并且 Can_Write 函数将返回 CAN_BUSY。

    1. 您是否正在监控 Can_Write() 函数的返回状态并观察 CAN_BUSY 状态?这表明硬件尚未准备好发送更多消息。(我们观察到了这种情况,这是预期结果。)
    #2. 当你说丢失了一条 Tx 消息时,你统计的是 Tx 确认数与 Rx 指示数之比,还是 Can_Write 调用数与接收消息数之比?

    我建议将 Tx FIFO 的深度(即CanHwObjectCount)增加到 10 以上,以便有足够的硬件插槽可用于传输。

  • 问题2没有解决,你说的建议不可取,为什么深度要增加到10以上,跟发送报文条目相同不行吗?此问题的截图最上面都说明了。是在测试canoe上观测Tx报文周期时,发现一帧报文最大周期是正常周期的2倍,看trace是丢了一帧。

    上面图可以看到canTxRxPduld[2]=7、canTxRxPduld[3]=8,这是调用Can_Write()存的索引号,对应的报文分别是0xF7C0000、0xF7C0001,所以此时应发送的报文顺序应该是0xF7C0000、0xF7C0001;

    test_CANWrite[0]=2、test_CANWrite[1]=3表示待发送的索引,可以看到Ram中是数据并没有0xF7C0000,但是已经请求过了,最后发到总线上的是0xF7C0001,还是之前的存的数据;在Can_WriteMsgRamPriv()中,因为是basiccan,所以idx重新从MCAN_TXFQS_TFQPI获取了一次,不是调用Can_Write()后读取的MCAN_TXFQS_TFQPI(bufNum)

  • 你好,

    我看到这个问题已被标记为已解决。请问您是否已经找到了解决方案?
    否则我们可以对此进行进一步分析。

    谢谢,此致敬礼!

    尼基尔·达桑

  • 你好,

        问题没有解决,误点成已解决了。请进一步分析,谢谢!

  • 你好,
    请您提供以下信息以便我们进一步分析?
    1. 在您的代码中,SchM_Enter_Can_CAN_EXCLUSIVE_AREA_1()/SchM_Exit_Can_CAN_EXCLUSIVE_AREA_1() 是如何实现的?这个独占区域旨在确保获取空闲缓冲区、将数据复制到缓冲区以及更新寄存器状态的流程不会中断。在您的应用程序中,是否存在两个不同的线程调用 Can_Write() 并相互中断的情况?
    2. 你是否在监控 Can_Write() 的返回值?你是否得到了 CAN_BUSY 状态?

  • 1. 在您的代码中,SchM_Enter_Can_CAN_EXCLUSIVE_AREA_1()/SchM_Exit_Can_CAN_EXCLUSIVE_AREA_1() 是如何实现的?这个独占区域旨在确保获取空闲缓冲区、将数据复制到缓冲区以及更新寄存器状态的流程不会中断。在您的应用程序中,是否存在两个不同的线程调用 Can_Write() 并相互中断的情况?

          SchM_Enter_Can_CAN_EXCLUSIVE_AREA_1、SchM_Exit_Can_CAN_EXCLUSIVE_AREA_1只在Can_WriteTxHandlerPriv()中使用

            

         使用的芯片是F29H85X,有2路can使用Can_Write()。

    2. 你是否在监控 Can_Write() 的返回值?你是否得到了 CAN_BUSY 状态?

      没监控Can_Write() 的返回值,是在不同总线负载率的情况下测试TX报文是否丢失,发现的问题

    之前回复的也可以说明到问题啊,存储数据时获取的索引,跟最终发送获取的索引不匹配,导致的。

  • 你好,

    或许是沟通上出了点问题。
    问题1是关于SchM_Enter_Can_CAN_EXCLUSIVE_AREA_1和SchM_Exit_Can_CAN_EXCLUSIVE_AREA_1在您的应用程序中是如何实现的,而不是关于驱动程序的?

    除了 MCAL CAN 驱动程序中的专用区域标签之外,它们在您的应用程序代码中是在哪里以及如何使用的?

    问候,
    普拉纳夫·西达帕

  • SchM_Enter_Can_CAN_EXCLUSIVE_AREA_1和SchM_Exit_Can_CAN_EXCLUSIVE_AREA_1没有在应用程序里用

  • 你好,

    问候,
    普拉纳夫·西达帕