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.

[参考译文] TM4C1294NCPDT:使用通过 SSI0的上电引导加载程序将初始映像加载到已擦除的闪存时出错。

Guru**** 2559240 points
Other Parts Discussed in Thread: TM4C1294NCPDT, EK-TM4C1294XL

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/993242/tm4c1294ncpdt-error-loading-an-initial-image-into-erased-flash-using-power-on-boot-loader-over-ssi0

器件型号:TM4C1294NCPDT
Thread 中讨论的其他器件: EK-TM4C1294XL

我正在使用 tm4c1294ncpdt、并在为包含处理器的卡供电后尝试使用 ROM 引导加载程序通过 SSI0加载初始映像。 因为下载命令从未返回 ACK 或 NAK、所以失败。 ping 和 get status 命令都能正常工作。 如果我使用 CCS IDE 或 J-Link 将映像编程到 MCU 中,并调用 ROM_UpdateSSI0(),则可以正常工作。  

我将下载命令更改为非法命令 、并得到 ACK、获取状态返回非法命令。 我更改了下载中的大小和地址、也不更改结果。 我发送了一个不带下载命令的发送数据命令 I、并获得了一个具有非法地址获取状态的 ACK。

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

    我使用 SSI0将2个 EK-TM4C1294XL 电路板连接在一起。 擦除闪存的编程可与这两个卡一起使用、这两个卡使用的软件与我在其中一个卡上执行编程所使用的软件相同、并且在 Mac OS X 11.2.3和 Windows 10上运行主机程序、这两个卡通过 TCP 连接到端口5000上的第一个卡。

    EK 和定制电路板的原理图之间唯一的显著差异是 VBAT 和 WAKE (低电平有效)。 我们的两个信号都未连接。

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

    尊敬的 Andrew:

     我不确定当其中一个电路板连接到主机 PC 而连接了两个电路板时、什么问题不起作用。 您说、当两个 LaunchPad 连接在一起时、主卡将能够向另一个卡发送命令(其闪存已擦除)并返回 ACK? 这是正确的理解吗? 如果是这种情况、则 MCU 运行正常。 您可能需要检查向 MCU 发送命令的主机 PC。 主机 PC 是否以正确的极性和相位发送命令? 如果您更改波特率、它会产生差异。 也许看看两个卡连接在一起时的 SSI 时序、并与发送命令的 PC 进行比较。 希望您能找到一些不同之处、并从中得到解释。  

    5.2.2 SSI 传输
    SSI 处理函数为 SSISend()、SSIReceive()和 SSIFlush()。 连接
    SSI 端口的使用需要以下四个管脚:SSITx、SSIRx、SSIClk 和 SSIFss。
    与引导加载程序通信的器件负责驱动 SSIRx、SSIClk 和
    而 Tiva 微控制器驱动 SSITx 引脚。 用于 SSI 通信的格式
    Motorola 格式、SPH 设置为1、SPO 设置为1 (请参阅 Tiva 系列数据表
    有关此格式的更多信息)。 SSI 接口具有限制的硬件要求
    SSI 时钟的最大速率为运行的微控制器频率的1/12
    引导加载程序。

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

    主机通过 TCP 连接向配置中的主卡发送命令和数据。 SPI 总线(SSI0)配置为 Motorola 模式3 (SPO=1、SPH=1)、工作速率为250Kbps。 主 MCU 用于与从 MCU (已擦除)通信、以便使用引导加载程序源代码中提供的命令对其进行编程。 如果器件已经被编程、那么主器件发送一条命令让从器件调用 ROM_UpdateSSI()。 如果未对器件进行编程、ROM 引导加载程序应扫描可用端口以获取有效命令。 这是根据文档(引导加载程序用户指南2.2.0.295)进行的。 正如我在上面所说的那样、如果从器件已经被编程、这个过程将起作用。 当从器件未编程时、它不会编程。 我使用两个 EKs 通过同一软件模拟我的设计、并执行相同的功能。 这两种情况 都是在与欧洲安全与合作组织模拟的情况下发生的。  

    为什么下载命令不发回 ACK 或 NAK (地址始终为0、大小约为32KB)? 引导加载程序代码具有通过所有选项发送 ACK 或 NAK 的最终路径。 唯一看起来可能导致问题的是意外中断、但无法从主器件侧了解中断。 ping 命令应使引导加载程序使用该接口、即使存在其他接口、因为它通过该接口接收到有效的命令。

    为什么调用 ROM_UpdateSSI()起作用,而不启动加载?

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

    您好!

     感谢您的澄清。   但是、我不知道问题在哪里。 那么、两个 EK 板看起来可以工作、但两个定制板不能工作、对吧? 我想不起作用的是在两个定制板之间。 您能否捕获两个 EK 板之间的下载命令波形并与定制板进行比较? 我想知道从器件是否未发送 ACK 命令、或者主器件是否在接收 ACK 时遇到问题。  

     下面是实现 COMMAND_DOWNLOAD 的代码片段。 查找解码各种命令的 Updater 函数。  根据代码、无论命令是否有效、都应发送 ACK。 您可以在 BL_main.c 文件中找到基于闪存的引导加载程序的详细信息。 ROM 引导加载程序的工作方式应相同。 也许、我还会建议您尝试闪存引导加载程序、您是否仍会在定制板上看到同样的问题。  

                //
                // This command indicates the start of a download sequence.
                //
                case COMMAND_DOWNLOAD:
                {
                    //
                    // Until determined otherwise, the command status is success.
                    //
                    g_ui8Status = COMMAND_RET_SUCCESS;
    
                    //
                    // A simple do/while(0) control loop to make error exits
                    // easier.
                    //
                    do
                    {
                        //
                        // See if a full packet was received.
                        //
                        if(ui32Size != 9)
                        {
                            //
                            // Indicate that an invalid command was received.
                            //
                            g_ui8Status = COMMAND_RET_INVALID_CMD;
    
                            //
                            // This packet has been handled.
                            //
                            break;
                        }
    
                        //
                        // Get the address and size from the command.
                        //
                        g_ui32TransferAddress = SwapWord(g_pui32DataBuffer[1]);
                        g_ui32TransferSize = SwapWord(g_pui32DataBuffer[2]);
    
                        //
                        // Depending upon the build options set, keep a copy of
                        // the original size and start address because we will need
                        // these later.
                        //
    #if (defined BL_PROGRESS_FN_HOOK) || (defined CHECK_CRC)
                        g_ui32ImageSize = g_ui32TransferSize;
    #endif
    #ifdef CHECK_CRC
                        g_ui32ImageAddress = g_ui32TransferAddress;
    #endif
    
                        //
                        // Check for a valid starting address and image size.
                        //
                        if(!BL_FLASH_AD_CHECK_FN_HOOK(g_ui32TransferAddress,
                                                      g_ui32TransferSize))
                        {
                            //
                            // Set the code to an error to indicate that the last
                            // command failed.  This informs the updater program
                            // that the download command failed.
                            //
                            g_ui8Status = COMMAND_RET_INVALID_ADR;
    
                            //
                            // This packet has been handled.
                            //
                            break;
                        }
    
    
                        //
                        // Only erase the space that we need if we are not
                        // protecting the code, otherwise erase the entire flash.
                        //
    #ifdef FLASH_CODE_PROTECTION
                        ui32FlashSize = BL_FLASH_SIZE_FN_HOOK();
    #ifdef FLASH_RSVD_SPACE
                        if((ui32FlashSize - FLASH_RSVD_SPACE) !=
                           g_ui32TransferAddress)
                        {
                            ui32FlashSize -= FLASH_RSVD_SPACE;
                        }
    #endif
    #else
                        ui32FlashSize = g_ui32TransferAddress + g_ui32TransferSize;
    #endif
    
                        //
                        // Clear the flash access interrupt.
                        //
                        BL_FLASH_CL_ERR_FN_HOOK();
    
                        //
                        // Leave the boot loader present until we start getting an
                        // image.
                        //
                        for(ui32Temp = g_ui32TransferAddress;
                            ui32Temp < ui32FlashSize; ui32Temp += FLASH_PAGE_SIZE)
                        {
                            //
                            // Erase this block.
                            //
                            BL_FLASH_ERASE_FN_HOOK(ui32Temp);
                        }
    
                        //
                        // Return an error if an access violation occurred.
                        //
                        if(BL_FLASH_ERROR_FN_HOOK())
                        {
                            g_ui8Status = COMMAND_RET_FLASH_FAIL;
                        }
                    }
                    while(0);
    
                    //
                    // See if the command was successful.
                    //
                    if(g_ui8Status != COMMAND_RET_SUCCESS)
                    {
                        //
                        // Setting g_ui32TransferSize to zero makes
                        // COMMAND_SEND_DATA fail to accept any data.
                        //
                        g_ui32TransferSize = 0;
                    }
    
                    //
                    // Acknowledge that this command was received correctly.  This
                    // does not indicate success, just that the command was
                    // received.
                    //
                    AckPacket();
    
                    //
                    // If we have a start notification hook function, call it
                    // now if everything is OK.
                    //
    #ifdef BL_START_FN_HOOK
                    if(g_ui32TransferSize)
                    {
                        BL_START_FN_HOOK();
                    }
    #endif
    
                    //
                    // Go back and wait for a new command.
                    //
                    break;
                }

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

    尊敬的 Andrew:

    [引用 userid="428255" URL"~/support/microcontrollers/other/f/other-microcontrollers-forum/993242/tm4c1294ncpdt-error-loading-an-initial-image-into-erased-flash-using-power-on-boot-loader-over-ssi0/3669460 #3669460"]主机计算机通过 TCP 连接将命令和数据发送到配置中的主卡[/quot]

    只是为了澄清卡片所指的内容、例如您的定制 PCB? 请使用词语 EVM 或 LaunchPad 来描述 TI 产品。 主机计算机可能正在主设备端进行传输、是否尝试将链路速度降低到10兆位?

    此外、如果主器件的环形缓冲器空间极小或没有、则可能导致 EMAC POST 故障状态位。 您可以通过 CCS 调试持续刷新来检查 DMARIS 寄存器。