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.

[参考译文] TMS320F280039:为什么在 CAN 总线保持短缺的同时总线关闭恢复并触发中断

Guru**** 2427060 points
Other Parts Discussed in Thread: TMS320F280039, C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1540201/tms320f280039-why-bus-off-recover-and-trigger-interrupt-while-can-bus-keep-shortage

器件型号:TMS320F280039
主题:C2000WARE 中讨论的其他器件

工具/软件:

我们发现总线关闭恢复并触发中断、同时 CAN 总线仍然短缺、固件不进行复位或初始化、想知道什么原因吗?

下面是波形、 通道 1 是 CAN-TX、通道 2 是 GPIO、用于指示固件执行 mcan init(从 H 到 L)、通道 3 是 GPIO、以 mcan 中断为单位指示总线关闭状态(可以检查下面的中断代码)

CH-3 为高电平表示总线关闭在开始时设置、然后 CH-2 拉至低电平以执行 mcan init、通道 3 拉至低电平以指示总 线关闭在 2.8ms 后中断时恢复、然后 CAN 总线再次保持短缺、通道 3 在中断时再次拉至高电平以指示总线关闭设置、但是为什么即使 CAN 总线保持短缺、通道 3 也会在 2.8ms 后拉至低电平?    

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

    您好、Terry、

    抱歉、您会再次重新发送波形捕获结果吗?  似乎他们没有被包括在职位。

    谢谢、

    Joseph

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

    很抱歉、上传波形图、请在下面进行检查、谢谢  

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

    您好、Terry、

    感谢您提供详细信息。  MCAN 没有与 DCAN 类似的自动总线恢复序列。  用户必须在检测到总线关闭后立即执行 MCAN 初始化过程。  有关 MCAN 总线关闭、请参阅该较早的文章: https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1300965/tms320f2800157-mcan-not-going-into-bus-off-state/4939070?tisearch=e2e-sitesearch&keymatch=mcan%25252525252520bus%25252525252520off%25252525252520recovery#

    此致、

    Joseph

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

    您好、Joseph

    感谢您的建议、是的、我们唤醒了 MCAN 没有自动总线恢复功能、我们的问题不是如何执行正确的初始化过程来恢复总线关闭、但感到困惑的是、为什么总线关闭状态标志会自动从 1 更改为 0、而客户代码不执行任何 MCAN 初始化过程。

    您可以检查波形和中断代码、当 CAN-H 和 CAN-L 短缺时、ch3 输出 PSR.BO 位以指示总线关闭状态、变为 1(这对于总线关闭是正确的)、但在 2.8ms 后变为 0(自动恢复异常)。 您能帮助提出可能的原因吗?

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

    您好、Terry、

    好的、明白了。  顺便说一下,客户在另一个帖子上也有确切的问题:TMS320F280039:  TMS320F280039:MCAN Busoff Recorvery Error  。  我们可能只保留一个职位。  屏幕截图中有一个异常之处在于、MCAN 在清除 PSR.BO 时尝试发送。  这是在 PSR.BO 位变为低电平时经过几个周期后发生的。  CAN 帧重新传输之前的几个周期似乎是发生 129 次总线空闲。 PSR.BO 只能在 设置 CCCR.INIT 的情况下清除。  整个序列似乎表明在某个点启动了总线关闭恢复。  查看您发送的代码片段、我没有看到 CCCR.INIT 的设置位置或 MCAN 的初始化位置。  您能否检查 CCCR.INIT 或 MCAN 已初始化的其他函数或 ISR?  可能正在代码中的某个位置或其中一个 ISR 中执行 MCAN INIT。

    此致、

    Joseph

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

    您好、Joseph

    客户 通过使用 GPIO 添加代码来指示状态、 CH1 为 PSR.BO 值、CH2 为 CCCR.INIT 值、而 CH3 为 CCCR.INIT CLEAR 函数操作。

    根据波形、CH1 显示 2.8ms 后总线关闭恢复、CH2 显示 INIT 跟随总线关闭状态立即、但 CH3 未发生 INIT 清除操作、您认为这是否是正常行为?  产生该波形的原因是什么?

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

    您好、Terry、

    好的、在这种情况下使用总线关闭位的方式实际上并不是总线关闭条件处理程序、而是用作将 GPIO 引脚滴答为指示器的条件、不会出现任何错误。  在检查 IF 语句是否存在总线关闭条件并驱动 GPIO 引脚后、MCAN_clearIntrStatus (MCANA_DRIVER_BASE、 MCAN_IR_BO_MASK) 清除总线关闭标志、因此 SW 会将其解释为总线关闭清除、然后开启总线并传输其正在发送的任何内容。  然后、它立即检测到由于 TEC 计数器尚未清零、因此再次设置总线关闭状态。

    处理总线关闭情况的正确方法是使中断处理程序关闭总线。  在中断处理程序中、设置 CCCR.INIT 以复位 CAN 模块。  这将停止任何正在进行的传输。  此外、CCCR.INIT 还将清除 TEC 和其他错误计数器、然后将初始化 CAN 模块、等待 129 个总线空闲周期、然后恢复任何中断的传输。

    此致、

    Joseph

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

    您好、Joseph

    感谢您的建议,我们可以理解为什么巴士关闭再次设置,我们混淆了为什么巴士关闭是明确的最后一个。

    我们执行如下更多测试、CH1 监测中断中的 PSR.BO 状态、 CH3 监测中断中的 CCCR.INIT 状态。  CH2 在 200us 计时器中断中监测 CCCR.INIT 状态。  

    从波形可以看出、CH3 与要再次设置 CH1 相同、然后在最后 3ms 后清除、但 CH2 无法捕获 INIT 设置时刻、在设置之后似乎 INIT 应非常快速地清除。  我们无法理解 init 的原因和原因、您能帮助我们理解吗?

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

    您好、Terry、

    抱歉、IIM 对客户如何测试总线或如何在代码中处理总线感到困惑。  您能否将总线关闭中断处理程序的完整代码片段附加到一起?  我只想查看事件序列和标志监测器。

    谢谢、

    Joseph

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

    您好、Joseph

    抱歉、您造成了混淆、客户不在中断中处理总线关闭、仅用于监控 CAN 标志寄存器和操作 GPIO 以指示标志状态的中断。 实际上、甚至客户原始固件也没有设置中断、仍然存在相同的波形行为、同时客户监控器可以在主循环例程中标记和运行 GPIO。

    客户固件仅在主循环中处理总线关闭恢复功能(如以下所附代码所示)、基本上代码将监测是否发生总线关闭->等待 100ms、然后清除 INIT 以复位 CAN ->等待  129 个总线空闲周期以重新启用传输。  以及客户短缺 CAN-H 和 L 导致总线关闭。

    因此、通常应将 INIT 设置为-> 100ms ->清除->传输->设置-> 100ms ->清除;  

    异常波形显示 INIT 设置-> 100ms ->清除->传输->设置-> 3ms ->清除; (这将在~30%的时间内发生)

    我们 搜索整个固件、并在以下代码中仅双击确认 MCANConfiguration ()、在整个主循环中运行 INIT、还通过 GPIO 进行监控以指示 MCANConfiguration () 在异常波形 INIT  设置  -> 3ms -> clear 的时间段内没有运行。  

    因此、我们无法理解什么可能会触发 INIT 设置  -> 3ms -> Clear? 您能看看代码并帮助我们了解更多可能的原因吗?

    e2e.ti.com/.../BusoffHandlecode.txt

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

    您好、Terry、

    抱歉、还有几个问题。  CAN 总线关闭恢复例程中设置的 100ms 延迟是在哪里设置的、标称比特率配置为多少?  我只是想看看清除总线关闭后总线空闲时间需要多长时间。

    谢谢、

    Joseph

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

    您好、Terry、

    我不知道客户的 MCANConfiguration () 函数中包含什么内容、但在 C2000Ware 示例中、这包括将 MCAN 置于 SW 初始化模式、轮询以检查 MCAN 是否在 while 循环中初始化、设置位时间、轮询消息 RAM 是否在 while 循环中初始化、配置消息 RAM、设置消息滤波器、然后设置模式以退出软件初始化、再次轮询以检查 MCAN 是否处于正常工作模式。  初始化可能会很快、也可能会扩展、具体取决于轮询例程所花费的时间。  我假设客户具有与 C200Ware 示例相同的 MCAN 初始化步骤。

    MCANConfiguration() 它似乎在客户的函数 HandleBusoffFastSlowRecovery(Void) 中被调用、这个例程是一个在主循环中每 1ms 运行一次的任务。  这种方案的问题在于、 MCANConfiguration() 中的轮询例程执行时间可能超过 1ms、这使得该例程与检查总线是否关闭的 1ms 常规任务异步、如果发生这种情况 、下次在 main 中执行 HandleBusoffFastSlowRecovery(Void) 时、它将再次执行 MCANConfiguration()。

    因此、使用中断处理程序来管理总线关断恢复会更好、更高效。  使用中断处理程序时、只有在总线关闭的情况下才调用 ISR 、这将是运行 MCANConfiguration() 的唯一时间。   不需要通过 HandleBusoffFastSlowRecovery (void) 功能作为定期运行的任务来轮询总线关闭事件。  这将消除在第一个实例花费的时间超过 1ms 任务持续时间的情况下可能背靠背运行 MCANConfiguration() 的问题。

    此致、

    Joseph

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

    您好、Joseph

    是的、 MCANConfiguration 包括 SW 初始化过程(作为 C2000WARE 示例)、但是我们不认为其运行时间过长  、因为我们  在 MCANConfiguration 函数的末尾放置了一个 GPIO 切换以监控时序、我们确认 MCANConfiguration 在传输前完成、并且在按照以下异常过程传输后不会再次运行。 我们能否与器件设计成员再次检查 MCAN 是否具有自动总线关闭恢复功能、从而导致传输后立即执行 INIT 清除 3ms? 客户需要通过使用中断来代替轮询模式、说服 OEM 供应商接受更新固件。   

    但是、 异常 波形显示 INIT 设置-> 100ms ->清除 (MCANConfiguration Finished)->传输->设置-> 3ms -> 清除; (这将在~30%的时间内发生)

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

    您好、Terry、

    我可以检查设计、但如您所知、需要时间才能得到一些回复、因为正在进行的设计项目优先考虑。  同时、您能否通过删除以前的 GPIO 切换、 在 MCANConfiguration 开始时将 GPIO 切换设置为高电平、在 MCANConfiguration 结束时将 GPIO 切换设置为低电平、同时运行正常的  HandleBusoffFastSlowRecovery 定时任务来对客户的代码进行类似的评估。  GPIO 切换会指示 CAN 初始化需要多长时间。  客户还应该在 30%的时间内看到 GPIO 切换异常长。

    此致、

    Joseph

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

    您好、Joseph

    客户可以将波形捕获为您的建议、CH1 表示总线关闭状态、CH2 表示 INIT 位状态、CH3 表示  MCAN配置 运行时间(GPIO 在 MCAN配置 开始时切换为高电平、在 MCAN配置 结束时切换为低电平)   

    波形 1 和 2 显示了 初始化设置为-> 100ms ->清除->传输->设置-> 100ms ->清除  ;  

    波形 3 显示了 INIT 设置-> 100ms ->清除->传输->设置->  3ms ->清除的异常行为 ;  

    但是 、MCANConfiguration 运行时间在 3 个波形中约为 380us、500us 或 400us 、MCANConfiguration 确认在异常 情况下不会再次运行。  

    如果有任何可能的原因、请帮助您仔细检查行为、问题大约需要 2 周时间、客户迫切需要回复 OEM 的答案。

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

    您好、Terry、

    我使用客户的其中一个快照注释定时任务+计数器例程的异步性质、以监控并从总线关闭中恢复。  可以清楚地看到、调用 MCANConfiguration 后、将 INIT 位清除需要超过 3ms、如蓝色标记所示。

    若要使此方案正常工作、一旦设置 CCCR.INIT、就应立即清除 INIT 位、而不是在 3ms 后生效。  这会使函数 HandleBusoffFastSlowRecovery() 中的内部计数器混乱、因为这是每 1ms 调用一次的。  应对总线关闭位进行轮询、以确保清除该位后才能正常工作。  请参阅随附的片段。  我在第 55 行添加了一个 while 循环。

    static void HandleBusoffFastSlowRecovery(void)
    {
        static UInt8 u8McanBusOffCounter               = INITIAL_ZERO;
        static UInt8 u8TxMsgNum                        = INITIAL_ZERO;
        static UInt8 u8BusoffToRecoveryFlg             = INITIAL_ZERO;
        static UInt16 u16McanBusOffRecoveryTime        = INITIAL_ZERO;
        static UInt16 u16McanBusOffEventStartTime      = INITIAL_ZERO;
        static UInt8 u8McanBusOffStatus                = INITIAL_ZERO;
        uint32 u32Temp = 0UL;
    
        if(TRUE == u8BusOffTimer1msFlg)
        {
    #if 0
            u8McanBusOffStatus = ((*(uint32 *)(MCANA_DRIVER_BASE + MCAN_PSR) & 0x80u) >> 7u);
    
            u32Temp = ((*(uint32 *)(MCANA_DRIVER_BASE + MCAN_PSR) & 0x80u) >> 7u);
            u8McanBusOffStatus = (Uint8)u32Temp;
    #else
            u32Temp = (*(uint32 *)(MCANA_DRIVER_BASE + MCAN_PSR) & MCAN_PSR_BO_MASK) & 0xFFU;
            u8McanBusOffStatus = (Uint8)u32Temp;
    #endif
    
            if(u8McanBusOffStatus == 0x80u)
            {
                u8BusoffControlMsgFlg = 1u;
    
            	/*cancel message transmit request in busoff*/
                if(0u != MCAN_getTxBufReqPend(MCANA_DRIVER_BASE))
                {
                    for(u8TxMsgNum = 0u; u8TxMsgNum < (NUM_OF_MSG - 1U); u8TxMsgNum++)
                    {
                        MCAN_txBufCancellationReq(MCANA_DRIVER_BASE,u8TxMsgNum);
                    }
                }
    
                u16McanBusOffEventStartTime++;
    
                if(u8McanBusOffCounter >= BUS_OFF_FAST_RECOVERY_COUNTER)
                {
                    u16McanBusOffRecoveryTime = BUS_OFF_SLOW_RECOVERY_TIME;	/*busoff slow recovery delay time*/
                }
                else
                {
                    u16McanBusOffRecoveryTime = BUS_OFF_FAST_RECOVERY_TIME;	/*busoff fast recovery delay time*/
                }
    
                if(u16McanBusOffEventStartTime > u16McanBusOffRecoveryTime) /*busoff fast recovery attempt counter*/
                {
                    u16McanBusOffEventStartTime = 0u;
    
                    /*Once CCCR.INIT has been cleared by the CPU,the device will then wait for 129 occurrences of Bus Idle (129 *
                      11 consecutive recessive bits) before resuming normal operation*/ /*129 * 11 * 1 / 500k = 2.8ms*/
                    MCANConfiguration();
    
                    while(*(uint32 *)(MCANA_DRIVER_BASE + MCAN_PSR) & MCAN_PSR_BO_MASK);
                    
                    u8BusoffToRecoveryFlg = 1u;
    
                    if(u8McanBusOffCounter < BUS_OFF_COUNTER_LIMIT)
                    {
                        u8McanBusOffCounter++;
                    }
                }
            }
            else
            {
                /* Each Tx Buffer has its own Transmission Occurred bit. The bits are set when the corresponding TXBRP bit is cleared after a successful transmission.
                   The bits are reset when a new transmission is requested by writing a '1' to the corresponding bit of register TXBAR. */
    
                if(MCAN_getTxBufTransmissionStatus(MCANA_DRIVER_BASE) != 0U)
                {
                    u8McanBusOffCounter = 0u;
                    u16McanBusOffEventStartTime = 0u;
                }
            }
    
            u8BusOffTimer1msFlg = FALSE;
        }
    
        if((1u == u8BusoffToRecoveryFlg) && (0u == u8McanBusOffStatus))
        {
            u8BusoffControlMsgFlg = 0u;
    
            /*Enable first frame send immediately - 20250620 LiuGaoSong*/
            u8FirstMsgSendFlg = TRUE;
    
            u8BusoffToRecoveryFlg = 0u;
        }
    
    }

    如果此方案有效或说服客户使用中断处理程序来管理 CAN-FD 总线关闭、请使用此方案。  您还可以在网上搜索 CAN-FD 总线关闭处理、其他制造商的所有其他论坛建议通过中断处理程序关闭总线。

    此致、

    Joseph

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

    您好、Joseph

    客户通过以下代码中断更新总线关闭处理程序、您能否帮助审核是否正确?

    他们将在第一次 MCAN 中断后立即调用函数来清除总线关闭状态、 还可以处理传输并 在中断中检查 TXBRP 是否清除、但是即使不开始新的传输、有时 MCAN 将在大约 3~4ms 后再次进入总线关闭中断。   

    我们是否可以再次与您确认是否 仅在设置了 TXBAR 的情况下才会发生新的传输? 总线关闭应该只发生传输失败?  

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

    您好、Terry、

    总线关闭恢复的正确顺序是首先清除 CCCR.INIT、通过 TXBCR 寄存器取消待处理传输、然后确认/清除中断和标志。  不要运行整个 MCANConfig 函数、而是尝试通过仅运行 CCCR.INIT CLEAR 语句替换该语句、然后在 CCCR.INIT CLEAR 语句后立即使用 TXBCR 执行传输取消。

    此致、

    Joseph