How to use C++ in CoIDE Preface
Transcription
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