我正在使用 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 值进行输出。但我不明白如何将非绝对 address-range 放入 -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 代码中使用的变量分配内存。
我找到了对某人有帮助的解决方案,但它并不能直接回答我关于 SRecord 中相对寻址的问题。该解决方案描述了如何将 CRC 附加到固件映像并像普通变量一样访问 C 中的 CRC 值。
解决方案使用 STM32CubeIDE 生成的 GCC 编译器和链接器脚本进行了测试。
(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 */
srec_cat infile.bin -binary -STM32 -maximum-addr infile.bin -binary -o outfile.bin -binary
__attribute__
声明C变量:const __attribute__((section(".crc.fwCrc"))) uint32_t fwCrc;
上述操作将创建附加了 CRC 的固件映像。可以使用
fwCrc
变量像普通 C 变量一样访问 CRC 值。使用const
限定符,因为该变量的值存储在FLASH存储器中,不能直接用赋值运算符更改。