Teensy4.1: optimisation -0g, -00 fails to start.

Status
Not open for further replies.

AndyCap

Well-known member
Hi Guys,

I'm seeing this with platformIO and the Arduino ide.

I am seeing the issue with hurts ILI9341_t3n library but am pretty sure this is not causing this, I have seen other similar issues on the internet with different libs.

If I take the following code:

Code:
#include <Arduino.h>
#include <ILI9341_t3n.h>

#define TFT_DC 9
#define TFT_CS 10
ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC);

void setup() 
{
  Serial.begin(115200); 

  Serial.printf("Started\n");
  tft.begin(); // Remove this and it starts fine
}

void loop() 
{
  Serial.printf("running\n");
}


If compiled with -O1, -O2 or -O3 then after flashing the teensy starts up and we see the log messages.

When compiled with -Og or -O0 then the teensy does not start up, the serial port is not there and to re-flash it you need to press the button.

Kurt told me to define PRINT_DEBUG_STUFF and look at the uart4 output.

With -O1, -O2 and -O3 I see:

Code:
***********IMXRT Startup**********
test 1 -1234567 3
CCM_ANALOG_PLL_USB1=80003000
  enable USB clocks
CCM_ANALOG_PLL_USB1=80003040
Increasing voltage to 1250 mV
need to switch to alternate clock during reconfigure of ARM PLL
USB PLL is running, so we can use 120 MHz
Freq: 12 MHz * 100 / 2 / 1
ARM PLL=80002042
ARM PLL needs reconfigure
ARM PLL=80002064
New Frequency: ARM=600000000, IPG=150000000
analogInit
BURSTSIZE=00000808
BURSTSIZE=00000808
USB1_TXFILLTUNING=00000000
USB reset took 6 loops
usb_serial_reset
usb_serial_configure
rx queue i=0
rx queue i=1
rx queue i=2
rx queue i=3
rx queue i=4
rx queue i=5
rx queue i=6
rx queue i=7

With -Og, -O0 I see no output at all, totally dead.

Has anyone got any ideas of what might be going wrong here?

Many thanks

Andy
 
I've had what could be a similar problem using Arduino IDE, audio library and TeensyDebug. You might want to try finding the cores\teensy4\startup.c file, and commenting out the reset_PFD() call around line 92 or so. This has worked a treat for me in the past, and currently! There's another call at line 120, so I don't think there's likely to be any adverse effects.
 
Hi h4yn0nnym0u5e,

You are a genius :)

I did find that removing this line stopped -O1 builds working, same issue with the hanging.

So I put the line back in and added at the top of startup.c:

Code:
#pragma GCC optimize ("O2")

Now all optimisation levels start fine.

Thanks very much for the help here, really appreciated.
 
No problem, glad it’s working for you now. If I remember I’ll have to see what the Arduino IDE uses as the optimisation level for startup.c, it may be different from platformIO (which I’ve never used), and a pragma might work to the same effect.
 
Further exploration yields the discovery that it's sufficient (for me) to add __attribute__((optimize("O2"))) before the definition of reset_PFD(), so the rest of startup.c can use whatever optimisation level is in force generally. Not sure if this makes much difference, given the code is only run once at boot, but it feels better ... even if I still don't know why it works!

I've put in PR #673, on the assumption that this has probably bitten quite a few people over time, and seems benign.
 
Hi,

I've had a similar problem when compiling with -Os and LTO. I think the root cause for these startup issues is the way the stack pointer is setup in ResetHandler(). If the compiler inserts some stack or frame handling code before __asm__ volatile("mov sp, %0" :: "r" ((uint32_t)&_estack));, the stack or frame setup gets messed up later on. If the compiler actually inserts stack-related code depends on optimization settings, function inlining during LTO, if startup_early_hook() is used, etc. In most cases the startup code just works fine.

But to resolve this, you IMHO have to setup the stack pointer in assembler before calling a C function. What works for me with several compiler optimization settings is the following reset handler:

