SuperHouse / esp-open-rtos

Open source FreeRTOS-based ESP8266 software framework
BSD 3-Clause "New" or "Revised" License
1.52k stars 491 forks source link

issues when using libstdc++ #623

Closed joostn closed 6 years ago

joostn commented 6 years ago

Hi,

My app uses the c++ standard library; I'm running into two issues when building:

IRAM is overflowing: section .text' will not fit in regioniram1_0_seg': looking at the map file, my IRAM uses approximately 0x8800, of which nearly 0x3000 bytes are used by printf* functions:

[....] .text 0x0000000040105fe0 0x61 ./build/libc.a(lib_a-printf.o) 0x65 (size before relaxing) 0x0000000040105fe0 _iprintf_r 0x0000000040105fe0 _printf_r 0x000000004010600c printf 0x000000004010600c iprintf *fill* 0x0000000040106041 0x3 .text 0x0000000040106044 0xb5 ./build/libc.a(lib_a-sprintf.o) 0xb9 (size before relaxing) 0x0000000040106044 _sprintf_r 0x0000000040106044 _siprintf_r 0x000000004010609c siprintf 0x000000004010609c sprintf *fill* 0x00000000401060f9 0x3 .text 0x00000000401060fc 0x57 ./build/libc.a(lib_a-fprintf.o) 0x5b (size before relaxing) 0x00000000401060fc _fprintf_r 0x00000000401060fc _fiprintf_r 0x0000000040106120 fprintf 0x0000000040106120 fiprintf *fill* 0x0000000040106153 0x1 .text 0x0000000040106154 0x4c5 ./build/libc.a(lib_a-nano-svfprintf.o) 0x0000000040106154 __ssputs_r 0x0000000040106250 __ssprint_r 0x0000000040106384 _svfprintf_r 0x0000000040106384 _svfiprintf_r *fill* 0x0000000040106619 0x3 .text 0x000000004010661c 0x43b ./build/libc.a(lib_a-nano-vfprintf.o) 0x43f (size before relaxing) 0x0000000040106654 __sfputs_r 0x00000000401066c4 __sprint_r 0x0000000040106754 _vfprintf_r 0x0000000040106754 _vfiprintf_r 0x0000000040106a30 vfprintf 0x0000000040106a30 vfiprintf *fill* 0x0000000040106a57 0x1 .text 0x0000000040106a58 0x10c ./build/libc.a(lib_a-snprintf.o) 0x0000000040106a58 _sniprintf_r 0x0000000040106a58 _snprintf_r 0x0000000040106adc snprintf 0x0000000040106adc sniprintf .text 0x0000000040106b64 0x5f ./build/libc.a(lib_a-vsprintf.o) 0x63 (size before relaxing) 0x0000000040106b64 _vsiprintf_r 0x0000000040106b64 _vsprintf_r 0x0000000040106b9c vsprintf 0x0000000040106b9c vsiprintf *fill* 0x0000000040106bc3 0x1 .text 0x0000000040106bc4 0x114 ./build/libc.a(lib_a-swprintf.o) 0x118 (size before relaxing) 0x0000000040106bc4 _swprintf_r 0x0000000040106c50 swprintf .text 0x0000000040106cd8 0x1616 ./build/libc.a(lib_a-svfwprintf.o) 0x165e (size before relaxing) 0x0000000040106dfc _svfwprintf_r *fill* 0x00000000401082ee 0x0 *fill* 0x00000000401082ee 0x0 *fill* 0x00000000401082ee 0x0 *fill* 0x00000000401082ee 0x0 *fill* 0x00000000401082ee 0x0 *fill* 0x00000000401082ee 0x0 *fill* 0x00000000401082ee 0x0 *libc.a:*findfp.o(.literal .text .literal.* .text.*) *fill* 0x00000000401082ee 0x2 .text 0x00000000401082f0 0x317 ./build/libc.a(lib_a-findfp.o) 0x0000000040108348 _cleanup_r 0x00000000401083e0 __sfmoreglue 0x0000000040108428 _cleanup 0x000000004010843c __sfp_lock_acquire 0x0000000040108454 __sfp_lock_release 0x000000004010846c __sinit_lock_acquire 0x0000000040108484 __sinit_lock_release 0x000000004010849c __sinit 0x0000000040108518 __sfp 0x00000000401085c8 __fp_lock_all 0x00000000401085e8 __fp_unlock_all *fill* 0x0000000040108607 0x0 *libc.a:*fputwc.o(.literal .text .literal.* .text.*) *fill* 0x0000000040108607 0x1 .text 0x0000000040108608 0x152 ./build/libc.a(lib_a-fputwc.o) 0x156 (size before relaxing) 0x0000000040108608 __fputwc 0x00000000401086b0 _fputwc_r 0x0000000040108724 fputwc *fill* 0x000000004010875a 0x0 *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) *(.fini.literal) *(.fini) *(.gnu.version) 0x000000004010875a _text_end = ABSOLUTE (.) 0x000000004010875a _etext = .

