startup time (400ms)

Status
Not open for further replies.

Adriano

Member
Hi,
I am trying to power on the teensy to save some data and then power off it again.
I noticed that the first line in the setup is executed after 400ms (on a small sketch and on heavy sketches).

I read somewhere that teensy boots in 5ms. Is there a way to speed up this "delay" of 400ms?

Code:
unsigned long startuptime = 0;

void setup() {
  startuptime = millis();
  while(!Serial);
  
  Serial.print(F("Started up in "));
  Serial.print(startuptime);
  Serial.println(F("ms"));
}

void loop() {}

I got always this output:
Started up in 400ms

I also tried to attach an oscillator, setting an output to high and I get a delay of 400ms from the power signal until the output is set:
Code:
void setup() {
  pinMode(6, OUTPUT);
  digitalWrite(6, HIGH);
}

void loop() {}

I don't know if the bootloader need some time or if I can set something in the IDE (currently it is 96MHz speed optimized).

Thanks,
Adriano
 
IIRC - Paul added a wait before calling setup to allow computers to deal better with the startup. You can find and hack that number and test for your usage. I'm on the wrong computer to give you a direct pointer.

If you are waiting to talk to USB serial - it takes 700 ms or more for it to come online best case under windows and that delay includes the entry to setup().

If USB isn't compiled I'm not sure if that delay gets dropped or not?
 
Hi Defragster.
Thank you very much for your help!
Found this on line 633 of pins_teensy.c:

Code:
	analog_init();
	// for background about this startup delay, please see this conversation
	// https://forum.pjrc.com/threads/31290-Teensey-3-2-Teensey-Loader-1-24-Issues?p=87273&viewfull=1#post87273
	delay(400);
	usb_init();

400ms is a lot of time if you don't have any USB connection. I have the USB if I want to "debug" and once it is ready to use I don't need the USB anymore.

To be honest I was trying to understand why this delay is necessary but I don't understand it :p

But I am able to start the program in 40ms now.

Thank you again for your help!
Adriano
 
Hi Defragster.
Thank you very much for your help!
Found this on line 633 of pins_teensy.c:

Code:
	analog_init();
	// for background about this startup delay, please see this conversation
	// https://forum.pjrc.com/threads/31290-Teensey-3-2-Teensey-Loader-1-24-Issues?p=87273&viewfull=1#post87273
	delay(400);
	usb_init();

400ms is a lot of time if you don't have any USB connection. I have the USB if I want to "debug" and once it is ready to use I don't need the USB anymore.

To be honest I was trying to understand why this delay is necessary but I don't understand it :p

But I am able to start the program in 40ms now.

Thank you again for your help!
Adriano

If I remember correctly, th3 delay was included to allow slow I2C chips to initialize. The fast boot led to problems before.
 
Anyone who's been around this forum for a long time can probably remember "Teensy loses my program after power down". Seemed like we were getting that same question almost every week.

Of course the real problem was initializing some extra hardware at the beginning of setup(). It would work reliably every time they upload new code, since the hardware had already been powered up. But on cold boot, Teensy would start up too quickly and their code lacked any way of detecting or alerting them about failure to initialize hardware. Then their program would just sit there, totally unresponsive, stuck in some loop waiting on the uninitialized hardware.

Everyone who encountered this problem incorrectly concluded it was a defect with Teensy, rather than a deficiency with their program. They really did believe Teensy wasn't keeping their program in its nonvolatile flash memory!

Often people would use code designed (by others) for Arduino Uno. All Arduino products have lengthy delay because their bootloader runs first and jumps to the user's program after a timeout waiting for the PC. This situation was doubly bad, because they were unfamiliar with how that particular code worked, but because it was known to work properly on Arduino Uno, failure of the same code on Teensy *really* reinforced the assumption that Teensy was defective.

I hope you can see the rationale for this delay. It's almost completely eliminated what was once a very common problem.

Of course you can edit or just delete the delay. Don't be shy, it's fine to just delete it completely if you want fast startup. Just be aware of the startup times of any other hardware you're using. Fast reboot can also confuse some USB hubs.

