I am working on porting a project that uses C++ exceptions to Teensy 4.1. The project is large, but at the moment I am not able to get exceptions to work properly at all even on the simplest of projects.
I am running on Platformio with this configuration:
Code:
[env:teensy41-gcc11]
platform = teensy
platform_packages =
toolchain-gccarmnoneeabi@symlink:///home/perception/.platformio/packages/toolchain-gccarmnoneeabi@1.11.3.1.202208/
;platformio/toolchain-gccarmnoneeabi@1.90301.200702
tool-teensy
lib_deps =
discord-intech/FreeRTOS-Teensy4@^10.0.5
board = teensy41
framework = arduino
build_unflags = -std=gnu++11 -std=gnu++14 -fno-rtti
build_flags = -std=c++17
-Wl,-Map,output.map
-D_GLIBCXX_HAS_GTHREADS=1
-Isrc/mutex_freertos
-D_GLIBCXX_HAVE_DIRENT_H
-fexceptions
This is my simple code:
Code:
#include <iostream>
#include <chrono>
#include <filesystem>
#include <mutex>
#include <Arduino.h>
#include <string>
#include <exception>
int led = 13;
void setup()
{
pinMode(led, OUTPUT);
}
void loop() {
try
{
throw std::runtime_error("exception"); // wait for a second
}
catch(...)
{
while(true)
{
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(100); // wait for a second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(100);
}
}
}
With the default Teensy beta linker script just published for GCC11, the program won't link as soon as I enable exceptions and gives these errors:
Code:
.pio/build/teensy41-gcc11/libFrameworkArduino.a(startup.c.o):(.ARM.exidx.startup+0x0): relocation truncated to fit: R_ARM_PREL31 against `.startup'
.pio/build/teensy41-gcc11/libFrameworkArduino.a(startup.c.o):(.ARM.exidx.startup+0x8): relocation truncated to fit: R_ARM_PREL31 against `.startup'
.pio/build/teensy41-gcc11/libFrameworkArduino.a(startup.c.o):(.ARM.exidx.startup+0x10): relocation truncated to fit: R_ARM_PREL31 against `.startup'
.pio/build/teensy41-gcc11/libFrameworkArduino.a(startup.c.o):(.ARM.exidx.flashmem+0x0): relocation truncated to fit: R_ARM_PREL31 against `.flashmem'
.pio/build/teensy41-gcc11/libFrameworkArduino.a(startup.c.o):(.ARM.exidx.flashmem+0x8): relocation truncated to fit: R_ARM_PREL31 against `.flashmem'
.pio/build/teensy41-gcc11/libFrameworkArduino.a(startup.c.o):(.ARM.exidx.flashmem+0x10): relocation truncated to fit: R_ARM_PREL31 against `.flashmem'
.pio/build/teensy41-gcc11/libFrameworkArduino.a(startup.c.o):(.ARM.exidx.flashmem+0x18): relocation truncated to fit: R_ARM_PREL31 against `.flashmem'
.pio/build/teensy41-gcc11/libFrameworkArduino.a(startup.c.o):(.ARM.exidx.flashmem+0x20): relocation truncated to fit: R_ARM_PREL31 against `.flashmem'
.pio/build/teensy41-gcc11/libFrameworkArduino.a(startup.c.o):(.ARM.exidx.flashmem+0x28): relocation truncated to fit: R_ARM_PREL31 against `.flashmem'
.pio/build/teensy41-gcc11/libFrameworkArduino.a(tempmon.c.o):(.ARM.exidx.flashmem+0x0): relocation truncated to fit: R_ARM_PREL31 against `.flashmem'
.pio/build/teensy41-gcc11/libFrameworkArduino.a(usb.c.o):(.ARM.exidx.flashmem+0x0): additional relocation overflows omitted from the output
I can fix these errors by modifying the linker script such that the general text AND the .ARM.exidx sections get put into flash:
Code:
.text.progmem : {
*(.progmem*)
*(.text*)
. = ALIGN(4);
} > FLASH
.text.itcm : {
. = . + 32; /* MPU to trap NULL pointer deref */
*(.fastrun)
. = ALIGN(16);
} > ITCM AT> FLASH
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx* .ARM.extab.text* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} AT> FLASH
This will compile, link, and execute but exceptions do not get caught. I don't have a debugger, but considering that the uC seems to reboot, I'm guessing its going to std::terminate(). I have read about issues with previous version of the ARM toolchain, but my understanding is that this was fixed. I have also looked at the map file to ensure that it's not linking the nano versions of newlib.
I don't know if the .ARM.exidx section needs to be in some kind of RAM to work properly, but if so, I don't know how to also put the startup in RAM (or at least ITCM) as well. I believe that the startup has to run from flash, but if so, the .ARM.exidx would have to be in Flash to to prevent the R_ARM_PREL31 error.