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.

[参考译文] CC2652PSIP:从 RAM 和二进制文件执行函数以进行固件升级

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1217324/cc2652psip-execution-functions-from-ram-and-binary-file-for-firmware-upgrade

器件型号:CC2652PSIP

您好!

为了实现 CC2652PSIP 的固件升级功能、必须从 RAM 执行某些函数。 map-file 显示该函数位于 RAM 中、但二进制文件的大小大于0x20、000、000、000、二进制文件的预期大小为0x58、000。 二进制文件中似乎包含了 RAM 中的函数。

函数由以下人员声明:

__attribute__((section (".TI.ramfunc"))) u32 crcImageCheck (void);

cmd -文件内的段看起来像:

部分

.intvecs:> flash_start
.text:>> FLASH | FLASH_last_page
.const:>> FLASH | FLASH_LAST_PAGE
.constdata:>> FLASH | FLASH_LAST_PAGE
.rodata:>> FLASH | FLASH_LAST_PAGE
.cinit:> flash | flash_last_page
.pinit:>> FLASH | FLASH_LAST_PAGE
init_array:> flash | flash_last_page
.emb_text:>> flash | flash_last_page
.ccfg:> flash_last_page (高电平)

组> SRAM

.data
#ifndef cache_as_ram
.bss
#endif /* cache_as_RAM */
.vtable
.vtable_ram
vtable_ram
.sysmem
.TI.ramfunc
.nonretenvar
/*如果不将 ll.o 放置在这里,则将 ll.o 对象保留在 GPRAM 之外
警告#10068被抑制。*/
#ifdef cache_as_ram
LL_BSS

-- library=*ll_*.a. (.bss)
-- library=*ll_*.a. (.bss)
}
#endif /* cache_as_RAM */
}load_end (heapStart)

.stack:> SRAM (高电平) load_start (heapEnd)


#ifdef cache_as_ram

.bss:

*(.bss)
}> GPRAM
#endif /* cache_as_RAM */
}

post_BUILD 步骤如下所示:

"${CCS_INSTALL_ROOT}/utils/tiobj2bin/tiobj2bin "${BuildArtifactFileName}""${BuildArtifactFileBaseName}.bin""${CG_TOOL_ROOT}/bin/tiarmofd "${CG_TOOL_ROOT}/bin/tiarmhex "${CCS_INSTALL_ROOT}/utils/tiobj2bin/mkhex4bin "

对于从 RAM 运行函数的工程、应如何处理0x58、000字节的二进制文件? 闪存映像应包含这些功能、并在调制解调器启动时将它们复制到 RAM 中。

谢谢。

