lpcware

1768 FreeRTOS xHeep __BSS(RAM) problems

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by FlySnake on Wed Jun 13 02:33:24 MST 2012
Hello everyone
Please help me figure out what's going wrong

heap2.c
static union xRTOS_HEAP
{
#if portBYTE_ALIGNMENT == 8
volatile portDOUBLE dDummy;
#else
volatile unsigned long ulDummy;
#endif
unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
} xHeap __BSS(RAM2);

But if I do this I get HardFaults after starting scheduler. It could be either IMPRECISERR (CFSR = 0x400) or INVSTATE (CFSR = 0x20000). Interestingly that if I walk through the code step by step with debugger it may work OK or falls in these faults on random instructions. Then I added task which just prints "hello" to uart and goes to vTaskDelay for a 1 second, and all other tasks (this problem occured in real project) are disabled. It always fails in this vTaskDelay.
#define configTOTAL_HEAP_SIZE( ( size_t ) ( 20 * 1024 ) )

It works OK when xHeep placed in RamLoc32.
It also works if I place another big static array in RamAHB32.
In map file I see those static arrays starting at 0x2007C000 address - correct address of RamAHB32. But FreeRTOS's heap wouldn't work in this section.

Linker scripts
MEMORY
{
  /* Define each memory region */
  MFlash512 (rx) : ORIGIN = 0x4000, LENGTH = 0x3c000 /* 240k */
  RamLoc32 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 32k */
  RamAHB32 (rwx) : ORIGIN = 0x2007c000, LENGTH = 0x8000 /* 32k */

}
  /* Define a symbol for the top of each memory region */
  __top_MFlash512 = 0x4000 + 0x3c000;
  __top_RamLoc32 = 0x10000000 + 0x8000;
  __top_RamAHB32 = 0x2007c000 + 0x8000;

MFlash512 starts at 0x4000 because of bootloader, but without it (starting at 0x0000) all symptoms are the same.
ENTRY(ResetISR)

SECTIONS
{

/* MAIN TEXT SECTION */
.text : ALIGN(4)
{
FILL(0xff)
KEEP(*(.isr_vector))

/* Global Section Table */
. = ALIGN(4) ;
__section_table_start = .;
__data_section_table = .;
LONG(LOADADDR(.data));
LONG(    ADDR(.data)) ;
LONG(  SIZEOF(.data));
LONG(LOADADDR(.data_RAM2));
LONG(    ADDR(.data_RAM2)) ;
LONG(  SIZEOF(.data_RAM2));
__data_section_table_end = .;
__bss_section_table = .;
LONG(    ADDR(.bss));
LONG(  SIZEOF(.bss));
LONG(    ADDR(.bss_RAM2));
LONG(  SIZEOF(.bss_RAM2));
__bss_section_table_end = .;
__section_table_end = . ;
/* End of Global Section Table */


*(.after_vectors*)

*(.text*)
*(.rodata .rodata.*)
. = ALIGN(4);

} > MFlash512

/*
* for exception handling/unwind - some Newlib functions (in common
* with C++ and STDC++) use this.
*/
.ARM.extab : ALIGN(4)
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > MFlash512
__exidx_start = .;

.ARM.exidx : ALIGN(4)
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > MFlash512
__exidx_end = .;

_etext = .;


.data_RAM2 : ALIGN(4)
{
   FILL(0xff)
*(.data.$RAM2*)
*(.data.$RamAHB32*)
   . = ALIGN(4) ;
} > RamAHB32 AT>MFlash512

/* MAIN DATA SECTION */

.uninit_RESERVED : ALIGN(4)
{
KEEP(*(.bss.$RESERVED*))
} > RamLoc32

.data : ALIGN(4)
{
FILL(0xff)
_data = .;
*(vtable)
*(.data*)
. = ALIGN(4) ;
_edata = .;
} > RamLoc32 AT>MFlash512


.bss_RAM2 : ALIGN(4)
{
*(.bss.$RAM2*)
*(.bss.$RamAHB32*)
   . = ALIGN(4) ;
} > RamAHB32

/* MAIN BSS SECTION */
.bss : ALIGN(4)
{
_bss = .;
*(.bss*)
*(COMMON)
. = ALIGN(4) ;
_ebss = .;
PROVIDE(end = .);
} > RamLoc32

PROVIDE(_pvHeapStart = .);
PROVIDE(_vStackTop = __top_RamLoc32 - 0);
}

Outcomes