_reboot_Teensyduino() vs. _restart_Teensyduino()

Status
Not open for further replies.
thanks stevech , i used your method, have no clue what it does but it works so well!

the " _restart_Teensyduino_(); " method gave me the following compile error:

collect2.exe*:error: ld returned 1 exit status
Error creating .elf
 
Last edited:
Just experienced something pretty crazy with this method.

I used:

Code:
#define CPU_RESTART_ADDR (uint32_t *)0xE000ED0C
#define CPU_RESTART_VAL 0x5FA0004
#define CPU_RESTART (*CPU_RESTART_ADDR = CPU_RESTART_VAL);

Normally this works fine for me. But at the moment I have three Teensy's daisy-chained via RX/TX with the first teensy connected via USB.

I called the CPU_RESTART via the Arduino monitor and it instantly made my macbook go blank and restart :-S any thoughts on this?
 
Yup, _restart_Teensyduino_() has not ever been implemented on Teensy 3.x or Teensy LC. It's meant to simulate a reset, but leave the USB connected, similar to how Arduino Uno resets the '328 chip but not the 16u2 USB chip.

The ARM AIRCR register gives you a chip reset, which also causes the USB to suddenly disconnect.

Some USB drivers are buggy and behave badly if you disconnect the USB right in the middle of a USB control transfer. If you're implementing a USB-based command, a delay should be used, so the USB command can complete.
 
Hi

I am currently using the CPU_RESTART macro and it works quite reliably.

However, if the Teensy is connected to the PC over USB, the Virtual COMM port on the PC sometimes becomes inaccessible after the RESTART. I can still see it in Device manager but any Serial Terminal will report "Serial Port not found".
The solution is to disconnect the USB cable and reconnect it.

This brings me to the assumption that the USB host or drivers are not properly handling/recognizing what's happening and are going into an inconsistent state. This shouldn't be a total surprise since we're doing a brute force RESET on the processor followed by a very quick re-connect (on reboot), without ever gracefully perming (or allowing time for) a disconnect on the USB host.

With this in mind, is there any function in the Teensy library that we can call to send a USB disconnect command to the host, before we do the actual RESET?
I'm not familiar with the USB stack that teensy uses so any pointers would be quite helpful.

I am assuming that by sending a USB disconnect and then reboot, it will force both the host and teensy to handshake with each other, from a clean state.

Thank you in advance for any information on this.

EDIT:

Actually dug into the libraries and found some more info inside "hardware\teensy\cores\teensy3\usb_serial.h":

void begin(long) { /* TODO: call a function that tries to wait for enumeration */ };
void end() { /* TODO: flush output and shut down USB port */ };

I assume USB is being initialized at boot (tried adding a delay at the start of setup() but the teensy usb seems to be recognized even before this).

I also found the USB registers in kinetis.h but it's unclear what needs to be set. I was unable to find a datasheet explaining these.

In "hardware\teensy\cores\usb_serial\usb_api.cpp" there is much more comprehensive class which waits for enumeration on the begin() procedure and calls usb_shutdown() on the end() procedure but I think this is for ATMEL.

So I'm back to asking for your help here. Any pointers (even if just for a manual or sample) would be greatly appreciated.

Thank you very much
 
Last edited:
I have no idea if this will help or not... really just a blind guess, but find pins_teensy.c and look for this code:

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(250);
        usb_init();
}

Perhaps try increasing that delay before the USB is initialized. If you're using Windows (especially before version 10), maybe try 2000 or even 5000.

If this helps, and especially if you gain any insight about what delay a particular version of your operating system needs, please post a quick followup here. I'm sure that info could really help anyone else trying to do something similar.
 
Hi Paul

Thank you very much for pointing me in that direction.

I have played with the delay (went all the way up to 10 seconds delay), but it doesn't seem to fix the issue. This is the behavior with 10secs delay:
- When Teensy runs the code to reboot displayed in this thread, I can see the LEDs on my board go off, so I assume the board turns off
- During the delay period before usb_init(), I can see there is no COMM port in Device manager
- Once the delay period passes, I can see the Virtual COMM coming up in Device Manager accompanied by the typical "usb connect" sound.
- However, when I try to connect to the COMM port it will still say the Port in not available (the same error I reported initially).
- If I physically disconnect the USB cable and reconnect then it goes back to working correctly again. (again, the same behavior I reported initially).

I'm not really sure as to why this is happening. Since the port actually disappears from Device manager (the same way it does on a physical disconnect), one would expect it to come back up in a "clean" state.
However that doesn't seem to be the case.

Interestingly though, when the reset is performed during programming (by the Teensy loader/Cortex M0), this problem doesn't happen. [EDIT: not really sure if this is relevant in the context of debugging this particular case; see my next post ]
Is the RESET performed in a very different manner when it's called by the Teensy Loader? Is there any timing during which the processor is kept in RESET state (to clear capacitors, etc.)?

With the method on this thread it seems to reboot immediately, without any period to discharge components. I'm now inclined to suspect some components might be retaining some sort of state.

Maybe if you could shed some light on how you perform the reset from the Teensy loader I might be able to do some additional testing.

I can see from the schematics that it's the M4 that receives the USB message from the Loader and that the RESET button is attached to the M0, so I assume the M0 does a number of things including an external reset.
Is there any way to gain access to calling the function that triggers the M0 to reset the M4, in the smae way it does when the message from the Loader is received over USB?

Thank you
 
Last edited:
Hi Paul

Apologies for replying to myself but I seem to have made some progress here:

Firstly, in usb_init() there some code (commented out) that should reset the USB module:

//reset USB module
USB0_USBTRC0 = USB_USBTRC_USBRESET;
while ((USB0_USBTRC0 & USB_USBTRC_USBRESET) != 0) ; // wait for reset to end


