Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: C++ STL on the Teensy 4.0 not possible?

  1. #1
    Junior Member
    Join Date
    May 2020
    Posts
    4

    C++ STL on the Teensy 4.0 not possible?

    Because I'm a stubborn jerk, I do not want to use Teensyduino. I want something more low-level for total control over Teensy 4.0, but I love my C++ STL. So, I discovered this nifty project someone kindly put on GitHub with a bare minimum Blinky that compiles straight C code for Teensy 4.0:

    https://github.com/blazer82/baremetal-blinky.teensy

    So far so good. I was able to alter the Makefile to use g++ to compile cpp files. I can write and compile code with classes, templates and all the fun stuff from C++. Hooray!

    But, I cannot for the life of me get any STL code like std::vector to link after compiling. I am pulling my hair out, searching Google like a madman, and tried all of the suggestions (of course I am using -lstdc++ to the linker flags). No dice. I get various linker errors, when I include stdc++ (underfed reference to new, or delete, or exit).

    Code:
    new_allocator.h:114: undefined reference to `operator new(unsigned int)'
    See code attached below:

    baremetal-blinky.teensy.zip

    I'm starting to think that the STL might actually not be supported on this thing. Is that true? I couldn't find a clear answer, but I have read a few articles that suggest that STL support with GNU Toolchain for Embedded ARM *does* work.
    Has anyone gotten this to work? Would be great if I could find a bare minimum Makefile. Here is what I'm using now:

    Code:
    CC = arm-none-eabi-gcc
    CXX = arm-none-eabi-g++
    LD = arm-none-eabi-ld
    OBJCOPY = arm-none-eabi-objcopy
    OBJDUMP = arm-none-eabi-objdump
    SIZE = arm-none-eabi-size
    LOADER = teensy_loader_cli
    
    OUTFILE = firmware
    
    BUILD_DIR = ./build
    SRC_DIRS ?= ./src ./teensy ./include
    
    SRCS := $(shell find $(SRC_DIRS) -name *.c -or -name *.cpp -or -name *.s)
    OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)
    DEPS := $(OBJS:.o=.d)
    
    FLAGS_CPU   := -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16
    FLAGS_OPT   := -O3
    FLAGS_COM   := -g -Wall -ffunction-sections -fdata-sections -MMD -nostdlib -nostartfiles
    FLAGS_LSP   := 
    
    FLAGS_CPP   := -std=c++17 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing
    FLAGS_C     := 
    FLAGS_S     := -x assembler-with-cpp
    FLAGS_LD    := -Wl,--gc-sections,--print-memory-usage,--relax,-Tteensy/imxrt1062.ld -specs=nosys.specs
    
    INCLUDE_DIRS := $(ARM_NONE_EABI_INCLUDE) $(shell find $(SRC_DIRS) -type d)
    FLAGS_INCLUDE := $(addprefix -I,$(INCLUDE_DIRS))
    
    LIB_DIRS := $(ARM_NONE_EABI_LIB)
    FLAGS_LIB_DIRS = $(addprefix -L,$(LIB_DIRS))
    
    LIBS := m stdc++_nano gcc g_nano c_nano
    FLAGS_LIBS := $(addprefix -l,$(LIBS))
    
    DEFINES     := -D__IMXRT1062__ -DTEENSYDUINO=147 -DARDUINO=10807
    DEFINES     += -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH
    
    CPP_FLAGS   := $(FLAGS_CPU) $(FLAGS_OPT) $(FLAGS_COM) $(DEFINES) $(FLAGS_CPP) $(FLAGS_INCLUDE)
    C_FLAGS     := $(FLAGS_CPU) $(FLAGS_OPT) $(FLAGS_COM) $(DEFINES) $(FLAGS_C) $(FLAGS_INCLUDE)
    S_FLAGS     := $(FLAGS_CPU) $(FLAGS_OPT) $(FLAGS_COM) $(DEFINES) $(FLAGS_S) $(FLAGS_INCLUDE)
    LD_FLAGS    := $(FLAGS_CPU) $(FLAGS_OPT) $(FLAGS_LSP) $(FLAGS_LD) $(FLAGS_LIB_DIRS) $(FLAGS_LIBS)
    AR_FLAGS    := rcs
    
    
    $(BUILD_DIR)/$(OUTFILE).hex: $(BUILD_DIR)/$(OUTFILE).elf
    	@$(OBJCOPY) -O ihex -R .eeprom build/$(OUTFILE).elf build/$(OUTFILE).hex
    	@$(OBJDUMP) -d -x build/$(OUTFILE).elf > build/$(OUTFILE).dis
    	@$(OBJDUMP) -d -S -C build/$(OUTFILE).elf > build/$(OUTFILE).lst
    	@$(SIZE) build/$(OUTFILE).elf
    
    $(BUILD_DIR)/$(OUTFILE).elf: $(OBJS)
    	@$(CXX) $(CPP_FLAGS) -Xlinker -Map=build/$(OUTFILE).map -Tteensy/imxrt1062.ld -o $@ $^
    	@echo Linking...
    
    $(BUILD_DIR)/%.s.o: %.s
    	@$(MKDIR_P) $(dir $@)
    	@$(AS) $(S_FLAGS) -c $< -o $@
    	@echo Assembling $<...
    
    $(BUILD_DIR)/%.c.o: %.c
    	@$(MKDIR_P) $(dir $@)
    	@$(CC) $(C_FLAGS) -c $< -o $@
    	@echo Compiling $<...
    
    $(BUILD_DIR)/%.cpp.o: %.cpp
    	@$(MKDIR_P) $(dir $@)
    	@$(CXX) ${CPP_FLAGS} -c $< -o $@
    	@echo Compiling $<...
    
    .PHONY: flash
    flash: $(BUILD_DIR)/$(OUTFILE).hex
    	$(LOADER) --mcu=TEENSY40 -w -v $<
    
    .PHONY: clean
    clean:
    	@$(RM) -r $(BUILD_DIR)
    
    MKDIR_P ?= mkdir -p

  2. #2
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    262
    I've not tried C++17 yet, but I know for sure C++14 is supported fairly well by Teensyduino and for a while now so I would start with that to use something with some more maturity on Teensy. I use a couple STL containers in one of my projects. For example, I use <vector>, but I had to add some code in order to get it to work as exceptions are not supported on Teensy I think. When I tried to use <vector> I got warnings about missing functions so I just defined them myself and I've been using STL vectors just fine. Given that you don't have an OS/page table, memory fragmentation is a concern so you should probably stick to containers with a reserve() command and allocate what you need at the start.

    See the following for how I added <vector> support to my project.

    https://github.com/Blackaddr/TouchMI...torSupport.cpp

  3. #3
    Junior Member
    Join Date
    May 2020
    Posts
    4
    thanks for this. have you tried the "-fno-exceptions" GCC flag when you compile your code? in your case, I think that flag will remove the necessity for the VectorSupport.cpp file altogether. when I have this flag enabled, I no longer get linker errors for those particular functions.

    still though, I can't compile any vector code due to linker not finding "new" and "delete" functions. these are very core STL functions, so I'm wondering what the hell is going on that it is linking all of the stdc++ library functions except these basic ones

  4. #4
    Junior Member
    Join Date
    May 2020
    Posts
    4
    maybe my next step should be to setup a teensyduino project and see if I can replicate what you've got for teensy 4.0, and then copy GCC options and linker flags to my Makefile. ideally I would like to end up with a simple Makefile project that is not tied to Arduino that has C++ STL support

  5. #5
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,698
    Quote Originally Posted by teensydude View Post
    still though, I can't compile any vector code due to linker not finding "new" and "delete" functions. these are very core STL functions, so I'm wondering what the hell is going on that it is linking all of the stdc++ library functions except these basic ones
    Are you not saying you wanted to use barmetal (i.e. no TeensyDuino)? So you must write first all the functionality STL expects (here memory management), right?

  6. #6
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    990
    The STL works nicely on T4.0. Unfortunately, there is a setting missing in the T4 linker script (T3 is OK).
    You find some information here: https://forum.pjrc.com/threads/59767...stl#post230936

  7. #7
    Junior Member
    Join Date
    May 2020
    Posts
    4
    thanks for the heads up, I was able to take the stuff luni showed me by defining these missing symbols:

    __exidx_start
    __exidx_end

    this is resolved by placing the following code at the end of the linker scr

    Code:
        .ARM.exidx :
        {
            __exidx_start = .;
            *(.ARM.exidx* .gnu.linkonce.armexidx.*)
            __exidx_end = .;
            . = ALIGN(4);
        } > RAM
    the forum discussion from the post above had > FLASH, which causes all sorts of errors. i was able to make them go away by putting the symbols into RAM with > RAM

    the next step was to get rid of the undefined reference to new and delete. although i'm not quite sure why these basic things do not exist in stdc++ library in the arm toolchain, i copied new.h and new.cpp

    so i present to you an un-verified bare metal C++ blink example for teensy with C++ 17 & STL support!

    The code is here for any who want to mess around. So far I've tested that I can compile std::vector, std::string and std::map without compiler errors. Whether this works or not, I will have to wait for my teensy 4.0 to arrive in the mail to start messing around.

    https://github.com/itsermo/baremetal-blinky.teensy

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •