Arm Mbed and Pelion Device Management support forum

BLE OTA: Placing a section in linker

I am trying to enable Over the air updates using BLE on mbed-os for STM32WB55.

As a first step, i started with BLE_GattServer example at: https://github.com/ARMmbed/mbed-os-example-ble/tree/master/BLE_GattServer

I am trying to add MagicKeyValue as indicated in the document : AN5289 Section 7.5.7

For this i have modified the linker file as:

#if !defined(MBED_APP_START)
#define MBED_APP_START 0x08007000
#endif

#if !defined(MBED_APP_SIZE)
#define MBED_APP_SIZE 484K
#endif

#if !defined(MBED_BOOT_STACK_SIZE)
    #define MBED_BOOT_STACK_SIZE 0x400
#endif

STACK_SIZE = MBED_BOOT_STACK_SIZE;

/* Linker script to configure memory regions. */
/* Total: 79 vectors = 316 bytes (0x13C) to be reserved in RAM1 (192K) */
MEMORY
{
  FLASH (rx)  : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE
  /*RAM1 (rwx)  : ORIGIN = 0x2000013C + 0X04, LENGTH = 192K - 0x13C - 0X04 */
  RAM1 (xrw)  : ORIGIN = 0x20000004, LENGTH = 191k
  RAM2a (rw)  : ORIGIN = 0x20030000, LENGTH = 10K
  RAM2b (rw)  : ORIGIN = 0x20038000, LENGTH = 20K
}

/* Linker script to place sections and symbol values. Should be used together
 * with other linker script that defines memory regions FLASH and RAM.
 * It references following symbols, which must be defined in code:
 *   Reset_Handler : Entry of reset handler
 * 
 * It defines following symbols, which code can use without definition:
 *   __exidx_start
 *   __exidx_end
 *   __etext
 *   __data_start__
 *   __preinit_array_start
 *   __preinit_array_end
 *   __init_array_start
 *   __init_array_end
 *   __fini_array_start
 *   __fini_array_end
 *   __data_end__
 *   __bss_start__
 *   __bss_end__
 *   __end__
 *   end
 *   __HeapLimit
 *   __StackLimit
 *   __StackTop
 *   __stack
 *   _estack
 */
ENTRY(Reset_Handler)

SECTIONS
{

     //ota_region 0x08087940:

     .ota_region 0x08007140:
     {
         KEEP(*(TAG_OTA_START)) 
	 . = ALIGN(4);
     } >FLASH
  
    .text :
    {
        KEEP(*(.isr_vector))
        *(.text*)
        KEEP(*(.init))
        KEEP(*(.fini))

        /* .ctors */
        *crtbegin.o(.ctors)
        *crtbegin?.o(.ctors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
        *(SORT(.ctors.*))
        *(.ctors)

        /* .dtors */
        *crtbegin.o(.dtors)
        *crtbegin?.o(.dtors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
        *(SORT(.dtors.*))
        *(.dtors)
        *(.rodata*)

        KEEP(*(.eh_frame*))
    } > FLASH

    .ota_region_end :
    {
        . = ALIGN(4);  
	KEEP(*(TAG_OTA_END))
	. = ALIGN(4);
    } >FLASH

    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > FLASH

    __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    }  > FLASH
    __exidx_end = .;

    __etext = .;

    _sidata = .;

    .data : AT (__etext)
    {
        __data_start__ = .;
        _sdata = .;
        *(vtable)
        *(.data*)

        . = ALIGN(8);
        /* preinit data */
        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP(*(.preinit_array))
        PROVIDE_HIDDEN (__preinit_array_end = .);

        . = ALIGN(8);
        /* init data */
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP(*(SORT(.init_array.*)))
        KEEP(*(.init_array))
        PROVIDE_HIDDEN (__init_array_end = .);

        . = ALIGN(8);
        /* finit data */
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP(*(SORT(.fini_array.*)))
        KEEP(*(.fini_array))
        PROVIDE_HIDDEN (__fini_array_end = .);

        KEEP(*(.jcr*))
        . = ALIGN(8);
        /* All data end */
        __data_end__ = .;
        _edata = .;

    } > RAM1

    .bss :
    {
        . = ALIGN(4);
        __bss_start__ = .;
        _sbss = .;
        *(.bss*)
        *(COMMON)
        . = ALIGN(4);
        __bss_end__ = .;
        _ebss = .;
    } > RAM1

    .heap (COPY):
    {
        __end__ = .;
        end = __end__;
        *(.heap*)
        . = ORIGIN(RAM1) + LENGTH(RAM1) - STACK_SIZE;
        __HeapLimit = .;
    } > RAM1

    /* .stack_dummy section doesn't contains any symbols. It is only
     * used for linker to calculate size of stack sections, and assign
     * values to stack symbols later */
    .stack_dummy (COPY):
    {
        *(.stack*)
    } > RAM1

    .ble_stby_mem (NOLOAD) :
    {
      *(MAPPING_TABLE);
      *(MB_MEM1);
    } >RAM2a

    .ble_shared_no_ret (NOLOAD) :
    {
      *(MB_MEM2);
    } >RAM2b

    /* Set stack top to end of RAM1, and stack limit move down by
     * size of stack_dummy section */
    __StackTop = ORIGIN(RAM1) + LENGTH(RAM1);
    _estack = __StackTop;
    __StackLimit = __StackTop - STACK_SIZE;
    PROVIDE(__stack = __StackTop);

    /* Check if data + heap + stack exceeds RAM1 limit */
    ASSERT(__StackLimit >= __HeapLimit, "region RAM1 overflowed with stack")

    TAG_OTA_END(NOLOAD)    : { KEEP (*(TAG_OTA_END)) } >FLASH 

}

Here I have added two sections TAG_OTA_START and TAG_OTA_END.

In my main.cpp, I add:

PLACE_IN_SECTION(“TAG_OTA_END”) const volatile uint32_t MagicKeywordValue = 0x94448A29 ;
PLACE_IN_SECTION(“TAG_OTA_START”) const volatile uint32_t MagicKeywordAddress = (uint32_t)(&MagicKeywordValue);

This means that at TAG_OTA_START an address is stored for the value of MagicKeywordValue
This should be stored at TAG_OTA_START at the end of code in flash.

  • When I build and flash the bin file and check the device memory, I see the address of MagicKeywordValue stored at 0x08007140. When i check that address, i don’t see the MagicKeywordValue. When I add offset of 0x140 to the address stored at 0x08007140, I see the MagicKeywordValue offset by an additional 8 bytes.

Can somebody tell me why is the value stored at address offseted by 0x140 + 8bytes?

1 Like