diff options
Diffstat (limited to 'components/cplusplus')
| -rw-r--r-- | components/cplusplus/README.md | 54 | ||||
| -rw-r--r-- | components/cplusplus/SConscript | 11 | ||||
| -rw-r--r-- | components/cplusplus/crt.cpp | 27 | ||||
| -rw-r--r-- | components/cplusplus/crt.h | 16 | ||||
| -rw-r--r-- | components/cplusplus/crt_init.c | 74 |
5 files changed, 182 insertions, 0 deletions
diff --git a/components/cplusplus/README.md b/components/cplusplus/README.md new file mode 100644 index 0000000000..d02048d1f1 --- /dev/null +++ b/components/cplusplus/README.md @@ -0,0 +1,54 @@ +# C++ support for RT-Thread # + +This is the C++ component in RT-Thread RTOS. In order to support C++ language, this component +implement a basic environment, such as new/delete operators. + +Because RT-Thread RTOS is used in embedded system mostly, there are some rules for C++ applications: + +1. DOES NOT use exception. +2. DOES NOT use Run-Time Type Information (RTTI). +3. Template is discouraged and it easily causes code text large. +4. Static class variables are discouraged. The time and place to call their constructor function could not be precisely controlled and make multi-threaded programming a nightmare. +5. Multiple inheritance is strongly discouraged, as it can cause intolerable confusion. + +*NOTE*: The libc (RT_USING_LIBC in rtconfig.h) must be enable. + +About GNU GCC compiler + +please add following string in your ld link script: + + // in your .text section + PROVIDE(__ctors_start__ = .); + /* old GCC version uses .ctors */ + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + /* new GCC version uses .init_array */ + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE(__ctors_end__ = .); + + . = ALIGN(4); + + // as a standalone section if you use ARM target. + + /* The .ARM.exidx section is used for C++ exception handling. */ + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + + /* This is used by the startup in order to initialize the .data secion */ + _sidata = .; + } > CODE + __exidx_end = .; + + /* .data section which is used for initialized data */ + + // in your .data section + PROVIDE(__dtors_start__ = .); + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + PROVIDE(__dtors_end__ = .); + + . = ALIGN(4); diff --git a/components/cplusplus/SConscript b/components/cplusplus/SConscript new file mode 100644 index 0000000000..b41537a52b --- /dev/null +++ b/components/cplusplus/SConscript @@ -0,0 +1,11 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Glob('*.cpp') + Glob('*.c') +CPPPATH = [cwd] + +group = DefineGroup('CPlusPlus', src, depend = ['RT_USING_CPLUSPLUS', 'RT_USING_LIBC'], CPPPATH = CPPPATH) + +Return('group') diff --git a/components/cplusplus/crt.cpp b/components/cplusplus/crt.cpp new file mode 100644 index 0000000000..6fa540b9e7 --- /dev/null +++ b/components/cplusplus/crt.cpp @@ -0,0 +1,27 @@ +#include <rtthread.h> +#include "crt.h" + +void *operator new(size_t size) +{ + return rt_malloc(size); +} + +void *operator new[](size_t size) +{ + return rt_malloc(size); +} + +void operator delete(void *ptr) +{ + rt_free(ptr); +} + +void operator delete[] (void *ptr) +{ + return rt_free(ptr); +} + +void __cxa_pure_virtual(void) +{ + rt_kprintf("Illegal to call a pure virtual function.\n"); +} diff --git a/components/cplusplus/crt.h b/components/cplusplus/crt.h new file mode 100644 index 0000000000..fd287c2ad5 --- /dev/null +++ b/components/cplusplus/crt.h @@ -0,0 +1,16 @@ +#ifndef CRT_H_ +#define CRT_H_ + +#include <inttypes.h> +#include <stdlib.h> + +void *operator new(size_t size); +void *operator new[](size_t size); + +void operator delete(void * ptr); +void operator delete[] (void *ptr); + +extern "C" void __cxa_pure_virtual(void); +extern "C" int cplusplus_system_init(void); + +#endif diff --git a/components/cplusplus/crt_init.c b/components/cplusplus/crt_init.c new file mode 100644 index 0000000000..958177c1f2 --- /dev/null +++ b/components/cplusplus/crt_init.c @@ -0,0 +1,74 @@ +/* +* File : crt_init.c +* This file is part of Device File System in RT-Thread RTOS +* COPYRIGHT (C) 2008-2011, RT-Thread Development Team +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License along +* with this program; if not, write to the Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Change Logs: +* Date Author Notes +* 2014-12-03 Bernard Add copyright header. +* 2014-12-29 Bernard Add cplusplus initialization for ARMCC. +*/ + +#include <rtthread.h> + +#ifdef __CC_ARM +extern void $Super$$__cpp_initialize__aeabi_(void); +/* we need to change the cpp_initialize order */ +void $Sub$$__cpp_initialize__aeabi_(void) +{ + /* empty */ +} +#endif + +int cplusplus_system_init(void) +{ +#if defined(__GNUC__) && !defined(__CC_ARM) + extern unsigned char __ctors_start__; + extern unsigned char __ctors_end__; + typedef void (*func)(void); + + /* .ctors initalization */ + func *ctors_func; + + for (ctors_func = (func *)&__ctors_start__; + ctors_func < (func *)&__ctors_end__; + ctors_func ++) + { + (*ctors_func)(); + } +#elif defined(__CC_ARM) + /* If there is no SHT$$INIT_ARRAY, calling + * $Super$$__cpp_initialize__aeabi_() will cause fault. At least until Keil5.12 + * the problem still exists. So we have to initialize the C++ runtime by ourself. + */ + typedef void PROC(); + extern const unsigned long SHT$$INIT_ARRAY$$Base[]; + extern const unsigned long SHT$$INIT_ARRAY$$Limit[]; + + const unsigned long *base = SHT$$INIT_ARRAY$$Base; + const unsigned long *lim = SHT$$INIT_ARRAY$$Limit; + + for (; base != lim; base++) + { + PROC *proc = (PROC*)((const char*)base + *base); + (*proc)(); + } +#endif + + return 0; +} +INIT_COMPONENT_EXPORT(cplusplus_system_init); |
