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.

[参考译文] LAUNCHXL-F280039C:通过 PC 适用于 2 个 MCU 的引导加载程序

Guru**** 2966500 points

Other Parts Discussed in Thread: TMS320F280039C

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1654853/launchxl-f280039c-bootloader-for-2-mcu-via-pc

器件型号: LAUNCHXL-F280039C
主题: TMS320F280039C 中讨论的其他器件

您好专家、

目前、我的电路有 2 个 MCU TMS320F280039C、我正在通过结构 PC ->(SCIA) MCU1 (SCIB)->(SCIA) MCU2 为这些 MCU 实现引导加载程序。 我使用 TI 的串行闪存编程器执行以下 2 个步骤:

步骤 1:PC 将通过 SCIA 引导 MCU1。 我以 TI 指南“C2000Tm 微控制器的串行闪存编程“为指导、并可以通过 OK 的方式为 MCU1 实施引导加载程序

步骤 2:PC 将通过 MCU1 引导 MCU2。 在这种情况下、MCU1 将是 UART 桥、只需通过 SCIA 从 PC 获取信号、而 SCIB 将在传输到 MCU2 之后从 SCIA 获得信号、如下所示:

    rxStatus1 = SCI_getRxStatus (SCIA_BASE);
    rxStatus2 = SCI_getRxStatus (SCIB_BASE);
    if (rxStatus1 || rxStatus2)
    {
      while(!SCI_isDataAvailableNonFIFO (SCIA_BASE)&&!SCI_isDataAvailableNonFIFO (SCIB_BASE))
      {
      }

      IF (SCI_isDataAvailableNonFIFO (SCIA_BASE)= 1)
      {
        receivedChar1 =((uint16_t)(HWREGH (SCIA_BASE + SCI_O_RXBUF)& SCI_RXBUF_SAR_M);
        SCI_writeCharNonBlocking (SCIB_BASE、receivedChar1);
      }
      IF (SCI_isDataAvailableNonFIFO (SCIB_BASE)= 1)
      {
        receivedChar2 =((uint16_t)(HWREGH (SCIB_BASE + SCI_O_RXBUF)& SCI_RXBUF_SAR_M);
        SCI_writeCharNonBlocking (SCIA_BASE、receivedChar2);
      }
    }

我还使用 TI 指南“C2000Tm 微控制器的串行闪存编程“为 MCU2 执行引导加载程序。 但是、 有时命令提示符指示 0xAA = 0xAA、PC 无法在下一个命令中向 MCU2 发送命令、如下图所示。 请帮助我分享您的建议。

谢谢你 33a19fab-b9d1-4976-bb50-f99ca26e8099.jpg

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

    您好:

    对延迟表示歉意、请等待星期一的回复。

    此致、
    马特

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

    您好:

    这似乎是 MCU1 的 SCI 桥接器代码中的时序和延迟问题。 SCI 引导加载程序协议要求在每次数据传输之后、引导加载程序会将接收到的每 8 位字符回传到主机以进行验证。 基于轮询的桥接器会引入延迟、导致 PC 端串行闪存编程器等待 MCU2 的回波响应超时、这就是它在自动波特握手 (0xAA = 0xAA) 成功后间歇性停止、但后续命令失败的原因。

    当轮询循环恰好在数据到达时处于其周期的正确位置时、您的间歇性成功发生—时间偶然对齐。 有时、循环在`while ()`中被阻止或处理错误的方向、导致回波延迟到达、串行闪存编程器超时。

    1. while () 阻塞循环创建竞态条件:

    while(!SCI_isDataAvailableNonFIFO(SCIA_BASE) && !SCI_isDataAvailableNonFIFO(SCIB_BASE))

    此过程会一直阻止、直到数据到达任一端口、但如果数据几乎同时到达两个端口(在回显期间发生)、您可能只处理每个循环迭代的一个方向、从而导致另一个方向的响应延迟或丢失。

    2.无 TX 就绪检查的非阻塞写入:

    SCI_writeCharNonBlocking(SCIB_BASE, receivedChar1);

    如果 TX 缓冲区已满、此调用将静默丢弃字符。 在写入之前不会验证发送器是否已准备就绪。

    3.引导加载程序协议是双向的,时间敏感的:
    在自动波特率锁定后、器件需要在自动波特率回波之后立即提供 KeyValue (0x08AA)。 串行闪存编程器具有严格的超时窗口—桥接器必须以最小的延迟双向中继字节、或者主机将缺失/延迟的回波解释为故障。

    推荐的修复:

    选项 A:中断驱动桥接器(推荐)

    将轮询循环替换为中断驱动的 FIFO 传输:

    // SCIA RX Interrupt - forward to SCIB
    __interrupt void SCIA_RX_ISR(void)
    {
    uint16_t data = SCI_readCharNonBlocking(SCIA_BASE);
    while(!SCI_isSpaceAvailableNonFIFO(SCIB_BASE)); // Wait for TX ready
    SCI_writeCharBlockingNonFIFO(SCIB_BASE, data);
    // Clear interrupt
    SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXRDY_BRKDT);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    // SCIB RX Interrupt - forward to SCIA
    __interrupt void SCIB_RX_ISR(void)
    {
    uint16_t data = SCI_readCharNonBlocking(SCIB_BASE);
    while(!SCI_isSpaceAvailableNonFIFO(SCIA_BASE)); // Wait for TX ready
    SCI_writeCharBlockingNonFIFO(SCIA_BASE, data);
    // Clear interrupt
    SCI_clearInterruptStatus(SCIB_BASE, SCI_INT_RXRDY_BRKDT);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }

    选项 B:修复轮询循环(最小修复)

    If you must use polling, fix these critical issues:
    for(;;)
    {
    // Check SCIA RX -> forward to SCIB
    if(SCI_isDataAvailableNonFIFO(SCIA_BASE))
    {
    receivedChar1 = (uint16_t)(HWREGH(SCIA_BASE + SCI_O_RXBUF) & SCI_RXBUF_SAR_M);
    while(!SCI_isSpaceAvailableNonFIFO(SCIB_BASE)); // CRITICAL: wait for TX ready
    SCI_writeCharNonBlocking(SCIB_BASE, receivedChar1);
    }
    
    // Check SCIB RX -> forward to SCIA
    if(SCI_isDataAvailableNonFIFO(SCIB_BASE))
    {
    receivedChar2 = (uint16_t)(HWREGH(SCIB_BASE + SCI_O_RXBUF) & SCI_RXBUF_SAR_M);
    while(!SCI_isSpaceAvailableNonFIFO(SCIA_BASE)); // CRITICAL: wait for TX ready
    SCI_writeCharNonBlocking(SCIA_BASE, receivedChar2);
    }
    }

    重要变化:
    -删除外部`if (rxStatus1 || rxStatus2)` check 和 blocking `while ()`—这些会增加不必要的延迟
    -在写入前添加 TX-READY 检查,以防止字符丢失
    -紧密连续循环—不要在 RX 状态标志上输入门控

    其他建议:从 RAM(而不是闪存)运行桥接代码、以尽可能减少执行延迟

    此致、

    马特

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

    您好 Matt、

    感谢您的反馈。 我听从了你的建议。 但是、选项 a cmd 在 41==0 处停止、如下所示

    在选项 B 中、信号无法发送到 cmd、如下所示

    您是否有任何其他建议或其他方法来  通过 MCU1 为 MCU2 实现引导加载程序?

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

    您好:

    请允许我花几天时间与我的同事讨论这个问题。

    此致、
    马特

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

    您好:

    几个澄清问题:

    A failure (41=0)—使用的设备类型:
    在选项 A 屏幕截图中、该命令使用 f280025 目录中的-d f28002x。 您能解释一下 MCU 是 TMS320F280039C、它是 F28003x 器件、而不是 F28002x 吗? F28002x 闪存内核不兼容。 您是否 使用-d f28003x 与 f280039C 内核重新运行选项 A?

    B 失败—SCIB 初始化:
    当选项 B 完全失败(no aa=aa 输出)时、最常见的原因是 while(!SCI_isSpaceAvailableNonFIFO (SCIB_BASE)) 一直在旋转、因为 SCIB TX 从未就绪。 请验证:

    1. MCU1 上的 SCIB 波特率配置为 9600 波特率(与-b 9600 参数匹配)
    SCIB TX/RX 引脚的 GPIO 多路复用器设置为 SCI 功能(非 GPIO 模式)
    SCIB 模式是非 FIFO(与 SCI_isDataAvailableNonFIFO / SCI_isSpaceAvailableNonFIFO API 调用一致)
    4.根据 F28003x TRM 引导模式表、将 MCU2 引导引脚配置为 SCIA 引导模式
     5. SCI TX/RX 物理连接

    要隔离问题、请在 MCU1 的桥接环路中添加一个简单的 GPIO 切换、以便您可以通过示波器或 LED 确认代码是否到达桥、或者是否卡在 while () 等待中。

    此致、

    Allison