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.

[参考译文] MSPM0G3519:在大尺寸文件的固件升级期间跳转到应用时出现问题

Guru**** 2872500 points

Other Parts Discussed in Thread: MSPM0G3519, UNIFLASH

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1630931/mspm0g3519-problem-in-jumping-to-application-during-firmware-upgrade-for-large-size-files

器件型号: MSPM0G3519
Thread 中讨论的其他器件: UNIFLASH

您好:

我使用的是 MSPM0G3519 LaunchPad。

我正在做以下工作:
 
  1. 引导加载程序代码:此代码在复位后运行。 处理闪存复制(应用存储器到应用程序存储器的临时存储器)。 检查是否使用 内存 0x00007C00 上的标志请求升级。

   2.应用程序代码:这是第一个运行的固件。 它保持在 0x00008000。 之后运行      引导加载程序会检查 0x00008000 是否存在任何有效数据。  

此代码通过 BLE 接收更新。 收到的新固件存储在 0x00058000 中。 完全接收到固件后、将更新标志存储在位置 0x00007C00。  

代码正确复制到 0x00008000、但不会跳转到应用程序。

 

首先、我使用 CCS 刷写引导加载程序代码以及应用程序代码(即第一个固件)。 它使用 JUMP_TO_application 函数运行、这个函数也适用于大小为 944 字节的固件、但当我使用大小为 3KB 的固件时、该函数不起作用。

 

请引导我。 我已正确检查新固件是否在应用程序区域中正确复制。

 

void jump_to_application (void)
  __disable_irq();
  uint32_t sp =*(uint32_t *) app_base;
  uint32_t reset =*(uint32_t *)(APP_BASE + 4);    
  
  ((void (*)(void)) reset)();
 
}
 
主函数代码流如下所示
 
if(is_update_requested())  
      {       
      clear_update_flag();
      erase_application_area();
      copy_temp_to_application();   
      verify_flash ();//检查临时区域数据和应用区域数据是否相同
      jump_to_application ();  //这里跳转到 application ,新固件没有运行,这是工作文件大小 944 字节.  
      
      }
   暴露
   {
      /*如果没有升级请求→运行应用程序*/
      uint32_t app_sp =*(uint32_t *) app_base;

      if ((upgrade_mode == false)&&(app_sp!= 0xFFFFFFFF))
      {
        jump_to_application();//在第一次、它正在运行
      }
    }
 
 
 
