I am trying to use core-coupled memory (CCMRAM) of my cortex-m4 (STM32F407). It works fine with Keil MDK-ARM but gcc-arm-none-eabi ignores __attribute__((section("CCMRAM")))
.
#define configTOTAL_HEAP_SIZE 1000*1024
#define region1_HEAP_SIZE (40*1024)
#define region2_HEAP_SIZE (configTOTAL_HEAP_SIZE - region1_HEAP_SIZE)
static uint8_t ucHeap1[ region1_HEAP_SIZE ] __attribute__((section("CCMRAM")));
static uint8_t ucHeap2[ region2_HEAP_SIZE ];
const HeapRegion_t xHeapRegions[] =
{
{ ucHeap1, sizeof(ucHeap1) },
{ ucHeap2, sizeof(ucHeap2) },
{ NULL, 0 } /* Terminates the array. */
};
According to manual I also tried to initialize ucHeap1
static uint8_t ucHeap1[ region1_HEAP_SIZE ] __attribute__((section("CCMRAM"))) = {0};
But does no effect.
Map-file contains nothing about ucHeap1
. GCC compiles with no warnings about attribute. But fail to link because of:
arm-none-eabi/bin/ld: avds.elf section `.bss' will not fit in region `RAM'
arm-none-eabi/bin/ld: region `RAM' overflowed by 55032 bytes
These 55032 should be allocated in CCMRAM. But it tries to use RAM. Please help me to understand what to do to make it work.
Linker script:
ENTRY(Reset_Handler)
_estack = 0x20000000 + 128K - 1;
_Min_Heap_Size = 0;
_Min_Stack_Size = 0x200;
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
}
SECTIONS
{
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} >FLASH
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
*(.glue_7)
*(.glue_7t)
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .;
} >FLASH
.rodata :
{
. = ALIGN(4);
*(.rodata)
*(.rodata*)
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >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 (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
_sidata = LOADADDR(.data);
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} >RAM AT> FLASH
_siccmram = LOADADDR(.ccmram);
.ccmram :
{ . = ALIGN(4);
_sccmram = .;
*(.ccmram)
*(.ccmram*)
. = ALIGN(4);
_eccmram = .;
} >CCMRAM AT> FLASH
. = ALIGN(4);
.bss :
{
_sbss = .;
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
} >RAM
._user_heap_stack :
{
. = ALIGN(4);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(4);
} >RAM
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
.ccmram
section name is not CCMRAM
. Note that sections with a leading dot should be by a small ignored convention left to implementations. So prefer just section names without leading dot.
Remove your .ccmram : { ... }
and replace it by:
.ccmram : {
. = ALIGN(4);
_sccmram = .;
KEEP(*(CCMRAM)) # section is named CCMRAM __not__ .ccmram and __not__ .ccmram*
. = ALIGN(4);
_eccmram = .;
} >CCMRAM AT> FLASH
after that change:
$ arm-none-eabi-gcc main.c -Wl,-T,./linker.ld --specs=nosys.specs && arm-none-eabi-nm ./a.out | grep ucHeap
/usr/lib/gcc/arm-none-eabi/10.2.0/../../../../arm-none-eabi/bin/ld: warning: cannot find entry symbol Reset_Handler; defaulting to 0000000008000000
10000000 d ucHeap1
20000434 b ucHeap2
Or alternatively you could change __attribute__((section("CCMRAM")))
to __attribute__((section(".ccmram")))
or to __attribute__((section(".ccmram*")))
to match section names used in linker script.
Your .bss
section could be overflowing nonetheless. As in my tests configTOTAL_HEAP_SIZE
macro was undefined, region2_HEAP_SIZE
was - 40*1024
which is negative so wraped around and resulted in a big positive number.
I tested with:
cat >Makefile <<EOF
all:
arm-none-eabi-gcc main.c -Wl,-T,./linker.ld --specs=nosys.specs && arm-none-eabi-nm ./a.out | grep ucHeap
EOF
cat >linker.ld <<EOF
ENTRY(Reset_Handler)
_estack = 0x20000000 + 128K - 1;
_Min_Heap_Size = 0;
_Min_Stack_Size = 0x200;
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
}
SECTIONS
{
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} >FLASH
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
*(.glue_7)
*(.glue_7t)
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .;
} >FLASH
.rodata :
{
. = ALIGN(4);
*(.rodata)
*(.rodata*)
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >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 (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
_sidata = LOADADDR(.data);
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} >RAM AT> FLASH
.ccmram :
{
. = ALIGN(4);
_sccmram = .;
KEEP(*(CCMRAM))
. = ALIGN(4);
_eccmram = .;
} >CCMRAM AT> FLASH
. = ALIGN(4);
.bss :
{
_sbss = .;
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
} >RAM
._user_heap_stack :
{
. = ALIGN(4);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(4);
} >RAM
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
EOF
cat >main.c <<EOF
#include <stdint.h>
#include <stddef.h>
static uint8_t ucHeap1[ 10 ] __attribute__((section("CCMRAM")));
static uint8_t ucHeap2[ 20 ];
typedef struct {
uint8_t *p;
size_t s;
} HeapRegion_t;
const HeapRegion_t xHeapRegions[] =
{
{ ucHeap1, sizeof(ucHeap1) },
{ ucHeap2, sizeof(ucHeap2) },
{ NULL, 0 } /* Terminates the array. */
};
int main() {
return xHeapRegions[1].s;
}
EOF
__attribute__((section("CCMRAM")));
you do not have section CCMRAM
. You have section .ccmram
.
User contributions licensed under CC BY-SA 3.0