Linker Problems STM32 + FreeRTOS MPU

I am using the STM3210E_eval (the new Rev. with MPU) and the Sourcery GCC compiler. (FreeRTOS 7.0.0 and StdPeriph Lib 3.5) Thanks to the examples on stf12.org setting up FreeRtos without MPU was easy and worked great. However I am now trying to get the MPU-Port running.
I took the code from the “CORTEX_MPU_LPC1768_GCC_RedSuite” example and adjusted FreeRTOS.h, the adresses in the main code and the LCD routines for the STM32F103. Compiles just fine. The problem is the Linker Script. “Placeholders” like
    . = ORIGIN( SRAM ) + _Privileged_Data_Region_Size;
will cause the code to somehow bloat
c:/programme/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.5.2/../../../../arm-none-eabi/bin/ld.exe: FreeRtos_MPU-LPC_Example.elf section `.text' will not fit in region `FLASH'
c:/programme/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.5.2/../../../../arm-none-eabi/bin/ld.exe: region `FLASH' overflowed by 133201600 bytes
If you set the flash to 1000M look at the listfile you will see a gap of the size of 0x8004000. No code in between. Does anyone have a working Linker Script for the STM32 family and the MPU-port?
Or an explanation for the behavior? Regards, Torben

Linker Problems STM32 + FreeRTOS MPU

Please could you post the whole likner script.

Linker Problems STM32 + FreeRTOS MPU

I accidentally posted the placeholder thing for the Ram Region. Here is the whole linker:
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20018000;    /* end of 96K RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0;      /* required amount of heap  */
_Min_Stack_Size = 0x200; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
  
  FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1M
  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 96K
  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
}
/* Variables used by FreeRTOS-MPU. */
_Privileged_Functions_Region_Size = 16K;
_Privileged_Data_Region_Size = 256;
__FLASH_segment_start__ = ORIGIN( FLASH );
__FLASH_segment_end__ = __FLASH_segment_start__ + LENGTH( FLASH );
__privileged_functions_start__ = ORIGIN( FLASH );
__privileged_functions_end__ = __privileged_functions_start__ + _Privileged_Functions_Region_Size;
__SRAM_segment_start__ = ORIGIN( RAM );
__SRAM_segment_end__ = __SRAM_segment_start__ + LENGTH( RAM );
__privileged_data_start__ = ORIGIN( RAM );
__privileged_data_end__ = ORIGIN( RAM ) + _Privileged_Data_Region_Size;
/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH, then the priv. functions */
    privileged_functions :
    {
        KEEP(*(.isr_vector))
        *(privileged_functions)
    } > FLASH
  /* The program code and other data goes into FLASH */
  .text :
  {
     
    /* Non privileged code kept out of the first 16K or flash. -- Doesn't Work as expected */
    . = __privileged_functions_start__ + _Privileged_Functions_Region_Size; 
     . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    KEEP (*(.init))
    KEEP (*(.fini))
    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH
   .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
    .ARM : {
    __exidx_start = .;
      *(.ARM.exidx*)
      __exidx_end = .;
    } >FLASH
  .ARM.attributes : { *(.ARM.attributes) } > FLASH
  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >FLASH
  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } >FLASH
  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(.fini_array*))
    KEEP (*(SORT(.fini_array.*)))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } >FLASH
  /* used by the startup to initialize data */
  _sidata = .;
    /* zero initialized data */     
    privileged_data :
    {
        _bss = .;
        *(privileged_data)
        /* Non kernel data is kept out of the first 256 bytes of SRAM. */
    } > RAM 
    . = ORIGIN( RAM ) + _Privileged_Data_Region_Size;
  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss secion */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM
  
    /* Initialized data sections goes into RAM, load LMA copy after code */
  .data : AT ( _sidata )
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */
    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >RAM
  PROVIDE ( end = _ebss );
  PROVIDE ( _end = _ebss );
  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(4);
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(4);
  } >RAM
  /* MEMORY_bank1 section, code must be located here explicitly            */
  /* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
  .memory_b1_text :
  {
    *(.mb1text)        /* .mb1text sections (code) */
    *(.mb1text*)       /* .mb1text* sections (code)  */
    *(.mb1rodata)      /* read-only data (constants) */
    *(.mb1rodata*)
  } >MEMORY_B1
  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }
}
Regards, Torben

Linker Problems STM32 + FreeRTOS MPU

BUMP Does no one have an idea? Regards,
Torben

Linker Problems STM32 + FreeRTOS MPU

I faced exactly the same strange problem when adapted STM32 CMSIS linker script from this one. Solved by moving problematic line out of .text {} block an placing it just before block. But original script in example project works fine howewer. Looks like bug in linker.

Linker Problems STM32 + FreeRTOS MPU

Oops. Not solved, just seemed as solved. Placeholder moved out from .text block actually does nothing ! It doesn’t rewinds location. I wasted two days trying to get FreeRTOS MPU working until I found reason. But now I don’t know how to fix it !
I expect that codeline
. = __privileged_functions_start__ + _Privileged_Functions_Region_Size;
just rewinds current location to specified value and subsequent .text section will start being placed from this point. But it results in such linker map:
...
.text       0x08001dc8  0x8005780
        0x08004000  . = (__privileged_functions_start__ + _Privileged_Functions_Region_Size)
 *fill*     0x08001dc8  0x8004000   00
 *(.text*)
 .text      0x10005dc8  ...
 ...
It recognizes resulted address as size and makes zero-filled region with this size ! It is crazy ???
(Official CORTEX_MPU_LPC1768_GCC_RedSuite luckily works only because flash address origin starts with just small 0x0. It results in small memory waste and little misalignment between actual data placement and defined regions.) I’m using Yagarto ARM Toolchain 4.6.0 Does no one have an idea?

Linker Problems STM32 + FreeRTOS MPU

Found solution:
. += __privileged_functions_start__ + _Privileged_Functions_Region_Size - .;
Remaining placeholders in script must be converted to such manner.

Linker Problems STM32 + FreeRTOS MPU

Oops. No. __privileged_functions_start__ must be replaced with ORIGIN( FLASH ). I’m confused finally.

Linker Problems STM32 + FreeRTOS MPU

Posted a bug report