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:升级后引导应用程序

Guru**** 2530830 points
Other Parts Discussed in Thread: UNIFLASH, EK-TM4C1294XL

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1273992/tm4c1294ncpdt-booting-of-application-after-upgrade

器件型号:TM4C1294NCPDT
主题中讨论的其他器件:UNIFLASHEK-TM4C1294XL

在我的器件中、固件升级必须由另一个器件通过以太网完成。 因此、我在我的应用程序中创建了代码(起始地址0x20000)、通过 TCP/IP 将接收到的数据写入另外一个存储器(0x40000)。 并在配置内存中将固件升级标志设置为1。

我已经检查过、在0x40000中存储的数据与从 PC 工具(项目工具)加载的二进制文件相同。  

应用程序:

1. TCP/IP

2.固件升级命令用于接收数据,并将数据存储在0x40000中  

3.检查 CRC 并设置固件升级标志

4.移动到引导地址(0x00)

用于移动到引导地址的代码

HWREG (NVIC_VTABLE)= 0x00

//从应用程序的矢量表加载堆栈指针。
_asm (" LDR R1、[r0]\n"
" mov sp、r1");

//从应用程序的矢量表加载初始 PC 并分支到
//应用程序的入口点。
_asm (" LDR r0、[r0、#4]\n"
" bx r0\n");

在引导代码中:

1.检查固件升级标志状态。

2.如果设置了固件升级,则擦除闪存0f 应用程序(0x20000长度约为128KB),并将闪存写入数据从0x40000写入0x20000,并重置固件升级标志。

跳转至应用程序地址0x20000。 (设置或未设置固件升级标志)。 在首先刷写引导加载程序并通过 CCS IDE/LM 闪存刷写应用程序时、此方法有效。

HWREG (NVIC_VTABLE)= 0x20000

//从应用程序的矢量表加载堆栈指针。
_asm (" LDR R1、[r0]\n"
" mov sp、r1");

//从应用程序的矢量表加载初始 PC 并分支到
//应用程序的入口点。
_asm (" LDR r0、[r0、#4]\n"
" bx r0\n");

通过 PC 工具(项目工具)升级后、从0x40000刷至0x20000并跳转至应用程序不工作。 在跳转到位置时丢失任何其他内容。 引导和应用程序都使用相同的 SRAM - 0x20000000存储器。 我需要更改 SRAM 中的任何内容吗?

应用命令文件


--retain=g_pfnVectors

/*以下命令行选项作为 CCS 项目的一部分设置。 */
/*如果您正在使用命令行进行构建,或者出于某种原因想要*/
/*在此处定义它们,您可以根据需要取消注释和修改这些行。 */
/*如果您使用 CCS 进行构建、则最好制作任何此类项目*/
/*对 CCS 项目的修改,并保留该文件。 */
/**/
/*--heap_size=0 */
/*--stack_size=256 */
/*--library=rtsv7M3_T_le_eabi.lib */

/*应用的起始地址。 正常情况下、中断矢量*/
/*必须位于应用程序的开头。 */
#define APP_BASE 0x00020000
#define RAM_BASE 0x20000000

/*系统内存映射*/