求你帮助我。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我不是很确定这个代码是如何工作的,因为我在 jump_to_application () 中看不到加载 VTOR 或 SP 寄存器的任何内容。

    您是否熟悉 boot_manager 示例? (这里)它的 start_app () 函数可能很有用[但另请参阅(这里)关于优化使用的讨论]。

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

    您好、  

    根据我的需要、您能为我提供一些建议吗?如何进行此固件升级? 我所遵循的任何程序都是错误的? 如果是这样、2432 字节代码如何正常工作。 我理解的一件事是 2432 是 8 的倍数,而 3020 不是 8 字节的倍数。 那么它是否会导致固件运行出现问题? 我可以将其复制到应用程序区域、但它未运行。  

    我需要这方面的帮助。

    请帮帮我

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

    我上面提供的两个链接包括(总共)3 个不同的 start_app () 变体,这是你的 jump_to_application () 的示例。 它们在微妙的方面有所不同,但它们都表现出了机制。 (它们也很短。) 更笼统地说、查看该示例可能会建议您应该做的其他事情。

    你怎么知道跳跃不会发生? 它会跳转到何处? 如果没有正确的 VTOR 和堆栈指针 (SP),我怀疑即使跳转是正确的,它们也不会运行很长时间。

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

    您好、

    SCB->VTOR = 0x00008000;我将此写为应用程序代码 main() 中的第一行。
    好的。 我将通过这些链接获得。
    但我还观察到一点、我在从 CCS 刷写后比较了应用区域中的数据、然后使用 UART 将数据复制到温度区域。 我发现差异。 闪存数据在中间添加了额外的 4 个字节 (00)、从其来源以及如何执行此操作、为什么.bin 文件没有这些额外的 4 个字节、我的文件大小为 3020 字节、但刷写后的应用程序区域有 3024 字节。
    答、我在这里分享屏幕截图。 左侧大小是将.bin 文件转换为十六进制字节后发现正确的温度区域数据。 右侧是使用 CCS 刷写的应用程序区域。 我突出显示了这些字节。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我预计这是因为闪存字为 8 个字节。 可以编写一个字的子集[Ref TRM (SLAU846C) 第 6.3.2]、但我不知道在这种情况下是否值得麻烦。  您的代码是如何编写闪存字的?

    在任何情况下、我都看不到这些 0 字节与您的症状之间有明显的联系。

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

    您好、

    我通过添加额外的 4 字节 00 进行了测试、如屏幕截图所示。 现在它正在运行。 我的问题是为什么.bin 文件没有提供使用 CCS 进行刷写时给出的确切字节。 .bin 文件似乎错误。 是否有任何方法可以纠正?

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

    我的观察不是关于 jump_to_application () 的代码,它工作正常,它是关于.bin 文件生成,如果从 CCS 刷写需要 3024 字节,那么为什么.bin 只显示 3020 字节。  

    我也尝试了生成.hex 文件。 使用 uniflash 对.hex 文件编程时会收到以下错误。

    我认为、文件大小必须是 8 字节的倍数、如何生成相同的数据?

    请提供指南。

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

    我不知道有一个 objcopy 选项可以舍入(向上).bin 的大小;我认为您可以使用“--gap-fill"和“和“--pad-to"将“将其填充到预定的大小。 你也可能会得到一个地方与明智地使用“. = align (8)“。

    据我所知、您的代码是将数据写入闪存的内容。 似乎最可靠的方法是始终将 8 个字节的倍数(写入对齐的 8 个地址)写入、 并 在最后输入填充字节(根据需要) 您使用什么 API 来编写闪存?

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

    您好、

    填充不起作用、因为我不知道在哪个位置需要填充。

    我做了以下操作。

    在“Build"->"Steps"->"Post-build"步骤“步骤下“下</s>“ ““

     我添加了此命令

    “C:/ti/ccs2050/ccs/tools/compiler/ti-cgt-armllvm_4.0.4.LTS/bin/tiarmobjcopy.exe -O 二进制--gap-fill 0x00“gpio_toggle_output.out""gpio_toggle_output.bin"“"gpio_toggle_output.bin"</s>“ “

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

    是否正确、请告知我。

    正在等待您的回答

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您遇到的问题可能是 堆栈导致的 指针 (SP)  向量表偏移寄存器 (VTOR )  未针对较大的应用程序正确重新初始化。 虽然跳转函数适用于 944 字节的文件(可能是因为它足够小,不依赖于复杂的中断或特定的栈深度)、但 3KB 应用通常具有更多的依赖关系、如果 CPU 状态未复位、则会失败。 需要记住以下几点:
    • 您的代码可识别 sp 值 、但不会实际设置它。 CPU 将继续使用引导加载程序的栈、该栈可能与您的 3KB 应用程序的数据重叠或太小。
    • 在  MSPM0G3519 上 默认情况下、CPU 在地址 0x000000000 处查找中断。 由于您的应用处于 0x00008000、任何中断(甚至 SysTick)都将导致系统崩溃、因为 CPU 仍在查看引导加载程序的矢量。
    • 较大的文件通常可以启用更多外设。 如果您的 3KB 应用启用了计时器或 UART 中断 VTOR 、但仍指向引导加载程序、代码将跳转到错误的存储器并崩溃。
    • 3KB 应用可能具有更深层的函数调用栈。 如果没有__set_MSP、则它会使用剩余的引导加载程序栈、这可能会导致 栈溢出 或损坏。
    您能否确保 .cmd 配置为与 0x000008000  起始地址匹配? 如果应用程序认为它位于 0x00000000 、但您将其放置在 0x000008000、则任何内部绝对跳变都将失败。 您是否已确认 应用程序的链接器脚本的 源代码设置为  0x8000?
    -布赖恩