如何将数据插入到MCU的编译二进制文件中

时间:2015-05-08 08:35:55

标签: c linker microcontroller ld linker-scripts

我正在尝试将二进制部分的md5哈希值插入到二进制文件中,以便跟踪MCU FW版本。

我接近这样: 我在链接脚本中将闪存拆分为两部分

MEMORY                                                                                                  
{                                                                                                       
FLASH0 (rx)      : ORIGIN = 0x8000000, LENGTH = 64K - 16                                                
FLASH1 (r)       : ORIGIN = 0x800FFF0, LENGTH = 16                                                      
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 8K                                                       
} 

然后我指定了一个输出部分:

  .fw_version :                                                                                         
  {                                                                                                     
    KEEP(*(.fw_version))                                                                                
  } >FLASH1

接下来,我的firmware_version.c文件只包含:

#define FW_VERSION_SIZE 16                                                                              

const unsigned char FW_VERSION[FW_VERSION_SIZE]                                                         
  __attribute__((section(".fw_version"), used)) = {0};

然后在编译二进制文件并使用objcopy创建.bin文件后,我有一个65536 B大文件,我将该文件拆分为65520字节,对第一部分执行md5校验和并将其插入第二部分部分(16 B)。最后我做cat parta partb > final.bin

当我用hexdump检查这个二进制文件时,我可以看到md5校验和确实在最后。 使用objdump -h我得到:

...
8 .fw_version   00000010  0800fff0  0800fff0  00017ff0  2**2
...

objdump -t给出:

...
0800fff0 g     O .fw_version    00000010 FW_VERSION
...

我认为这意味着我可以使用FW_VERSION[i]从mcu fw中获取md5校验和的第i部分但是当我在gdb中检查内存时,我得到它全部归零喜欢它永远不会改变。

我在这里缺少什么?

[编辑]该设备是通过gdb编程的stm32f030c8t6手臂皮质m0。

1 个答案:

答案 0 :(得分:0)

就像我在这个问题上评论一样,我发现它不起作用的(一个)原因是当我在使用gdb编程时加载.elf文件时操作.bin文件。 如果我使用程序员或引导程序将.bin文件下载到目标文件,它应该(可能)有效。

我找到了更好的(我认为)这样做的方式。

  1. 将项目中的所有源代码编译为.o文件。
  2. cat * .o> /tmp/tmp.something_unique。我在Makefile
  3. 中使用了$(shell mktemp)
  4. openssl dgst -md5 -binary /tmp/tmp.something_unique> version_file
  5. objcopy -I binary -O elf32-littlearm -B arm version_file v_file.o
  6. linkscript有一个.fw_version : { KEEP(v_file.o(.data)) } >FLASH1
  7. 部分
  8. 链接申请
  9. 应用程序中的
  10. 通过extern unsigned char _binary_version_file_start; uint8_t *FW_VERSION = &_binary_version_file_start; const size_t FW_VERSION_SIZE = (size_t) &_binary_version_file_size;获取版本号的地址。请注意&的使用是正确的。
  11. 这将导致校验和被接收从源编译的所有对象,然后此校验和将链接到目标中闪存的二进制文件。