How to use C++ in CoIDE Preface

CooCox Application Note --- How to use C++ in CoIDE
How to use C++ in CoIDE
Preface
Using C++ language in CoIDE is a piece of cake, just several steps list below:
1)
2)
3)
4)
Replace the link file
Modify the startup code
Link C++ library
Enjoy you code with C++
Initial version
CooCox Team
2013-10-23
Note:
1. Appendix is source code of new linker configuration file.
2. Purple word is CoIDE menu.
3. In source code, shallow blue word is new added code.
1 / 11
CooCox Application Note --- How to use C++ in CoIDE
Below are the detail informations
Replace the link file
Open the <project configuration> windows, switch to <link> page, then unselect "use memory
layout from memory window"
Now, a default link file named “arm-gcc-link.ld” is created by coide in current project
directory
Open “arm-gcc-link.ld” file then copy the section “MEMORY”, which looks like below:
MEMORY
{
rom (rx)
: ORIGIN = 0x08000000, LENGTH = 0x00100000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000
ram1 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x00010000
}
Now, Use our new link file to replace the old link file, then use <step 3> memory section
to replace new link file content.
Then rename <rom> to <FLASH>, <ram> to <RAM>, <ram1> to <RAM1>, and so on.
After done, your linker file look like this:
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
*
Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
*
__exidx_start
*
__exidx_end
*
__etext
*
__data_start__
*
__preinit_array_start
*
__preinit_array_end
*
__init_array_start
*
__init_array_end
*
__fini_array_start
*
__fini_array_end
*
__data_end__
*
__bss_start__
*
__bss_end__
*
__end__
*
end
2 / 11
CooCox Application Note --- How to use C++ in CoIDE
*
__HeapLimit
*
__StackLimit
*
__StackTop
*
__stack
*/
/* Linker script to configure memory regions.
* Need modifying for a specific board.
*
FLASH.ORIGIN: starting address of flash
*
FLASH.LENGTH: length of flash
*
RAM.ORIGIN: starting address of RAM bank 0
*
RAM.LENGTH: length of RAM bank 0
*/
[Bold][gray]
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x00100000
RAM (rwx)
: ORIGIN = 0x20000000, LENGTH = 0x00020000
RAM1 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x00010000
}
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
…
3 / 11
CooCox Application Note --- How to use C++ in CoIDE
Modify the startup code
We need add


heap configure code
_start symbol
Into startup code. Below is details:
Open startup code, add the follow code below “stack configuration” section, after finished,
it looks like below:
/*----------Stack Configuration-----------------------------------------------*/
#define STACK_SIZE
r
*/
0x00000200
/*!< The Stack size suggest using even numbe
__attribute__ ((section(".co_stack")))
unsigned long pulStack[STACK_SIZE];
/* Heap Configuration
* Note:
* 1) You can use macro __HEAP_SIZE to set default heap size
* 2) This value is suggest to use an even number
* 3) The default linker configure file will check the size of heap, if the heap is
*
overflow that system ram, then linker will report error like this:
*
<-- error: size of array '__HeapPool' is too large -->
*/
#define __HEAP_SIZE
0x00000400
__attribute__ ((section(".heap")))
unsigned long __HeapPool[__HEAP_SIZE];
Then replace main function with the follow code:
/*!< The entry point for the application. */
#ifdef SYSTEM_LIB
extern int _start(void);
_start();
#else
4 / 11
CooCox Application Note --- How to use C++ in CoIDE
main();
#endif
we use “SYSTEM_LIB” to switch on/off “_start” symbol, at this time we need to open
<project configuration> windows <compiler> page, then add macro <SYSTEM_LIB>.
One more thing, “_start” symbol is defined in gcc runtime library, so we need use system
standard startup code by open <project configuration> window <link> page, then unselect
“Don't use standard system startup files” option.
Link C++ library
Open <project configuration> window <link> page, and add <libstdc++.a> <libsupc++.a>
<libnosys.a> library to your project
You can find lots of library files in gcc install directory.
For example:
C:.
│ libc.a
│ libc_s.a
│ libg.a
│ libgloss-linux.a
│ libg_s.a
│ libm.a
│ libnosys.a
│ librdimon.a
│ librdimon_s.a
│ librdpmon.a
│ libstdc++.a
│ libstdc++_s.a
│ libsupc++.a
│ libsupc++_s.a
│
├─armv6-m
│
libc.a
│
libc_s.a
│
libg.a
│
libgloss-linux.a
│
libg_s.a
│
libm.a
│
libnosys.a
5 / 11
CooCox Application Note --- How to use C++ in CoIDE
│
librdimon.a
│
librdimon_s.a
│
librdpmon.a
│
libstdc++.a
│
libstdc++_s.a
│
libsupc++.a
│
libsupc++_s.a
│
redboot.ld
│
├─armv7-m
│ └─thumb
│
│ libc.a
│
│ libc_s.a
│
│ libg.a
│
│ libgloss-linux.a
│
│ libg_s.a
│
│ libm.a
│
│ libnosys.a
│
│ librdimon.a
│
│
│
│ librdpmon.a
│
│ libstdc++.a
│
│ libstdc++_s.a
│
│ libsupc++.a
│
│ libsupc++_s.a
│
│ redboot.ld
│
│
│
├─fpu
│
│
libc.a
│
│
libc_s.a
│
│
libg.a
│
│
libgloss-linux.a
│
│
libg_s.a
│
│
libm.a
│
│
libnosys.a
│
│
librdimon.a
│
│
librdimon_s.a
│
│
librdpmon.a
│
│
libstdc++.a
│
│
libstdc++_s.a
│
│
libsupc++.a
│
│
libsupc++_s.a
│
│
redboot.ld
│
│
│
└─softfp
librdimon_s.a
6 / 11
CooCox Application Note --- How to use C++ in CoIDE
│
libc.a
│
libc_s.a
│
libg.a
│
libgloss-linux.a
│
libg_s.a
│
libm.a
│
libnosys.a
│
librdimon.a
│
librdimon_s.a
│
librdpmon.a
│
libstdc++.a
│
libstdc++_s.a
│
libsupc++.a
│
libsupc++_s.a
You can select respond library according to your mcu type, i.e, if you use <ST F4 Discovery board>, then you can select the
librarys in ARMv7-m directory.
More information, please reference to <gcc manual>
Enjoy Coding with C++
Oh, great , Now you can enjoy C++ coding with CoIDE, have fun!
7 / 11
CooCox Application Note --- How to use C++ in CoIDE
Appendix
New linker configure file for C++
Note: Remember to change “MEMORY” section according to your MCU.
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x00100000 /* 128K */
8 / 11
CooCox Application Note --- How to use C++ in CoIDE
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 /* 8K */
}
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
9 / 11
CooCox Application Note --- How to use C++ in CoIDE
__etext = .;
/* _sidata is used in coide startup code */
_sidata = __etext;
.data : AT (__etext)
{
__data_start__ = .;
/* _sdata is used in coide startup code */
_sdata = __data_start__;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
/* _edata is used in coide startup code */
_edata = __data_end__;
10 / 11
CooCox Application Note --- How to use C++ in CoIDE
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
_sbss = __bss_start__;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
_ebss = __bss_end__;
} > RAM
.heap (COPY):
{
__end__ = .;
_end = __end__;
end = __end__;
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.co_stack (NOLOAD):
{
. = ALIGN(8);
*(.co_stack .co_stack.*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.co_stack);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}
11 / 11