1768 FreeRTOS xHeep __BSS(RAM) problems

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

1768 FreeRTOS xHeep __BSS(RAM) problems

371 Views
lpcware
NXP Employee
NXP Employee
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);
}
0 Kudos
3 Replies

308 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by  on Sat Jun 16 11:53:08 MST 2012
Glad you got it working.

[I think maybe you misunderstood my suggestion that peripherals were using the RAM.  I didn't mean the peripherals were mapped to that area, but Ethernet and USB buffers controlled by DMA would normally use that RAM]
0 Kudos

308 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by FlySnake on Sat Jun 16 11:48:17 MST 2012
Thanks for reply!
__BSS(RAM2) is exactly AHB RAM. This is macro provident by CodeRed.
This RAM region is not used by peripherals. This is just another free RAM region. It is defined in space 0x2007C000 - 0x20083FFF. But peripherals starts at 0x2009C000. http://www.nxp.com/documents/user_manual/UM10360.pdf page 12 "Memory map"
Probably I found the problem: alignment. I had configMINIMAL_STACK_SIZE 56. When I've changed it to 64 the program started to work.
0 Kudos

308 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by  on Thu Jun 14 02:24:04 MST 2012
I am familiar with the code, so know the change you have made, I doubt anybody else looking at this will be able to provide an answer as you have not actually said what you changed.

From the look of it, you are attempting to put the xHeap block into __BSS(RAM2) which is in AHB RAM.  I'm not sure about the syntax [I would normally use __attribute__section((""))], but assuming the syntax is correct,  so I think the question is why can the stacks not be in AHB RAM?

That RAM by convention is used by peripherals (USB, Ethernet).  Do you have anything enabled that might be overwriting that RAM?

You can adapt heap_x.c to define a pointer to the start of AHB RAM, rather than defining an array of fixed size.  I'm pretty sure I have done that before without a problem, but can't be sure.  I know I have done a similar thing with Ethernet buffers which are accessed both by the DMA and C functions.
0 Kudos