Code:
__attribute__((section(".startup"), naked, noreturn))
void ResetHandler(void) {
	__asm__ volatile("str %1, [%0] \n\t" :: "r" (&IOMUXC_GPR_GPR17), "r" (&_flexram_bank_config) : "memory");
	__asm__ volatile("str %1, [%0] \n\t" :: "r" (&IOMUXC_GPR_GPR16), "r" (0x00200007) : "memory");
	__asm__ volatile("str %1, [%0] \n\t" :: "r" (&IOMUXC_GPR_GPR14), "r" (0x00AA0000) : "memory");
	__asm__ volatile("dsb" ::: "memory");
	__asm__ volatile("isb" ::: "memory");
	__asm__ volatile("msr msp, %0" :: "r" (&_estack) : "memory");
	__asm__ volatile("dsb" ::: "memory");
	__asm__ volatile("isb" ::: "memory");

	ResetHandlerC();
}

It initializes DTCM, sets the stack pointer and then calls the original reset handler code (renamed to ResetHandlerC() here).

If that makes sense to you guys, I can create a pull request. But before merging it should be reviewed and tested by others, too :)

Timo
 
Hi,

I've had a similar problem when compiling with -Os and LTO. I think the root cause for these startup issues is the way the stack pointer is setup in ResetHandler(). If the compiler inserts some stack or frame handling code before __asm__ volatile("mov sp, %0" :: "r" ((uint32_t)&_estack));, the stack or frame setup gets messed up later on. If the compiler actually inserts stack-related code depends on optimization settings, function inlining during LTO, if startup_early_hook() is used, etc. In most cases the startup code just works fine.
...

Interesting note. Since T_4.0 beta hardware, the LTO that worked well with new T_3.6, it regularly failed so it just never got used. And looking at optimized options LTO has been removed at this time. Perhaps due to the toolchain update and issues as follows.

Enabling it in boards.txt and building CoreMark and BLINK fails IDE 1.8.19 and TSET using IDE 2.0 build:
Code:
lto-wrapper.exe: fatal error: C:\T_Drive\arduino-1.8.19\hardware\teensy/../tools/arm/bin/arm-none-eabi-gcc returned 1 exit status
compilation terminated.
c:/t_drive/arduino-1.8.19/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld.exe: error: lto-wrapper failed
collect2.exe: error: ld returned 1 exit status
Error compiling for board Teensy 4.1.
 
Unfortunately, no.
I did a quick test with a blink example and had to add "noinline" as attribute for ResetHandler2() to make it built with -O2 -flto.
Maybe I did not declare the C-ResetHandler static in my previous tests and therefore didn't run into that issue...
 
Ok, will look at this again for LTO. Yesterday I tested only with the 5 optimization levels we're currently offering in the Arduino menu, which doesn't (yet) have LTO.
 
Was going to put that together here (p#8) to see if LTO changed ... but too many moving parts ... if they get aligned, will do some test builds.
 
:)

Seems multiple other things are broken regarding LTO. I'm putting this in for 1.58 release, because it's low risk and I was able to confirm it is indeed a problem with LTO. Everything else in need of fixing to supply LTO will have to wait for 1.59.

Do you have a list of the other things that are broken with LTO? I'm only aware of cores/pull/682.
 
No, I didn't write any notes. When we start 1.59 beta, I will put the LTO options back in the Arduino menu, so it's easier to test what's working and what's in need of fixing to work with LTO.
 
I just realized that I’m probably explaining PR 682 wrong and wanted to add this for posterity:
PR 682 doesn’t fix an LTO bug. It fixes a non-LTO problem that the original LTO fix attempt introduced.
 
I removed _serialEvent_default and reworked the yield() optimization stuff. Closed #681 and #682, as they no longer apply.

I also fixed startup issues with LTO, though part of the fix involves adding brief delays which seem like an ugly hack (the rest was replacing the memory init with inline assembly so the compiler doesn't massively alter it). I'm not 100% happy with needing unexplained delays, but it at least seems to solve the startup problems for now.

1.59-beta1 now has LTO in the Arduino Tools > Optimization menu. Many programs work fine with LTO, but some do not, especially when used with -O3 (called "Fastest" in the Arduino menu). Please report any programs that fail on the 1.59-beta1 thread.

https://forum.pjrc.com/threads/72523-Teensyduino-1-59-Beta-1

I'm going to close this thread, as its original issue of startup failure is now fixed.
 
Status
Not open for further replies.
Back
Top