How i can place buffer at .noinit section?

cancel
Showing results for 
Search instead for 
Did you mean: 

How i can place buffer at .noinit section?

687 Views
Contributor I

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 */
) );
}

Tags (2)
0 Kudos
6 Replies

78 Views
Contributor I

Thank you. Now it's clear, why bss shows additionally size of .noinit section.

0 Kudos

78 Views
NXP Employee
NXP Employee

.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

0 Kudos

78 Views
Contributor I

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.

0 Kudos

78 Views
NXP Employee
NXP Employee

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

0 Kudos

78 Views
Contributor I

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.

0 Kudos

78 Views
NXP Employee
NXP Employee

Please re-read this FAQ.

.

'Noinit' Memory Sections

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

0 Kudos