How to make ARM GCC linker put a version number at a fixed address at the end of a memory section?

0

I'm developing firmware update code for a Cortex-M4 based system and need a way for my firmware to obtain the version number of the separately-linked boot loader so I can determine if it must be updated. The makefile I inherited currently puts the build date/time at the end of the code, but it moves if code is added or removed.

I attempted to do this by defining a new memory section called .version and modifying the loader script to place it near the end of flash memory just before an existing section call .binfo, and including a header file containing the version number with a attribute that puts it in that section in main.c. The loader script I started with looks like this (with extraneous parts replaced by "...").

MEMORY
{
  rom      (rx)  : ORIGIN = 0x00000000, LENGTH = 16K
  ram      (rwx) : ORIGIN = 0x20000000, LENGTH = 192K

...

    . = ALIGN(4);
    _end = . ;

    _binfo_start = 16K - 4 * 4;
    .binfo _binfo_start : {
      KEEP(*(.binfo)) ;
    } > rom
}

I changed this to:

MEMORY
  rom      (rx)  : ORIGIN = 0x00000000, LENGTH = 16K
  ram      (rwx) : ORIGIN = 0x20000000, LENGTH = 192K

...

    . = ALIGN(4);
    _end = . ;

    _version_start = 16K - 4 * 4 - 2;    /* new, intended to reserve 2 bytes for .version before .binfo */
    .version _version_start : {
      KEEP(*(._version)) ;
    } > rom                              /* end new */

    _binfo_start = 16K - 4 * 4;
    .binfo _binfo_start : {
      KEEP(*(.binfo)) ;
    } > rom
}

I understand the " > rom" after .binfo to constrain .binfo to lie entiredly inside rom, so I omitted it bootloaderVersion.h in included in main.c, and looks like this:

#ifndef BLVERSION_H
#define BLVERSION_H

#define BLVERSIONMAJOR 0x00
#define BLVERSIONMINOR 0x01
#define BLVERSION (BLVERSIONMAJOR << 8 | BLVERSIONMINOR)

 __attribute__((section(".version"))) __attribute__((__used__)) const uint16_t blVersion = BLVERSION;

#endif

It builds, but I don't see anything in the .bin file before 0x3FF0 (where binfo resides). When I look at the loader with Segger Ozone I see that bootloaderVersion.h was included but consumed no memory.

What am I doing wrong?

Incidentally, binfo is filled as follows:

__attribute__((section(".binfo"))) __attribute__((__used__)) const UF2_BInfo binfo = {
#if USE_MSC_HANDOVER
    .handoverMSC = handover,
#endif
#if USE_HID_HANDOVER
    .handoverHID = hidHandoverLoop,
#endif
    .info_uf2 = infoUf2File,
};
gcc
linker
bootloader
asked on Stack Overflow Apr 16, 2020 by Sapient Hetero

1 Answer

0

Found the problem; it was a copy/paste error;

KEEP(*(._version)) ;

should be:

KEEP(*(.version)) ;   /* no backspace before version */

Now it works perfectly.

answered on Stack Overflow Apr 16, 2020 by Sapient Hetero

User contributions licensed under CC BY-SA 3.0