Perhaps the delay should be made into a weak alias hook, like the ones for executing code in the startup process (see mk20dx128.c for details). Of course, if you want to run something with minimal delay right at startup, that early/watchdog hook gives you easy access to the earliest possible moment, before anything else has run. This give very fast startup response! The late hook can also be used, which is much easier since the hardware and software runtime environment have been set up.
 
Last edited:
[...] Of course, if you want to run something with minimal delay right at startup, that early/watchdog hook gives you easy access to the earliest possible moment, before anything else has run. [...]

Can it be that the early hook no longer works with the newer Ardunio versions ?
I happened last night, trying to use it - but it did not work.
 
Last time I used it was porting the Adafruit_Sleepydog library. Worked then.

If you used the hook from C++ code, did you have an extern "C" declaration?
 
Glad the tip got you to that Adriano, I knew it was there.

It was the "confuse some USB hubs" issue I was referring to with "allow computers to deal better with the startup". I knew Adriano was using USB - provided sample and details didn't say it was for debug only.

Paul - Though that usb_init() code always runs - could the delay be made conditional on the sketch having USB compiled in?

I didn't know about these (gosh a wiki would be cool):
Code:
void startup_early_hook(void)		__attribute__ ((weak, alias("startup_default_early_hook")));
void startup_late_hook(void)		__attribute__ ((weak, alias("startup_default_late_hook")));
 // ...