Alex   

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

    您好 Alex:

    您的.map 文件评估与二进制文件大小之间的差异在于、二进制文件孔洞(即初始化段0x58000至0x20000000之间的差距)由 tiobj2bin 工具填充。 由于孔洞必须通过填充来表示、因此权变措施包括创建两个单独的 bin 文件或使用不同的文件输出。  以下是一些相关的 E2E 主题:

    https://e2e.ti.com/f/1/t/935537 
    https://e2e.ti.com/f/1/t/1192341 

    此致、
    Ryan

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

    Ryan、感谢您这么快的回复。

    二进制文件的大小不是大问题:可以将其缩减为0x58000。 我担心的是、从 RAM 函数执行的位于 二进制文件中的地址0x20、000、000 (RAM)后面、我在闪存中找不到这些函数的副本。 它们最初必须位于闪存中并在启动时复制到 RAM 中。

    谢谢。

    Alex

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

    感谢您的澄清。  我建议您参阅 已链接的 TI 链接器命令文件入门指南中的从不同地址加载、从其他地址运行部分。   此参考设计还有多个相关的 E2E 主题。

    此致、
    Ryan

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

    谢谢。 二进制文件现在看起来正常、闪存升级函数的起始地址位于 RAM 中。 将一些函数从 闪存复制到 SRAM 的最简单方法是什么。 所有这些功能都位于不同而不相邻的位置。

    谢谢。

    Alex

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

    我建议使用 memcpy ( 如果代码使用了 osal 层、则可能为 osal_memcpy)。  我不会 在此时添加相关的 E2E 主题帖。  值得注意的是、BLE OAD 应用将使用静态 持久应用程序 、以避免将 应通过 OAD 更新持续存在的函数从闪存复制 到 RAM。  BLE5-Stack 用户指南的片上 OAD 部分介绍了这方面的内容

    此致、
    Ryan

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

    map 文件包含以下段:

    链接器生成的复制表

    ..........

    Bint @ 0002accc 记录:1、大小/记录:12、表大小:16
    .ti.ramfunc:load addr=0000003c、load size=0000033c、run addr=20000fe0、run size=0000033c、compression=none

    这意味着有一种机制可以复制函数 FLASH -> SRAM、但加载 addr=0000003c 是错误的。 项目的哪个部分定义了"加载开始"地址?

    此致、

    Alex

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

    此处是 TI Arm Clang 编译器工具用户指南的链接。  我将请 TI 编译器团队对您的疑问进一步做出评论。

    此致、
    Ryan

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

    尊敬的 Alex:

    我不确定自线程开始以来您的项目是如何更改的、但您应该在.TI.ramfunc 的链接器命令文件中包含明确的放置位置、以确保其加载到您想要的地址(在复制到 SRAM 之前)

    .TI.ramfunc : {} load=FLASH, run=RAM, table(BINIT)

    当然、Ryan 链接到上述 TI 链接器入门中介绍了这方面的内容、因此您可能已经在做这方面了。 您也可以为"load="使用硬编码地址。  您能否展示链接器命令文件放置示例?  我想了解加载地址出错的原因。

    谢谢。

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

    您好、Alan!

    我的工程基于 CC2652PSIP 的"simple_peripheral"工程、我的 CCS 版本 v.12.2.0.202212151800、我的 silmplelink_cc13xx_cc26xx_SDK_6_40_00_13。

    我尝试了几个选项来确定这个部分,并得到错误的"load addr"或 错误:

    选项1

     .TI.ramfunc   :  {}load = flash、run = SRAM、table (BINT)

    从.map -文件:

    链接器生成的复制表

    Bint @ 0002accc 记录:1、大小/记录:12、表大小:16
    .ti.ramfunc:load addr=0000003c、load size=0000033c、run addr=20000fe0、run size=0000033c、compression=none

    备选案文2.

     .TI.ramfunc   :  {}load = flash、run = SRAM、load_start = 0x2accc、load_end = 0x2b008、table (BINT)

    五颗星 CCS 报告不能使用"="的错误、只能使用()。  

    选项3.

     .TI.ramfunc   :  {}load = flash、run = SRAM、load_start (0x2accc)、load_end (0x2b008)、table (BINT)

    五颗星  CCS 报告错误 "需要" "而不是"0x2accc"

    备选案文4.

    _RamfuncsLoadStart = 0x2accc

    _RamfuncsLoadEnd = 0x2b008;

     .TI.ramfunc   :  {}load = flash、run = SRAM、load_start (_RamfuncsLoadStart)、load_end (_RamfuncsLoadEnd)、table (BINT)

    五颗星  CCS 报告: 警告#10190-D:正在重新定义绝对符号"_RamfuncsLoadStart"

    从.map -文件:

    Bint @ 0002accc 记录:1、大小/记录:12、表大小:16
    .ti.ramfunc:load addr=0000003c、load size=0000033c、run addr=20000fe0、run size=0000033c、compression=none

    备选案文5.

     .TI.ramfunc   :  {}load = flash、run = SRAM、load_start (_RamfuncsLoadStart)、load_end (_RamfuncsLoadEnd)、table (BINT)

    从.map -文件:

    Bint @ 0002accc 记录:1、大小/记录:12、表大小:16
    .ti.ramfunc:load addr=0000003c、load size=0000033c、run addr=20000fe0、run size=0000033c、compression=none

    我可以假设符号: _RamfuncsLoadStart、_RamfuncsLoadEnd 取自文件 simple_peripheral_LP_CC2652PSIP_tirtos7_ticlang_linkInfo.xml  



    _RamfuncsLoadStart
    0x3c


    _RamfuncsLoadEnd
    0x378

    工程配置中的哪些参数用于该文件中符号_RamfuncsLoadStart 的初始化? 神奇地址是什么:0x3C?  如何修复它?

    谢谢。

    Alex

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

    尊敬的 Alex:

    目前、链接器正在选择闪存区域内的一个位置来放置段。  我没有看到链接器命令文件的存储器区域配置、但大概地址 ix 0x3x 位于该区域内。  

    LOAD_START 和 LOAD_END 运算符只能用于识别链接器将生成的分别包含所选起始地址和结束地址的符号。  

    为了改变负载的实际位置、您需要调整"load=flash"设置、方法是根据您想要的位置创建一个新的存储器区域、或手动编码所需的地址。 例如:

    .TI.ramfunc     :   {} load = 0x2accc, run = SRAM

    您还可以指定段放置的对齐要求、文档中对此进行了说明。

    -艾伦

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

    您好、Alan!

    可以手动编码所需的地址、但每次我构建项目时地址都会不同。 更普遍的解决方案更可取。 您能否提供有关您推荐的其他解决方案的更多信息?  

    此致、

    Alex

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

    尊敬的 Alex:

    这将取决于链接器命令文件中存储器范围的配置。  查看 编译器指南中关于 MEMORY 指令的这一部分;您需要确保您的内存区域配置正确、然后您可以将.TI.ramfunc 加载放置在正确的位置。

    .TI.ramfunc     :   {} load = YOURREGION, run = SRAM

    根据我在上面看到的内容、目前.TI.ramfunc 正在被放置在名为 FLASH 的存储器区域中、此区域似乎没有根据您预期的存储器地址范围进行配置。

    -艾伦

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

    您好、Alan!

    存储器部分如下所示:

    */李国坚女士(香港
    *内存大小
    */
    #define FLASH_BASE 0x00000000
    #define GPRAM_BASE 0x11000000
    #define RAM_BASE 0x20000000
    #define ROM_BASE 0x10000000

    #define flash_size 0x00058000
    #define GPRAM_SIZE 0x00002000
    #define RAM_SIZE 0x00014000
    #define ROM_SIZE 0x00040000

    #define RTOS_RAM_SIZE 0x0000012C
    #define reserved_RAM_SIZE ROM_1 0x00000B08
    #define reserved_RAM_SIZE ROM_2 0x00000EB3

    */李国坚女士(香港
    *内存定义
    * /

    */李国坚女士(香港
    * RAM
    */
    #if defined (FLASH_ROM_Build)
    #if (flash_rom_build == 1)
    #define reserved_RAM_SIZE_AT_START 0
    #define reserved_RAM_SIZE_AT_END reserved_RAM_SIZE_ROM_1
    #else //(flash_rom_build == 2)
    #define reserved_RAM_SIZE _AT_START (RTOS_RAM_SIZE + RESERVED_RAM_SIZE ROM_2)
    #define reserved_RAM_SIZE_AT_END 0
    #endif
    #else /*仅闪存*/
    #define reserved_RAM_SIZE_AT_START 0
    #define reserved_RAM_SIZE_AT_END 0
    #endif // flash_rom_build

    #define RAM_START (RAM_BASE + RESERVED_RAM_SIZE_AT_START)
    #ifdef icall_ram0_start
    #define RAM_END (ICALL_RAM0_START - 1)
    #else
    #define RAM_END (RAM_BASE + RAM_SIZE -保留_RAM_SIZE_AT_END - 1)
    #endif /* icallL_ram0_start */

    /*对于 ROM 2器件,需要分配并保留以下段*/
    #define RTOS_RAM_START RAM_BASE
    #define RTOS_RAM_END (RAM_BASE + RTOS_RAM_SIZE - 1)

    */李国坚女士(香港
    *闪存
    */

    #define FLASH_START FLASH_BASE
    #define WORD_SIZE 4.

    #define page_size 0x2000

    #ifdef page_align
    #define FLASH_MEM_ALIGN PAGE_SIZE
    #else
    #define FLASH_MEM_ALIGN WORD_SIZE
    #endif /* page_align */

    #define page_mask 0xFFFFE000

    /*最后一个闪存页保留用于应用程序。 */
    #define NUM_RESERVED_FLASH_PAGES 1.
    #define reserved_flash_size (NUM_reserved_flash_pages * page_size)

    /*检查是否需要与层叠图像进行页对齐。 如果是、请勿链接
    *放入堆栈共享的页面。
    */
    #ifdef ICALL_STACK0_START
    #ifdef page_align
    #define ADJ_ICALL_STACK0_START (ICALL_STACK0_START * PAGE_MASK)
    #else
    #define ADJ_ICALL_STACK0_START ICALL_STACK0_START
    #endif /* page_align */

    #define FLASH_END (ADJ_ICALL_STACK0_START - 1)
    #else
    #define FLASH_END (FLASH_BASE + FLASH_SIZE - reserved_FLASH_size - 1)
    #endif /* ICALL_STACK0_START */

    #define flash_last_page_start (flash_size - page_size)

    外部闪存

    FLASH (RX):origin = flash_start、length =(flash_end - flash_start + 1)

    FLASH_LAST_PAGE (RX):origin = FLASH_LAST_PAGE_START、length = PAGE_SIZE

    #if (已定义(FLASH_ROM_BUILD)&&(FLASH_ROM_BUILD == 2))
    RTOS_SRAM (rwx):origin = RTOS_RAM_START、length =(RTOS_RAM_END - RTOS_RAM_START + 1)
    #endif
    SRAM (rwx):origin = RAM_START、length =(RAM_END - RAM_START + 1)

    #ifdef cache_as_ram
    GPRAM (rwx):origin = GPRAM_start、length = GPRAM_SIZE
    #endif /* cache_as_RAM */
    }

    此致、

    Alex

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

    尊敬的 Alex:

    假设闪存的存储器区域定义为:

    FLASH (RX):origin = flash_start、length =(flash_end - flash_start + 1)

    如果 FLASH_start 定义为 0x00000000、并且由于.TI.ramfunc 放置在闪存中(用于加载)、链接器只需选择该区域中的可用地址来放置可以容纳它的段、最终为0x0000003c。  如果地址不正确、您必须创建一个新的存储器区域、用于适当放置段。  本文档介绍了如何执行该操作。

    -艾伦

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

    您好、Alan!

    起始地址  0x0000003c,位于 Vector Addresses (向量地址)区域,令人困惑。 由于当前未使用矢量15及以上的矢量、因此它解释了一切。  符号 _RamfuncsLoadStart 和_RamfuncsLoadEnd 是根据这一事实确定的。 重定位到 SRAM 函数后可以正常工作。

    谢谢、

    Alex