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.

[参考译文] TMS320F28388D:单组多核的实时固件更新(LFU)

Guru**** 2539500 points
Other Parts Discussed in Thread: TMS320F28388D, C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1383686/tms320f28388d-live-fw-update-lfu-for-multi-core-with-single-bank

器件型号:TMS320F28388D
Thread 中讨论的其他器件: C2000WARE

工具与软件:

您好!  

我正在调查 TMS320F28388D 的 LFU 和

  • 我想知道您是否有此芯片的参考文档和示例?
  • 我阅读了 F28004x 的文档、但实现必须不同、因为每个内核有一个闪存组可用。
  • 在哪里可以找到单组闪存分区的示例、以实现固件更新和回滚功能?
  • 此解决方案是否可以通过内核1和内核2更新来实现?

感谢你的帮助。

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

    请注意、由于美国假期、大部分团队都是 OOO。  请在下周回复。  

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

    VIC

    -不,我们没有 LFU 参考 F2838d 文档

    -这是正确的。 F28004x 具有2个存储体、F28003x 最多具有3个存储体、而 F2838x 每个内核只有1个存储体。

    -我们在 F28002x 中有一个示例实施(1个组)

    C2000Ware_5_02_00_00\driverlib\f28002x\examples\flash

    lfu_singlebank 是一个简单的 LED 闪烁应用程序示例、flash_kernel_ex3_ldfu 是闪存内核/引导加载程序。

    在此示例中、我们在 LFU 期间在闪存中覆盖整个应用程序。 为了使应用保持运行、因此、我们将必要的 ISR 复制到 RAM 中。 我们还将闪存 API 和特定函数从内核/引导加载程序复制到 RAM。 这是因为闪存组不是 RWW (写入时读取)。

    -是的,你可以有同样的方法适用于 CPU1和 CPU2。

    谢谢!

    SIRA

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

    感谢您发送编修。

    根据我的理解、 C2000Ware_5_02_00_00\driverlib\f28002x\examples\flash 的示例会在更新过程中覆盖整个映像。 因此、如果此过程中出现任何错误、则无法回滚到之前的固件版本。

    • 你是否有链接器命令文件示例、可以帮助我将唯一的闪存组拆分为两个分区?
      我想、为了使回滚的可能性、我应该这样做。

    • 如果我要实施 CPU1和 CPU2的固件更新、是否可以使用 SPRABV4H 中所述的串行闪存编程方法?
      是否只有预先要求具有通信接口(并行 IO、SCI 或 CAN)和 GPIO 引导模式选择?
      我仍在考虑 基于 LFU 的这种解决方案、而不知道哪一种解决方案对我的情况而言是最佳和最高效的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    VIC

    我没有适合此确切用例的链接器 cmd 文件、但它应该可以轻松创建它。 您有3个单独的链接器 cmd 文件

    -一个用于闪存内核/引导加载程序

    -一个用于新应用程序

    -一个用于现有(回滚)应用程序

    sprabv4介绍了一种不基于 LFU 的通用固件更新方法。

    这取决于您的特定应用需求。 在更新过程中是否需要应用程序运行-这是关键问题。

    谢谢!

    SIRA

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

    SIRA,  

    您能否确认我的理解是否正确?


    在我的场景中,我把我的闪存分成3个区域用于回滚目的:[内核][PART_A][PART_B]

    我应该有1个构建配置、可生成[kernel]并在出厂时将其刷写1次。

    在产品的整个生命周期中、我应该有2个其他构建配置以及关联的链接器文件、用于生成[PART_A]或[PART_B]图像。 这样我就可以发送它们来执行连续更新了吗?

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

    VIC

    完全正确。

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

    尊敬的 Sira:

    我尝试从 f28002/4x 示例中获得灵感、实现定制 SCI 闪存内核、但我遇到了一个问题。


    尝试使用串行闪存编程器传输固件映像时、代码执行将跳转至 fmstatFail  功能(请参阅以下图片)。


    这发生在擦除段之后、将新数据重新写入闪存之前。 我通过在 fmstatFail 函数中添加 flash_status 和 status 值、以更好地理解这些参数。 他们各自的价值是4112和  Fapi_Status_Fsm 、所以不能真正帮助我。

    我修改了闪存内核、因此擦除功能不会擦除完整的闪存、而是仅对应于我的固件映像最大大小的子部件。

    我已经检查了 ldfuCopyData ldfuLoad 是从 RAM 运行的。

    我还检查了 SPNU632 4.2中代表的典型擦除流程是否得到遵守、看起来就是这种情况。

    你是否有任何线索可能是这个错误的原因?

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

    VIC

    我确实看到 ldfuCopyData 和 ldfuLoad 是从 RAM 地址运行的。

    您是否还确保将闪存 API 库复制到 RAM?

    谢谢!

    SIRA

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

    尊敬的 Sira:
    感谢您的意见。

    我找到:

    1. 时钟初始化错误以及它
    2. FlashAPI 实际上未从 RAM 运行(请参阅以下图片)。

    对于1.、我建议这个改变可以应用于 C2000示例以避免遇到错误的硬编码频率:  

    对于2.、我仍然难以从 RAM 运行 FlashAPI、这可能是由于链接问题所致。

    我在链接器文件中添加了以下行、


      GROUP
       {
           .TI.ramfunc
           {
              -l F2838x_C28x_FlashAPI.lib
           }
       }  LOAD = STATIC_CODE,
    	  RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
    	  LOAD_START(RamfuncsLoadStart),
    	  LOAD_SIZE(RamfuncsLoadSize),
    	  LOAD_END(RamfuncsLoadEnd),
    	  RUN_START(RamfuncsRunStart),
    	  RUN_SIZE(RamfuncsRunSize),
    	  RUN_END(RamfuncsRunEnd),
    	  ALIGN(8)

    -l F2838x_C28x_FlashAPI.lib 会生成以下警告:../linker_flash_custom_static.cmd"、第147行:警告#10068-D:无匹配段

    使用 #pragma CODE_SECTION (foo、".TI.ramfunc")的其余代码似乎在正确的位置进行刷写。

    此警告是否意味着链接器无法找到该库、因此无法将其放在正确的地址中?

    感谢你的帮助。

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

    我通过  在我的项目中删除 F2838x_C28x_FlashAPI.lib 的本地副本而改为添加一个链接、解决了 FlashAPI 链接问题。

    然而,在解决这个问题后,我刚刚意识到在闪存写入过程中仍然有一些问题。

    在 ldfu_load()中的固件传输结束时、写入密钥和 REV 值的函数调用返回成功、但实际上失败了。 查看内存浏览器时、可以看到起始值、但看不到 REV 和 KEY。

    在以下存储器浏览器中、我需要0x5A5A5A5A 0xFFFFFFFE 0x5B5B5B5B5B。 我无法解释这个结果。

     

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

    VIC

    您使用的将闪存 API 库从闪存复制到 RAM 的方法看起来是正确的(在链接器 cmd 文件中)、但为了确保您查看.map 文件并检查闪存 API 是否映射到 RAM 地址?

    您是否能够尝试在写入 KEY 和 REV 之前放置一个断点、并检查预期的写入值是否正确?

    谢谢!

    SIRA

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

    SIRA,  

    由于我 用一个链接替换了 F2838x_C28x_FlashAPI.lib 的本地副本、FlashAPI 现在正在从 RAM 运行。

    关于 KEY 和 REV 写入问题、此问题似乎与存储器块大小和/或 ECC 有关。


    当我写入从0x80120开始、KEY 从0x80124开始时、它不起作用并且  Fapi_getFsmStatus ()返回0x30。
    但是
    当 我写入从0x80120开始、KEY 从0x8012C 时、它将起作用!  

    范围内 flash_kernel_ex3_sci_flash_kernel 对于 F28002x、它们在连续存储器地址中执行 WRITE START、KEY 和 REV。 不应以与 F2838x 相同的方式工作?

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

    VIC、让我与团队成员一起检查一下、然后再联系您。

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

    尊敬的 Sira:

    我想我通过重新排列存储器部分的定义解决了这个问题。 我可能在每个闪存擦除周期内都试图写入两次相同的64位块。

    因此我成功地使用内核刷写内核并发送映像1。 但是、当我尝试从映像1执行分支到存储在内核中的 LiveDFU 函数时、可以看到 interrupt_illegalOperationHandler ()被触发。

    执行自动重锁后、我跳转至存储在地址0x80100处的 LiveDFU 函数。 为此、我使用中使用的方法  flashapi_ex3_live_firmware_update F28004x 的关系。

    这是我第一次见到你。  interrupt_illegalOperationHandler 我不知道原因是什么 .

    我已经检查 LiveDFU 函数是否位于存储器中的预期位置、真实就是这种情况。

    你有什么理由吗?

    是否可以将地址0x080100处的指令视为无效指令、尽管从内核映像运行时函数 LiveDFU()正在按预期运行?

    编辑:

    • 即使调用栈在地址0x08010E 处显示 SYSCTL_DELAY、这也是错误的。 此函数不位于该地址。
    • 我尝试0x080100以外的其他位置而没有成功。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    最新动态:  

    通过查看反汇编代码,我可以看到执行跳转到正确的地址,并开始执行 LiveDFU()函数。
    但是、跳转到 LdfuLoad()内存扇区时、没有要执行的指令。


    在我看来,这是正常的,因为 LdfuLoad()函数不是在活动图像中编译的,而是仅由静态代码编译的。

    因此、即使 使用此行将".TI.ramfunc"代码段正确地从闪存复制到 RAM:

    我们怎么能期望 RAM 包含 ldfuLoad()或 ldfuCopyData()的指令?

    我认为活动映像中缺少了一点、即从静态闪存将 ldfu 函数复制到正确的 RAM 地址。

    再次感谢您的帮助。

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

    尊敬的 Vic:  

    您是否能够针对项目共享您的.map 文件以查看 LdfuLoad 函数在内存中的放置位置?

    谢谢。此致、

    Charles

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

    VIC

    很抱歉、您仍然遇到问题。 请今天给我分析一下、看看我是否能确定这里可能发生的情况。

    我会在明天回复。

    谢谢!

    SIRA

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

    尊敬的 Vic:

    那么、我们今天究竟站在哪里:

    您能够将内核刷写到器件闪存中?

    是否可以使用上述内核将 Image1刷写到器件闪存中(使用 START、KEY 等正确写入)?

    使用此设置、您从外部主机发送 LFU 请求、并且执行从 Image1分支到内核、然后它会在某处跑到杂草中?

    在查看您的.map 文件时、我看到内核和图像1中使用了相同的 RAMGS10_13区域。 对于静态内核和 Image1、您的 RamfuncsRunStart 是相同的地址(0x17000)。 这意味着您想要从闪存复制到 RAM 的任何代码都将被复制(首先是内核)、然后被覆盖(当您对 Image1进行同样的闪存到 RAM 复制时)。

    应避免这种情况。 请为内核、图像1和图像2分配不同的闪存和 RAM 区域。

    "根据这一观察、我明白它为什么不起作用、但我不知道一种干净的方法来修复它。 Ldfuload 函数在闪存中刷写静态代码时出现、因此分区1可能应在使用之前将其复制到 RAM。"

    因此没有必要予以添加。 如上所述、无论静态内核中需要从 RAM 运行的任何内容(例如闪存 API 库、特定内核函数)、都应该在静态内核代码中使用 memcpy 将其从闪存复制到 RAM、这样就足够了。

    然后、应在 Image1中使用 memcpy 将需要从 RAM 运行的任何内容(例如、您希望在 LFU 期间运行的特定 ISR)从闪存复制到 RAM、这样就足够了。

    同样、您将在图像2中执行相同的操作(因此、在通过多个 LFU 时、它可以以乒乓方式工作)。

    请注意:下周我将会离职、但我希望我的上述回答会解除您的限制并帮助您取得进展。

    谢谢!

    SIRA