void ResetHandler(void)
{
 // ...
	// programs using the watchdog timer or needing to initialize hardware as
	// early as possible can implement startup_early_hook()
	startup_early_hook();

Indeed rushing some cold devices on fast Teensy startup is a problem.

The other common issue I see is so many sample sketches have the inherited "while (!Serial);" in them when they run without a serial monitor online, or are offline on battery. That really makes the Teensy look dead - and thus qBlink() was born - and a timeout in that while().

I was in ResetHandler(void) the other day with Kurt's code on the HSRUN Serial# edits and had no idea how I got there - I see the context for this now and how it gets there:
Code:
void (* const _VectorsFlash[NVIC_NUM_INTERRUPTS+16])(void) =
{
	(void (*)(void))((unsigned long)&_estack),	//  0 ARM: Initial Stack Pointer
	ResetHandler,					//  1 ARM: Initial Program Counter
 
Hi all,

I'm considering adding this code to the mk20dx128.c file:

void reset_vec(void) __attribute__ ((weak, alias("ResetHandler")));

Along with altering the _VectorsFlash shown in the post above to use reset_vec (I'd be quite happy to see this officially changed btw).

The thing is, when I was programming my two new Teensy 3.5's I was surprised that quite a lot of hardware registers were "set up" even though I wrote my own main() function. With Arduino, if you have your own main() it skips setting up quite a lot of things, though the bootloader leaves the two COM port pins (0, 1) configured for comms rather than being digital IO. It's just I really intended to program the chips at a low level, but now I'm not sure if my code is doing everything it needs to since the hardware isn't in a fully reset state.

Also, I notice you can have your own systick_isr with Teensy, along with all other isr's, however ResetHandler relies on having systick_millis_count updated so it can use the delay function (shown in post #3 here). So without allowing us to customise things via this reset_vec, we are being locked in somewhat to the way things work now. The fault_isr also keeps polling some things too which is making me think... so...

I also want to ask, is there a risk of bricking the Teensy with a custom reset_vec function? I'm asking because I don't really know how the Teensy bootloader works. Also (if possible) can you tell me what state the bootloader leaves the hardware registers in, assuming it's going to play with port A (looking at the schematic) and configure the USB port at a minimum.

Finally, does anyone know if there's any public domain USB handling code available for these chips? Coming from a MEGA2560 environment, I was hoping it was similar but it looks far more complicated than simply setting up a clock and poking (/peeking) characters into a register to transfer data and checking flags for completeness. Does the USB transfer of this chip require interrupt(s)? For one application I have in mind, I may want to limit what interrupts are used so the one I have has no competition.

Thanks for any advice,
Jason.
 
With Arduino, if you have your own main() it skips setting up quite a lot of things,

Please keep in mind with Arduino Uno & Mega, even if your code skips everything, you've still got another chip on the PCB with a lot of code implementing the USB communication. Even if your program compiles to only a couple hundred bytes, there's still many thousands of bytes of code running on your Uno or Mega in the other chip.

On a single-chip board like Teensy, or Arduino Leonardo or MKR1000, all that USB functionality gets compiled into your program.


I also want to ask, is there a risk of bricking the Teensy with a custom reset_vec function?

This should be fine. But you'll almost certainly have to press the button to get into bootloader mode.

Finally, does anyone know if there's any public domain USB handling code available for these chips?

If MIT license is close enough, just look in you Arduino hardware/teensy/avr/cores/teensy3 folder.

Coming from a MEGA2560 environment, I was hoping it was similar but it looks far more complicated than simply setting up a clock and poking (/peeking) characters into a register to transfer data and checking flags for completeness.

With the hardware serial ports, if you don't enable the FIFOs or other extra features, they work pretty similarly to the ones on AVR.

One important difference, which exists in pretty much all modern chips, is everything defaults to a low-power state. You have to enable clocks to most things before you start using them, even the GPIO pins. This adds extra setup steps, but if you're designing a low power project, it's very helpful to not have everything turned on and using power by default, as happens on AVR.

Does the USB transfer of this chip require interrupt(s)?

It's important to keep hardware serial and USB separate. I know they tend to be thought of the same way when using Arduino Uno & Mega, which really only has hardware serial.

The USB is quite complex. It uses both interrupts and DMA. While code could be written that uses only polling, the DMA is essential. There isn't any register-based access to the actual data, like you would do with a UART for serial.

For one application I have in mind, I may want to limit what interrupts are used so the one I have has no competition.

Maybe you could take advantage of the nested priority levels? Just set your interrupt to the highest priority (0 = highest, 255 = lowest) and it will be able to interrupt the USB interrupt.
 
If you're just getting into learning ARM, I highly recommend you get Joseph Yiu's book:

https://www.amazon.com/dp/0124080820

Most of this info isn't documented by any of the semiconductor manufacturers. ARM has reference manuals that technical do document this stuff, but they don't *explain* any of it. Joseph Yiu does. If you want to dig into the low-level details and develop all your own bare metal code from the ground up, even just know the details to do so, you really do need this book.
 
I know Arduino with bootloader boots after ~seconds,
and with no delay without bootloader (ICSP programming)

but didn't notice teensy have booting delay,400ms maybe insignificant ,
is that delay in 3.5/3.6 ,teensy 3.1, or all of them?

I'll subscribe this post anyway , and gonna buy the book.
Thanks Paul ;)
 
but didn't notice teensy have booting delay,400ms maybe insignificant ,
is that delay in 3.5/3.6 ,teensy 3.1, or all of them?

The 400 ms startup delay is in the code used for all Teensy 3.x and LC.

See message #5 in this thread for background on why we have this delay in the code.
 
The 400 ms startup delay is in the code used for all Teensy 3.x and LC.

See message #5 in this thread for background on why we have this delay in the code.

Yes, I give no doubt about the booting delay

I assume booting delays are needed in many devices, such as SD cards? (SD/ SdFat library?)

I remember I once modified the begin timeout in library (1000ms) to many shorter length (50,100,500, etc)
and met much higher percentage of begin failures.
 
In some experimentation I did breaking up the delay(400); noted above to look like this:
Code:
	delayMicroseconds(40000); // split up the  // delay(400);
	usb_init();
	delay(360);

It holds off setup() entry to the same 400ms, but generally Serial/USB comes online 200-300 ms faster at < 410 ms perhaps instead of something like 650ms - at least I usually see that on Win 10 with TyCommander (TyQt).

FrankB gave this a try and it didn't work like that for him - he noted a DELL monitor with a HUB - I found I have a DELL display like that - but haven't tried it yet to see what really happens or further adjustment might help.

With my external powered hub holding my Teensy's this was the best mix I could find for regular improvement. Using less than 40ms before usb_init() didn't help so I left that. And playing with the 360ms would not often save more than a ms or so as I suspect that is the response time of Windows 10 on the arrival of a USB device.

But knowing it is there and why means it can be adjusted based on use - and then rewritten after each update to TeensyDuino. Even my case could lose the delay(360) and just wait in setup() for Serial doing other stuff that the hardware can support that quickly.
 
Status
Not open for further replies.
Back
Top