首页 > 解决方案 > 是否可以在 SRecord 中使用非绝对地址范围并将一些数据粘贴到二进制文件的最后一个字节上?

问题描述

我正在使用 STM32CubeIDE(带有 gcc 编译器的基于 Eclipse 的 IDE)为 ARM Cortex-M4 微控制器制作项目,并希望将整个固件的 CRC 嵌入到二进制文件的末尾。我已经修改了链接器脚本以创建一些放置在已编译二进制文件末尾的变量。这是我对链接器脚本的修改:

... linker script ...
  /* My section (it is the last section in linker script) */
  .end_of_code :
  {
    . = ALIGN(4);
    KEEP (*(.end_of_code.fwSize)) /* Force memory allocation even if variable is unused */
    KEPP (*(.end_of_code.fwCrc)) /* Force memory allocation even if variable is unused */

    _end_of_code = .; /* Get current address */
    _size_of_code = ABSOLUTE (_end_of_code - ORIGIN(FLASH)); /* Subtruct current address from start of image */
  } >FLASH

这是C中上述变量的声明:

// Some C file

extern uint32_t _size_of_code; // Linker variable

const __attribute__((section(".end_of_code.fwSize"))) uint32_t fwSize = (uint32_t) &_size_of_code;
const __attribute__((section(".end_of_code.fwCrc"))) uint32_t fwCrc = 0xFFFFFFFF;

使用链接描述文件创建的最后一个变量应该存储整个固件的 CRC32。我想使用 SRecord 脚本来计算 CRC 值,并希望能够像 C 代码中的普通变量一样引用它的值。

我的目标是制作 SRecord 脚本,它将使用-binary格式打开文件,用 SRecord 计算的 CRC32 替换最后 4 个字节,并用替换的 CRC 值进行输出。但我不明白如何将非绝对地址范围-crop放入或-exclude过滤器。我想做这样的事情:

# SRecord script
fw.bin -binary
-CRC32 -maximum-addr fw.bin -binary -4
-o fw_with_CRC.bin -binary

我的问题是:是否有可能以及如何在 SRecord 中使用相对地址?或者是否有可能以及如何用 SRecord 覆盖二进制文件末尾的一些数据?

关于替代解决方案:我知道我可以从链接器中删除fwCrc变量并创建如下内容:

#define FW_CRC_ADDR    ( ((uint32_t) &fwSize) + 0x04 )
#define GET_FW_CRC()   ( *(uint32_t *) FW_CRC_ADDR )

但这样的解决方案对我来说不可接受。我想要存储 CRC 值的变量。插入一些数据/变量而不是未使用的中断向量元素的解决方案也不可接受。

也许我可以接受fwCrc变量不分配任何内存并使用 SRecord 将 CRC 附加到二进制文件末尾的解决方案,但我不知道如何强制链接器不为 C 代码中使用的变量分配内存。

标签: cbinarymicrocontrollercrcsrecord

解决方案


我找到了对某人有帮助的解决方案,但它并没有直接回答我关于 SRecord 中相对寻址的问题。该解决方案描述了如何将 CRC 附加到固件映像并访问 C 中的 CRC 值,就像普通变量一样。

使用 STM32CubeIDE 生成的 GCC 编译器和链接器脚本对解决方案进行了测试。

  1. 存储 CRC 值的链接器部分的类型应更改为(NOLOAD). 它强制链接器不为二进制映像中分配给此部分的变量分配内存。更多信息(NOLOAD)可以在这里找到。
... linker script ...

  /* Last section in linker script */
  .end_of_code :
  {
    . = ALIGN(4);
    KEEP (*(.end_of_code.fwSize)) /* Last variable in flash memory */

    _end_of_code = .; /* Get current address */
    _size_of_code = ABSOLUTE (_end_of_code - ORIGIN(FLASH)); /* Subtruct current address from start of image */
  } >FLASH

  /* New section for CRC */
  .crc (NOLOAD) :
  {
    . = ALIGN(4);
    
    *(.crc.fwCrc))
    
    . = ALIGN(4);
  } >FLASH

... /DISCARD/ ...

} /* SECTIONS */
  1. 将 CRC 附加到固件的最大地址,例如在构建后命令执行期间:
srec_cat infile.bin -binary -STM32 -maximum-addr infile.bin -binary -o outfile.bin -binary
  1. 用 right 声明 C 变量__attribute__
const __attribute__((section(".crc.fwCrc"))) uint32_t fwCrc;

上述操作将创建附加 CRC 的固件映像。CRC 值可以像使用fwCrc变量的普通 C 变量一样访问。const使用了限定符,因为此变量的值存储在 FLASH 内存中,不能直接使用赋值运算符(如=.


推荐阅读