I'm now running this before CPU_RESTART

1) In any case after further investigation it seems the problem is on the computer side with the Serial Terminal software itself or the drivers. This is my testing:

- Open Realterm and open the port. (I used Realterm because we get a finer control of what's happening but the same happens in the Arduino IDE).
- send data (optional)
- Disconnect and reconnect the physical USB cable
- Try to send more data: the data hangs (it doesn't seem to be sent).
- Close the COMM port in realterm
- Try to reopen the port: you get an error of Bad COMM port number (yet it shows in device manager).
- No other software can access the port until you physically disconnect and reconnect the device again (this time without any software connect on the comm port - also because no software is able to open it at this point).

An interesting fact is that if you close the comm port on the PC, while the cable is physically disconnected (or during a large delay you put before 'usb_init') before reconnecting, then device comes back up fine and you reconnect to the COMM port.

The problem has been narrowed down to when you keep the COMM port open on the PC while the teensy disconnects and reconnects over usb (wether through soft reboot or physical disconnect).

Bottom line I'm seeing the same behavior when I physically disconnect the cable and when I do a soft reboot, so I'm now assuming there's nothing wrong with the soft reboot. Even though it's a specific condition it is rather problematic: for applications that need permanent connection such as data logging, because any usb failure (or need to reboot) impairs the whole system.

2) I repeated the procedure above with an FTDI USB to Serial Adapter and it works fine and as expected (I don't experience any of the errors above: I am can keep the COMM port open during the disconnect and reconnect and when I reconnect the USB device I'm able to resume sending data without even having to close and reopen the Virtual COMM port).

With this in mind, I am inclined to believe the issue is likely with the Windows USB drivers for the teensy Virtual COMM Port. The procedure above provides a clear reproduction of the issue.
(I'm using Windows 7 x64 btw)

As for me, I'm leaving the USB reset code for other's reference although I'm not even sure it's needed at all. Playing with the delay before usb_init is likely useful though.

If you have any input on this - in particular any alternative device drivers - it' be great; I'll move on to another piece of the project and will come back to this as we make more progress.

All the best,
Pedro
 
Last edited:
Once again apologies for replying to myself, but in the meantime I've collected more information.

The problem with the Serial port not reseting after a Teensy reboot seems related to the Teensy USB drivers for Windows version <10.

On Windows 10, with the default Microsoft drivers, this procedure seems to work: teensy reboots, USB connection is lost and then comes back up and the COMM port access behaves normally (like I tested with the FTDI above). So the issue seems definitely related to the custom Serial drivers installed on windows <10 with most software.

A work around that seems to work fine in Windows <10 (despite the apparent USB driver issue) is to use the Monitor from TyQT (search the forum for this).
The Serial monitor of that tool can handle error conditions and re start the serial connection properly which is a huge relief if you're making use of this soft reboot feature.
 
Last edited:
So the issue seems definitely related to the custom Serial drivers installed on windows <10 with most software.
Teensy does not use custom drivers. It uses windows-builtin-drivers. With Windows <10, too.

work around that seems to work fine in Windows <10 (despite the apparent USB driver issue) is to use the Monitor from TyQT
TYQT just uses the present drivers (and the USB-HID proctol, i think).
The problem with most terminals is, that they are not aware of disappearing COM-ports (during reprogramming the Teensy). TYQT can handle this.
 
I'm not trying to advocate in favor of one thing working better than the other or stating bluntly that it's broken. This is really not what I'm going for here:
I'm merely reporting my own experience hoping to give others a head start if they run into the same issue.

The problem with most terminals is, that they are not aware of disappearing COM-ports (during reprogramming the Teensy).
In my post of March 30th, I've actually taken the time to compare the behavior using a Teensy and an FDTI USB to serial adapter.
My conclusions at the time were clear: the serial terminals handled very well disconnections of the FTDI, but failed (miserably I must add) with teensy disconnections.

The other important point I was making in my previous posts was regarding issuing a reboot using the MACRO discussed in this thread. I was not referring to the Teensy reboot after you flash it (that seems to work kind of OK).

Teensy does not use custom drivers. It uses windows-builtin-drivers. With Windows <10, too.
About this, as far as I know, you need to install "something" on windows <10. I know little about the architecture of the USB driver but as far as I understand the INF file (and eventually any other addition) work as a bridge to the native Microsoft VCP driver in earlier Windows versions.
In Windows 10 it does not appear to be necessary to install this file, so something is different.

If you are indeed interested in following through with this issue, I'd encourage you to try to reproduce all my detailed testing (especially the one of MArch 30th) as it's probably the best to understand the anomalous behavior I was reporting. (I rested my case when I tested an FTDI adapter, as I referred, and it worked against the same setup and test procedure where teensy failed).
 
Last edited:
Maybe you're hitting the USB serial bug present in all versions of Windows before 10?

https://www.youtube.com/watch?v=DRmvUsa2xuU

Here's a video I made for Microsoft - which prompted them to change their tune from "there's no bug" to actually fixing it in Windows 10. :) (also thanks to Phil T of Adafruit for finding the right people within Microsoft....)
 
Maybe you're hitting the USB serial bug present in all versions of Windows before 10?

https://www.youtube.com/watch?v=DRmvUsa2xuU

Here's a video I made for Microsoft - which prompted them to change their tune from "there's no bug" to actually fixing it in Windows 10. :) (also thanks to Phil T of Adafruit for finding the right people within Microsoft....)

Wow thanks for doing that! I know it takes more effort to run these things up the flagpole and get someone to notice... but in this case it seems like a big win for all of us who struggle with USB issues. Beer's on me if ever we meet!
 
Status
Not open for further replies.
Back
Top