I'm using LPCXpresso IDE and MCU is LPC1759.
I want to allocate a static array which will be used as heap for RTOS. The size of this array is 32 KB and the size of firmware (.bin file) increases by 32 KB, because initialization of buffer will be placed in .data section. So i want to move it into .noinit section:
__NOINIT(RAM2) uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
But after this directive, this initiailization moved from .data section into .bss section and size of firmware wasn't changed.
Below is my linker script:
ENTRY(ResetISR)
SECTIONS
{
/* MAIN TEXT SECTION */
.text : ALIGN(4)
{
FILL(0xff)
__vectors_start__ = ABSOLUTE(.) ;
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*)
} >MFlash512
.text : ALIGN(4)
{
*(.text*)
*(.rodata .rodata.* .constdata .constdata.*)
. = ALIGN(4);
/* C++ constructors etc */
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
KEEP(*(.fini));
. = ALIGN(4);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
. = ALIGN(4);
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
. = ALIGN(4);
/* End C++ */
} > 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 section for RamAHB32 */
.data_RAM2 : ALIGN(4)
{
FILL(0xff)
PROVIDE(__start_data_RAM2 = .) ;
*(.ramfunc.$RAM2)
*(.ramfunc.$RamAHB32)
*(.data.$RAM2*)
*(.data.$RamAHB32*)
. = ALIGN(4) ;
PROVIDE(__end_data_RAM2 = .) ;
} > RamAHB32 AT>MFlash512
/* MAIN DATA SECTION */
.uninit_RESERVED : ALIGN(4)
{
KEEP(*(.bss.$RESERVED*))
. = ALIGN(4) ;
_end_uninit_RESERVED = .;
} > RamLoc32
/* Main DATA section (RamLoc32) */
.data : ALIGN(4)
{
FILL(0xff)
_data = . ;
*(vtable)
*(.ramfunc*)
*(.data*)
. = ALIGN(4) ;
_edata = . ;
} > RamLoc32 AT>MFlash512
/* BSS section for RamAHB32 */
.bss_RAM2 (NOLOAD): ALIGN(4)
{
PROVIDE(__start_bss_RAM2 = .) ;
*(.bss.$RAM2*)
*(.bss.$RamAHB32*)
. = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
PROVIDE(__end_bss_RAM2 = .) ;
} > RamAHB32
/* MAIN BSS SECTION */
.bss : ALIGN(4)
{
_bss = .;
*(.bss*)
*(COMMON)
. = ALIGN(4) ;
_ebss = .;
PROVIDE(end = .);
} > RamLoc32
/* NOINIT section for RamAHB32 */
.noinit_RAM2 (NOLOAD) : ALIGN(4)
{
*(.noinit.$RAM2*)
*(.noinit.$RamAHB32*)
. = ALIGN(4) ;
} > RamAHB32
/* DEFAULT NOINIT SECTION */
.noinit (NOLOAD): ALIGN(4)
{
_noinit = .;
*(.noinit*)
. = ALIGN(4) ;
_end_noinit = .;
} > RamLoc32
PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);
PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0);
/* ## Create checksum value (used in startup) ## */
PROVIDE(__valid_user_code_checksum = 0 -
(_vStackTop
+ (ResetISR + 1)
+ (NMI_Handler + 1)
+ (HardFault_Handler + 1)
+ (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */
+ (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */
+ (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */
) );
}
Thank you. Now it's clear, why bss shows additionally size of .noinit section.
.bss is never downloaded, so has no presence in the .axf file.The arm-none-eabi-size utility shows you the size difference (with/without the buffer) as .bss likely because it's the closest data type to .noinit. If you think there's something else going on, you'll at least need to provide the before and after .axf files.
Thanks and regards,
LPCXpresso Support
Yes, i have the same.
.bss_RAM2 0x2007ca00 0x0
and .noinit
.noinit_RAM2 0x2007ca00 0x7000
*(.noinit.$RAM2*)
.noinit.$RAM2 0x2007ca00 0x7000 ./FreeRTOS/src/heap_4.o
0x2007ca00 ucHeap
*(.noinit.$RamAHB32*)
0x20083a00 . = ALIGN (0x4)
But the output of converter is next:
text data bss dec hex filename
54964 3736 29624 88324 15904 firmware.axf
The size of firmware .bin file is increased of 28 KB after buffer allocation.
There seems to be some confusion. I made a similar heap4.c modification. The difference being, I removed the static allocation so it shows up in the map file. My heap size is 10K.
__NOINIT(RAM2) uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
Here's the information in the map file:
.noinit_RAM2 0x2f000000 0x2800
*(.noinit.$RAM2*)
.noinit.$RAM2 0x2f000000 0x2800 ./freertos/heap_4.o
0x2f000000 ucHeap
What might be confusing to you is if you search the map file for the ucHeap[] address you might see something like this:
.bss_RAM2 0x2f000000 0x0
[!provide] PROVIDE (__start_bss_RAM2, .)
Same address, but zero length. The .noinit buffer is at this address.
Thanks and regards,
LPCXpresso Support
Thank you very much for your answer.
I have read this FAQ and it didn't help. I'm using C++ and NewlibNano. I don't have some problem with buffer allocation. The memory will be reserved for FreeRTOS heap at RamAHB32(I'm using heap4.c memory modell. It's static allocation of buffer for heap), as I would. So, the problem is, that size of my firmware is 50 KB and 28 KB (size of buffer for FreeRTOS) from theese bytes are 0x00, which will be used for initialization of buffer for FreeRTOS. I don't need this initialization and I try to use directive __NOINIT(RAM2) with hope, that my buffer will be not initialized after start and size of firmware will be decreased on 28KB.
P.S. I tried this variant with dynamic allocation, but so I can not effective use whole RAM memory of LPC.
Please re-read this FAQ.
.
This mechanism is used with Managed linker scripts. The linker script doesn't show where your buffer was allocated. You need to extract this from the map file. The next issue to investigate is which low-level library (Redlib, Newlib, etc.) is being used. FreeRTOS may be allocating heap using the library malloc. Unless less you've supplied your own malloc, the library isn't using the space you've allocated.
Thanks and regards,
LPCXpresso Support