内存
{
/*存储在内部闪存中并从内部闪存执行的应用程序*/
Flash (RX):origin = APP_BASE,length = 0x00010000
/*应用程序使用内部 RAM 进行数据*/
SRAM (rwx):origin = RAM_BASE、length = 0x00040000

/*内存中的段分配*/

部分
{
.intvecs:> app_base
.text :>闪存
.const :>闪存
cinit :>闪存
请输入您的密码:> FLASH
init_array:> FLASH

.vtable:> RAM_BASE
.data :> SRAM
bss :> SRAM
.sysmem:> SRAM
.stack:> SRAM

#ifdef __TI_Compiler_version__
#if __TI_Compiler_version__>= 15009000
.TI.ramfunc:{}load=flash、run=SRAM、table (BINIT)
#endif
#endif

引导命令

--retain=g_pfnVectors

/*以下命令行选项作为 CCS 项目的一部分设置。 */
/*如果您正在使用命令行进行构建,或者出于某种原因想要*/
/*在此处定义它们,您可以根据需要取消注释和修改这些行。 */
/*如果您使用 CCS 进行构建、则最好制作任何此类项目*/
/*对 CCS 项目的修改,并保留该文件。 */
/**/
/*--heap_size=0 */
/*--stack_size=256 */
/*--library=rtsv7M3_T_le_eabi.lib */

/*应用的起始地址。 正常情况下、中断矢量*/
/*必须位于应用程序的开头。 */
#define boot_BASE 0x00000000
#define RAM_BASE 0x20000000

/*系统内存映射*/

内存
{
/*存储在内部闪存中并从内部闪存执行的应用程序*/
FLASH (rwx):origin = boot_BASE、length = 0x00002000
/*应用程序使用内部 RAM 进行数据*/
SRAM (rwx):origin = 0x20000000、length = 0x00040000

/*内存中的段分配*/

部分
{
.intvecs:> boot_BASE
.text :>闪存
.const :>闪存
cinit :>闪存
请输入您的密码:> FLASH
init_array:> FLASH

.vtable:> RAM_BASE
.data :> SRAM
bss :> SRAM
.sysmem:> SRAM
.stack:> SRAM
#ifdef __TI_Compiler_version__
#if __TI_Compiler_version__>= 15009000
.TI.ramfunc:{}load=flash、run=SRAM、table (BINIT)
#endif
#endif

__STACK_TOP =_STACK + 4096;

两者都有启动文件。 但"引导"不需要启动。 如何在 boot cmd 中删除该矢量。

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

    您好!

    Unknown 说:
    两个文件都有启动文件。 但"引导"不需要启动。 如何在 boot cmd.
    中删除该矢量

    这是什么意思?引导加载程序不需要启动文件? 引导加载程序的启动文件位于 C:\ti\TivaWare_C_Series-2.2.0.295\boot_loader\bl_startup_ccs.s 中。 我通常不建议修改启动文件。 但是、如果您必须针对您的应用进行自定义、请仔细阅读该文件。 阅读该文件、了解引导程序如何跳转到应用程序以及应用程序如何跳回引导加载程序。

    常用引导加载程序通过调用 CheckForceUpdate 进行检查、以查看 APP_START_ADDRESS 处的应用程序是否为0xFFFFFFFF。 CheckForceUpdate 位于 bl_check.c 文件中。 如果  APP_START_ADDRESS 中存在非 FFFFFFFF 值 、则引导加载程序将跳转到应用程序。 常用引导加载程序将跳转到 APP_START_ADDRESS 、但如果您有两个应用程序映像、则需要向您智能添加要跳转到哪一个映像。  

    我不知道当您将第二个 FW 编程为0x40000时会发生什么情况。 0x20000处的闪存发生了什么情况? 您是否无意中擦除了您的第一个 FW? 使用内存浏览器确认0x20000是否仍然完好无损。 如果在您尝试在0x40000处升级第二个固件时以某种方式擦除了0x20000、并且如果引导加载程序尝试在0x20000处跳转到第一个固件、则引导加载程序没有可跳转到的应用程序代码、并且它将保持在引导加载程序模式。  

    引导加载程序的链接器命令文件位于 C:\ti\TivaWare_C_Series-2.2.0.295\boot_loader\bl_link_ccs.cmd 中。 如果您读取.cmd 文件、您将看到引导加载程序的加载和运行地址。 引导加载程序从0x0加载、但从0x20000000运行。 如果您读取  bl_startup_ccs.s 文件、您会看到、该器件超出复位范围后、会先将程序映像从0x0复制到0x20000000、然后将 NVIC_table 更改为0x20000000、然后从 SRAM 地址0x20000000运行引导加载程序代码。 查看启动文件中的 ProcessorInit 函数。 引导加载程序用于对您的应用程序代码进行编程。 如果从0x0运行引导加载程序、则对应用程序进行编程时会出现问题。 这就像运行闪存中的代码并尝试同时对闪存进行编程(虽然位于不同的地址)。 因此、要从 SRAM 运行引导加载程序、并且相关矢量表、堆栈指针和复位矢量入口点设置为0x20000000处的 SRAM。 读取引导加载程序链接器命令文件后、该文件从0x0加载并运行。 您仅将.intvecs 更改为 SRAM、但仍在闪存中运行引导加载程序代码。  

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

    如建议、现在我将使用 bl_link_ccs.cmd 和 bl_startup_ccs.c 和 Tiva 引导加载程序。 并将 APP 的起始地址更改为0x4000。

    Bootloader -> 0x0 address 和 App 1 - 0x4000。

    问题1:通过 uniflash 加载二进制文件时不起作用。 (打印在 UART 中为这些应用和引导测试切换添加的语句)。

    1.在0x00中加载了引导加载程序二进制文件。 存储库和应用程序。 无观察结果。

    2. 我已通过 CCS 加载引导加载程序, 而0x4000已通过 uniflash 加载二进制文件。 启动代码已执行、但应用程序代码不起作用。

    3.我已经通过 CCS 加载了应用程序,应用程序工作。 将评估套件断电并通电能够看到两个代码运行。

    问题2:不从应用程序切换到引导加载程序。

    1.固件升级必须通过以太网执行。 因此、我分离了另一个闪存来扩展新的 FW (0x20000)。 在使用 lwip 的应用中、接收新的 FW 二进制文件并存储在辅助存储器(0x20000)。 尝试切换到引导加载程序位置、在调试模式下会进行这种切换、但不清楚是正在进行切换、还是仅执行应用程序代码。

    此切换是通过 NVIC 矢量完成的。  

    HWREG (NVIC_VTABLE)= StartAddress;

    //从应用程序的矢量表加载堆栈指针。
    _asm (" LDR R1、[r0]\n"
    " mov sp、r1");

    //从应用程序的矢量表加载初始 PC,并跳转到 应用程序的入口点。
    _asm (" LDR r0、[r0、#4]\n"
    " bx r0\n");

    在通过测试实用程序进行升级时、会计算 CRC 这些值是否匹配、并且0x20000中存储的二进制值与载入的二进制值相匹配。

    已更新引导加载程序代码以检查 copytoRAM 后的固件升级标志、如果设置了该标志、则使用新固件从0x20000重新写入0x4000内存。 该 CRC 也与预期相同。 升级时不会丢失数据。  正在尝试切换到0x4000。 这种切换也不会发生。

    问题3:切换后不会发生中断(不清楚是否发生了类似前面所述的情况、仅在对应用程序代码进行 CCS 调试时、可以观察到以下情况。

    1.从引导加载程序切换到应用程序后(通过 CCS、固件升级或编程器不工作)、使用 NVIC 矢量集重置器件。 能够从引导加载程序启动应用程序、但未发生中断。

    2.在设置向量地址之前尝试禁用中断,"NVIC_INT_CTRL"和"NVIC_SYS_PRI3"的值与加载应用程序时的值不同。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    1. 在0x00中加载引导加载程序二进制文件。 存储库和应用程序。 无观察。

    您是如何加载两个二进制文件的? 您是同时加载还是分别加载? 如果您单独加载、那么应用程序的第二个加载将覆盖从引导加载程序所在位置0x0开始的闪存。 如果同时加载了两个二进制文件、请参阅下面的。 我加载了 boot_emac_flash 和 boot_demo_emac_flash.bin、我可以看到两者都成功加载、还可以看到 LED 闪烁、表明应用正在运行。  

    2. 我已通过 CCS 加载引导加载程序, 而0x4000已通过 uniflash 加载二进制文件。 启动代码已执行、但应用程序代码不起作用。

    [/报价]

    同样、您可能遇到同样的问题。 使用 CCS 加载引导加载程序时、应该已成功加载。 但当您在0x4000处加载使用 Uniflash 的应用程序时、它可能已擦除从0x0开始的闪存。 检查您的"Memory Browser"窗口、查看从0x0开始的闪存是否仍然具有引导加载程序映像。 如果您看到所有的 F、则意味着它们被擦除。  

    3.我已经通过 CCS 加载了应用程序,应用程序工作。 将评估套件断电并通电能够看到两个代码运行。

    [/报价]

    您是如何构建应用程序映像的? 您的应用程序映像链接到0x0或0x4000。 如果您认为它在单独加载时可以正常工作、则表示您将程序映像链接到0x0。 复位后的处理器将查找0x0处的堆栈指针以及0x4处的复位矢量。 由于您构建了将其链接到0x0的图像、因此这就是它起作用的原因。 但是、如果您有一个从0x0开始的引导加载程序、那么您也如何在0x0处构建您的应用程序? 它将相互覆盖。  

    为什么不查看 boot_demo_EMAC_flash 链接器命令文件呢? 请参阅下面的 C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\boot_demo_emac_flash\boot_demo_emo_emac_flash_ccs.cmd

    /*应用的起始地址。 正常情况下、中断矢量*/
    /*必须位于应用程序的开头。 */
    #定义 APP_BASE 0x00004000
    #define RAM_BASE 0x20000000

    /*系统内存映射*/

    内存
    {
    /*存储在内部闪存中并从内部闪存执行的应用程序*/
    闪存(RX):origin = 应用程序基础 ,长度= 0x000fc000
    /*应用程序使用内部 RAM 进行数据*/
    SRAM (rwx):origin = 0x20000000、length = 0x00040000

    /*内存中的段分配*/

    部分
    {
    .intvecs:> app_base
    .text :>闪存
    .const :>闪存
    cinit :>闪存
    请输入您的密码:> FLASH
    init_array:> FLASH

    我认为我们应该先解决您的问题1、然后再跳到其他问题。  

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

    在 Uniflash 中、已选择 neseccary 页面。https://e2e.ti.com/resized-image/__size/320x240/__key/communityserver-components-multipleuploadfilemanager/fdcc57ab_2D00_368c_2D00_4901_2D00_acUpload  4f_2D00_1d5315c77c50-577940-complete/necessarypage.png

    引导地址在加载时选择为0x00,加载时应用地址选择为0x4000,

    通过 uniflash 升级后的存储器:两者都有数据、

    代码中的 APP 基址也是0x4000。 验证也已通过

    代码未 运行、也尝试复位。

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

    加载自定义引导加载程序和应用程序后、如果调试器连接到目标、PC (程序计数器)在哪里? 它仍然位于引导加载程序中、还是 PC 已跳转到应用程序中0x4000的某个位置?

    为了进行实验、您为什么不使用 Uniflash 来加载常用的 boot_emac_flash.bin 引导加载程序和应用 Medtronic-HC-PRIMARL.bin? 您的应用会运行吗? 如果它运行、则意味着常用的引导加载程序将跳转到您的应用程序、但您自己的自定义引导加载程序由于某种原因不能跳转到您的应用程序。  

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

    我无法使用 BOOT_EMAC_FLASH 通过以太网升级 FW。 我尝试了 lmflash、eflash 显示了"尝试连接"、但升级没有发生。 如果0x4000具有0xffffffff、则发生 LED 闪烁(等待以太网升级)。  

    只有我有自定义引导加载程序。 此处修改的代码 是在.s 文件中进行 Enterapplication 调用之前进行的1函数调用(修改的 checkapplication、而不是 checkforceupdate)。

    在 checkapplication 中、如果未设置固件升级标志、请检查0x4000中的值并返回1 (与 checkforceupdate 相同)。

    如果设置了固件升级标志、请将新固件从0x20000复制到0x4000、并检查0x4000中的应用程序并返回1。

    然后调用 Enterapplication。 即使设置了固件升级标志并且未设置、也无法正常运行。

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

    我分析的是使用 CCS 生成的引导加载程序二进制文件无法正常工作。

    如果 我上传了 bin (通过 LMFLASH 在 SDK (boot_serial 0x0)中可用)、并通过 LMFLASH 中的 UART 升级 BLINK 二进制文件(在 CCS 中生成0x4000)。 两个纸槽都在工作。

    如果我  通过 LMFLASH 上传 boot_serial hex /bin、使用 CCS 生成的文件不起作用。 通过 UART 升级 BLINK 二进制文件时、显示"正在与目标建立通信"、并且出现错误弹出窗口。

    Blink ->使用 CCS 构建、APP_BASE 为0x000 ->通过 LMFLASH 上传的二进制文件有效。 Blinky 项目 缺省 文件使用.cmd 文件和 startup_gcc.c 文件和最新编译器版本(V20)。

    引导加载程序具有.cmd 文件和 gcc.s (使用的默认文件)。 bl_config.h - UART 标志被启用。 并构建代码。 生成十六进制。  选择 Compiler version - v18 (默认)。  使用这种生成的十六进制可以观察到相同的行为、并将编译器版本更改为 v20 (最新)、输出为二进制。 对于这两种情况、编译器的观察是相同的。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我无法使用 boot_emac_flash 通过以太网升级 FW。 我尝试了 lmflash、eflash 显示了"尝试连接"、但升级没有发生。 如果0x4000具有0xffffffff、则发生 LED 闪烁(等待以太网升级)。  [/报价]

    我想我有一个根本性的问题要问。 请回答我一些非常基本的问题。

    -是否成功运行了常用的 BOOT_EMAC_FLASH (引导加载程序)和 BOOT_DEMO_EMAC_FLASH (应用程序)示例? 闪存被擦除后、您首先通过 JTAG 加载 BOOT_EMAC_FLASH。 引导加载程序运行后、您是否能够通过 lmflash 或 eflash 下载 boot_demo_EMAC_flash? ("是"或"否")?

    -假设您能够下载应用程序的第一次,这意味着上述步骤是成功的。 换句话说、引导加载程序仍然位于0x0、应用程序现在位于0x4000。 应用程序运行后、LED 应闪烁。 您是否能够从 lmflash 或 eflash 再次升级相同的应用程序? ("是"或"否")? 当您使用 lmflash 或 eflash 升级固件时、它将向客户端发送一个魔术包。 应用 boot_demo_EMAC_flash 将检测魔术包并跳转到引导加载程序以再次升级固件。  

     您似乎永远无法成功地运行这些示例。 这就是为什么我必须知道上述问题的答案。 您似乎表明 BOOT_EMAC_FLASH 不起作用、但只有您的自定义引导加载程序才能起作用。 这是我感到困惑的地方。 这些示例应该可以开箱即用。 我已经亲自运行过这些示例很多次、并且从未遇到过问题。 如果即使在示例中也有问题、应该理解出了什么问题。  

    如果 我上传了 bin、此容器可通过 LMFLASH 在 SDK (boot_serial 0x0)中找到、并通过 LMFLASH 中的 UART 升级 BLINK 二进制文件(在 CCS 中构建0x4000)。 两个纸槽都在工作。

    好的。 这是预料之中的。

    如果我  通过 LMFLASH 上传 boot_serial hex /bin、我使用 CCS 生成的文件不起作用。 通过 UART 升级 BLINK 二进制文件时、显示"正在与目标建立通信"、并且出现错误弹出窗口。

    不清楚为什么需要加载 hex 文件。 在任何情况下、您可以转到0x0处的存储器浏览器并在加载十六进制文件与加载 bin 时显示闪存内容。 区别是什么? 显示每种选项的屏幕截图。 也许会加载引导加载程序的十六进制文件、但内容与 bin 文件不同。 如果是这种情况、则与十六进制的生成方式有关。  

    blink ->使用 CCS"APP_BASE 构建为0x000 ->通过 LMFLASH 上传的二进制文件有效。 Blinky 项目 缺省 文件使用.cmd 文件和 startup_gcc.c 文件和最新的编译器版本(V20)。

    这预计会起作用。  

    Bootloader 具有.cmd 文件和 gcc.s.(使用的默认文件)。 bl_config.h - UART 标志被启用。 并构建代码。 生成十六进制。  选择 Compiler version - v18 (默认)。  使用这种生成的十六进制可以观察到相同的行为、并将编译器版本更改为 v20 (最新)、输出为二进制。 对于这两个编译器观察结果相同。

    请参考我上面的答案。 查看在0x0处加载到 UART 引导加载程序闪存中的内容。 它与使用 bin 文件加载的内容是否相同? 在 CCS 中、您甚至可以保存存储器。 加载 hex 文件后、保存存储器并对 bin 文件执行相同操作。 比较两个不同的存储器内容。 区别是什么?  

    [/quote]