In particular as you can see there's a large lib_a-svfwprintf (0x1616 bytes).

The linker script seems to move these to iram explicitly: libc.a:printf.o(.literal .text .literal. .text.)

Why is that? Because printf is used in interrupts? Can this rule be changed to move some stuff to flash?

And secondly the linker complains about doubly implemented delete operator:

LD build/app.out ./build/core.a(cplusplus_operators.o): In functionoperator delete(void)': /Users/joostn/GitProjects/ucprojects/esp8266/esp-open-rtos/core/cplusplus_operators.cpp:18: multiple definition of `operator delete(void)' /Users/joostn/GitProjects/ucprojects/esp8266/esp-open-sdk/xtensa-lx106-elf/bin/../lib/gcc/xtensa-lx106-elf/4.8.5/../../../../xtensa-lx106-elf/lib/libstdc++.a(del_op.o):/Volumes/case-sensitive/esp-open-sdk/crosstool-NG/.build/src/gcc-4.8.5/libstdc++-v3/libsupc++/del_op.cc:45: first defined here`

I can silence this error by commenting out operator delete in cplusplus_operators.cpp, but is this a safe thing to do?

Thanks for providing esp-open-rtos!

gudvinr commented 5 years ago

@joostn Hi. Can you give some hints for using libstdc++ with esp-open-rtos? Is it supported right out of the box or do I need to declare path to include and lib directories? Is there are any hassle with compiler params, etc?

joostn commented 5 years ago

Hi,

See my comment here: https://github.com/SuperHouse/esp-open-rtos/pull/625

The patches are included in esp-open-rtos already.

Use buildtoolchain.sh (see above) to build the toolchain.

It works, but RAM is tight, especially when using exceptions. If you don't need exception support then you actually might be able to use a stock esp-open-rtos.

joostn commented 5 years ago

Here's one of my Makefiles:

# ESPPORT=/dev/cu.SLAB_USBtoUART

ESPPORT=/dev/cu.wchusbserial1410
PROGRAM=app
EXTRA_CXXFLAGS=-fexceptions -Wno-reorder -ffunction-sections -frtti
LIBS=stdc++
EXTRA_C_CXX_FLAGS=-DJNUC_DEVICESERIES_ESP82 -DJNUC_DEVICESERIES_ESP -DLWIP_RAW=1 -DDEFAULT_RAW_RECVMBOX_SIZE=3 -DMDNS_RESPONDER_DEBUGGING=0
# -U__STRICT_ANSI__
FLASH_SIZE=32

EXTRA_COMPONENTS=../user $(UCPROJECTS)/cppcomponentsv3 $(UCPROJECTS)/cppcomponentsv3/startupcode extras/cpp_support extras/mdnsresponder extras/sntp extras/timekeeping extras/rboot-ota extras/dhcpserver
include $(UCPROJECTS)/esp8266/esp-open-rtos/common.mk

startupcode above refers to these files: Archive.zip You need to edit this to remove references to my own library code (all the jnuc_ stuff) and there's some ESP32 code in there as well.