Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 40

Thread: _reboot_Teensyduino() vs. _restart_Teensyduino()

  1. #1

    _reboot_Teensyduino() vs. _restart_Teensyduino()

    Hello all!

    Question based on previous question located here: http://forum.pjrc.com/threads/23776-...Software-Reset

    Does the _restart_Teensyduino_() method exist for the Teensy3? I see it located in core_pins.h, but I get an error when trying to compile an example sketch with it. _reboot_Teensyduino() works fine, but requires the Teensyduino software to be open, and results in a reprogram command.

    My usage case is for a controlled soft-reboot, without re-uploading the program. I have an integrated battery and charger, and don't expect the Teensy to ever be rebooted due to loss of power or a reprogram event, so would like to hedge against long-timeline problems developing that are generally hard to foresee and test..

    Any help would be appreciated, thanks for your help in advance.

  2. #2
    Apologies, example code:

    Don't leave it running, it results in a reprogram loop every 5 seconds.

    Replacing _reboot_Teensyduino_(); with _restart_Teensyduino_() results in an error.

    void setup(){

    // Note, nonstandard Teensy 3 output LED pin.
    pinMode(5, OUTPUT);
    digitalWrite(5, HIGH);
    delay(50);
    digitalWrite(5, LOW);


    delay(5000);

    _reboot_Teensyduino_();



    }

    void loop(){
    digitalWrite(5, !digitalRead(5));
    delay(200);


    }

  3. #3
    Senior Member pictographer's Avatar
    Join Date
    May 2013
    Location
    San Jose, CA
    Posts
    664
    If you're open to additional hardware, you could add a watchdog timer chip or a second Teensy so the two could watch each other.

  4. #4
    I love the watchdog timer chip - that would be more robust than a purely programmatic reboot request.

    I saw in the MK20 documentation that it has an internal watchdog timer, I will have to look into that as well. Thanks for the idea!


    In the meantime though, I'd like to get the restart function working - I must be missing something, because the reboot function works exactly as advertised.

  5. #5
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,342
    Quote Originally Posted by kam42 View Post
    Does the _restart_Teensyduino_() method exist for the Teensy3?
    No, this has not yet been implemented for Teensy 3.0.

    If you just want to reboot the chip, I believe software reset using a hardware register should be possible. From the reference manual:

    6.2.2.8 Software reset (SW)
    The SYSRESETREQ bit in the NVIC application interrupt and reset control register can
    be set to force a software reset on the device. (See ARM's NVIC documentation for the
    full description of the register fields, especially the VECTKEY field requirements.)
    Setting SYSRESETREQ generates a software reset request. This reset forces a system
    reset of all major components except for the debug module. A software reset causes the
    RCM's SRS1[SW] bit to set.
    Here's the ARM documentation:

    http://infocenter.arm.com/help/index.../Cihcbadd.html

    Scroll down to the "Application Interrupt and Reset Control Register" section (I can't find a way to copy a link directly to that part). You can also click the left side to expand "NVIC register descriptions" and click it from the list.

    So in theory, writing the correct value to address 0xE000ED0C ought to cause a software reset.


    However, a software reset might reset the USB, which can cause a USB disconnect. The _restart_Teensyduino_() tries to simulate a reboot, but without the USB disconnecting. It is quite difficult to implement, because this requires the USB stack to be able to detect previous initialization. Teensy 2.0's USB stack was rewritten a couple years ago for this purpose. So far, I haven't done this with Teensy3. It's quite a lot of work!


    If you do explore using the ARM AIRCR register, please post here about what worked (or didn't work).

  6. #6
    Paul,

    Thanks for the reply, I'll look into the documentation you kindly provided and report back. Fortunately, I would be calling the software reset after the USB is disconnected so I don't think that will be a major issue.

  7. #7
    Senior Member pictographer's Avatar
    Join Date
    May 2013
    Location
    San Jose, CA
    Posts
    664
    Did you know there are two programmable processors on the Teensy 3? Well, one of them is only programmable by Paul, but it's still programmable. So another long term approach would be to sweet talk Paul into implementing a watchdog in the Cortex-M0 processor that boots the main Cortex-M4.

    Am I correct in assuming this is thread is for learning about fault-tolerance, not using a hobby board for functional safety where there is a significant hazard to people or property? If safety is an issue, a broader conversation might be prudent.

  8. #8
    Good point about the M0, that would be fantastic.

    Correct with respect to fault tolerance - these boards aren't going into anything related to functional safety. Pure data acquisition and logging boards. My concern is that running these continuously for 6 months is a difficult usage case to debug, and I like the idea of having a relatively fresh start every so often. Hence, a reset after completing data download and battery charge.

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,342
    Quote Originally Posted by pictographer View Post
    So another long term approach would be to sweet talk Paul into implementing a watchdog in the Cortex-M0 processor that boots the main Cortex-M4.
    I'm open to feedback and ideas, but first I need to understand why a feature would be valuable and have a good idea of how it should actually work. So far regarding this reboot, neither of those are clear to me. Then any new feature needs to have some significant advantage over other ways, in this case using the watchdog that's already built into the chip. Then, of course, it goes onto my extremely long to-do list. But like many other things, such as the low power update, I do usually get to them eventually. But especially with change in the Mini54 chip, my strong preference is "ain't broke, don't fix", so first I'd really like to talk about the MK20's watchdog timer and other capabilities.

  10. #10
    Hi Paul,

    I had some time to work with your above points, and have successfully rebooted both my custom boards and normal Teensy 3.0 boards using the below code. Required writing to the SYSRESETREQ bit. The program is rough, and doesn't follow the normal register conventions of offsets and shifts as I am not very familiar with them.

    Code:
    // Should restart Teensy 3, will also disconnect USB during restart
    
    // From http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/Cihcbadd.html
    // Search for "0xE000ED0C"
    // Original question http://forum.pjrc.com/threads/24304-_reboot_Teensyduino%28%29-vs-_restart_Teensyduino%28%29?p=35981#post35981
    
    #define RESTART_ADDR       0xE000ED0C
    #define READ_RESTART()     (*(volatile uint32_t *)RESTART_ADDR)
    #define WRITE_RESTART(val) ((*(volatile uint32_t *)RESTART_ADDR) = (val))
    
    void setup(){
    
      // startup routine
      pinMode(13, OUTPUT);
    
      digitalWrite(13, HIGH);
      for(int i = 0; i < 10; i++){
        digitalWrite(13, !digitalRead(13));
        delay(200);
      }  
    
      delay(1000);
    
      // 0000101111110100000000000000100
      // Assert [2]SYSRESETREQ
      WRITE_RESTART(0x5FA0004);
    }
    
     // Should never get here. 
    void loop(){}
    Let me know if this works for you also.

  11. #11
    Senior Member pictographer's Avatar
    Join Date
    May 2013
    Location
    San Jose, CA
    Posts
    664
    How are the data downloaded? If there's a network, then there's a possibility of putting a watchdog on the net. This could have the added advantage of having a separate power source and the ability to report failures.

    By the way, is it legal to call digitalRead() on an output and what does it do?

  12. #12
    By the way, is it legal to call digitalRead() on an output and what does it do?
    Nifty little trick I learned here on the forum to easily blink a light. From my experience with it, seems it is possible to call digitalRead on an output.

    Data downloaded via software serial over USB from the microSD card to a host computer.

    I currently have the restart set to run every time it detects the USB cable disconnected from the device.

  13. #13
    HI there,
    Thanks for posting the code on how to reset the Teensy 3. I could sure use it.
    It doesn't seem like the whole code posted to the thread? I only see the setup() call but not the loop or the definition of WRITE_RESTART.
    Thanks for any follow up...
    In my case, I'm specifically trying to reset the Teensy if the USB connection gets ;lost'. For some reason, my Teensy sometimes does this, probably because it contains I2C code to a sensor, and that itself gets hosed because the I2C code can get hung permanently.

  14. #14
    It's all there, the loop is empty since code should never get there. The definition of WRITE_RESTART is defined before setup(), #define WRITE_RESTART(val) ((*(volatile uint32_t *)RESTART_ADDR) = (val))

  15. #15
    Senior Member
    Join Date
    Jan 2013
    Posts
    966
    Quote Originally Posted by astroyam View Post
    because it contains I2C code to a sensor, and that itself gets hosed because the I2C code can get hung permanently.
    It's not a good idea to fix that problem with a watchdog timer. There is an alternative i2C library available that has a timeout/restart function that would help overcome the problem temporarily but ultimately its better to find and fix the root cause. It could well be a problem with noise/signal integrity on the I2C bus.

  16. #16
    Quote Originally Posted by Headroom View Post
    It's not a good idea to fix that problem with a watchdog timer. There is an alternative i2C library available that has a timeout/restart function that would help overcome the problem temporarily but ultimately its better to find and fix the root cause. It could well be a problem with noise/signal integrity on the I2C bus.
    Thanks, and yes I believe you could be right about the lines.
    What is the name of that I2C library with the timeout? That would be a great start.

  17. #17
    Quote Originally Posted by kam42 View Post
    It's all there, the loop is empty since code should never get there. The definition of WRITE_RESTART is defined before setup(), #define WRITE_RESTART(val) ((*(volatile uint32_t *)RESTART_ADDR) = (val))
    Thanks. For some reason the void loop() doesn't show on my screen, and the code stopped at '...get here.' I added the void loop(){} and it works. Thanks for that, I can definitely use it...

  18. #18
    Senior Member
    Join Date
    Jan 2013
    Posts
    966
    Quote Originally Posted by Headroom View Post
    It's not a good idea to fix that problem with a watchdog timer. There is an alternative i2C library available that has a timeout/restart function that would help overcome the problem temporarily but ultimately its better to find and fix the root cause. It could well be a problem with noise/signal integrity on the I2C bus.
    THIS is the alternative I2C library written by user nox771. I have not used the timeout feature with that particular library, but if you have questions about its application please ask in the thread I linked to.

  19. #19
    Quote Originally Posted by Headroom View Post
    THIS is the alternative I2C library written by user nox771. I have not used the timeout feature with that particular library, but if you have questions about its application please ask in the thread I linked to.
    Thanks. I have been using this library for a while, and had tried a while back to get the timeout feature to fix my issue, and hadn't got it to work. But now with that code plus the WRITE_RESTART, I've got a fix. Super. Mind you , as you point out, the root I2C miscomm is still undiagnosed, but I don't actually have time to get to it...

  20. #20
    Member neilh20's Avatar
    Join Date
    Jan 2014
    Location
    N California
    Posts
    54
    Thanks for the posts, the WRITE_RESTART(0x5FA0004) worked for me.
    As its a visible debug element, and I generate a system status report when the user inputs '?'
    I generate the following

    Code:
    resetReason();
    and gives a console output

    ResetReason:0x40 ExtResetPin - on reprogramming
    ResetReason:0x400 SoftWare - on executing a WRITE_RESTART(0x5FA0004)

    which has the following components

    Code:
       //K20 - on startup
      resetReasonHw= RCM_SRS0;
      resetReasonHw |= (RCM_SRS1<<8);
    Code:
    void resetReason() {
    	uint16_t mask=1;
    	Serial.print(strReason);
    	Serial.print(resetReasonHw,HEX);
    	do {
    		switch (mask & resetReasonHw){
    		//RCM_SRS0
    		case 0x0001: Serial.print(F(" wakeup")); break;
    		case 0x0002: Serial.print(F(" LowVoltage"));  break;
    		case 0x0004: Serial.print(F(" LossOfClock")); break;
    		case 0x0008: Serial.print(F(" LossOfLock")); break;
    		//case 0x0010 reserved
    		case 0x0020: Serial.print(F(" wdog")); break;
    		case 0x0040: Serial.print(F(" ExtResetPin")); break;
    		case 0x0080: Serial.print(F(" PwrOn")); break;
    
    		//RCM_SRS1
    		case 0x0100: Serial.print(F(" JTAG")); break;
    		case 0x0200: Serial.print(F(" CoreLockup")); break;
    		case 0x0400: Serial.print(F(" SoftWare")); break;
    		case 0x0800: Serial.print(F(" MDM_AP")); break;
    
    		case 0x1000: Serial.print(F(" EZPT")); break;
    		case 0x2000: Serial.print(F(" SACKERR")); break;
    		//default:  break;
    		}
    	} while (mask <<= 1);
    }
    Last edited by neilh20; 03-11-2014 at 10:42 PM.

  21. #21
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    Work-around for lack of restart in libraries for Teensy 3, and adapting from the above by kam32, here's a concise way to restart a Teensy 3 (not reboot which tries to down
    Code:
    #define CPU_RESTART_ADDR (uint32_t *)0xE000ED0C
    #define CPU_RESTART_VAL 0x5FA0004
    #define CPU_RESTART (*CPU_RESTART_ADDR = CPU_RESTART_VAL);
    then just use the macro CPU_RESTART in your application.

  22. #22
    Junior Member
    Join Date
    Jun 2014
    Location
    Johannesburg, South Africa
    Posts
    18
    Thanks neilh20 - this works so well!

  23. #23
    Junior Member
    Join Date
    Aug 2014
    Posts
    5
    Hi stevech

    I want to reset the teensy because it should become in the initial state.
    I have tried the CPU_RESTART macro and the _reboot_Teensyduino() procedure but did not work for me.
    I have tried this with when I was connected to the hardware serial port (USB) and via the AltSoftSerial ports.
    When I used the _reboot_Tensyduino(), then the Teensy tries to load the software again, and if not present it hangs.
    When I tried the CPU_RESART it sometimes hangs and somtimes not. Unpredictable;
    What can I do more to have a gracefull restart?

    EDIT: Found it. I still had other hard reboot code in the project
    Last edited by almulder; 12-23-2014 at 10:27 PM.

  24. #24
    Junior Member
    Join Date
    Feb 2015
    Posts
    9
    Hiya. Arduino noob here First post on forums.

    I guess I am posting this for other noobs out there looking to implement a soft reboot into the code- ie: reprogramming mode

    Copying from stevech above:

    #define CPU_REBOOT (_reboot_Teensyduino_());

    Then use CPU_REBOOT; in your loop.


    //*****Example Code:********

    Code:
    /*
      
      ON REBOOT:   -Flashes LEDS five times quickly on reboot.
     
      IN THE LOOP: -In the loop Flashes led once quickly, once not so quickly
                           -2 second pause and puts the Teensy 3.1 into Reboot Mode
    
      NOTE: If Teensy application is set to auto, it will reload current hex file
     */
     
    // Pin 13 has an LED connected on the Arduino 3.1 board.
    
    
    #define CPU_REBOOT (_reboot_Teensyduino_());
    int led = 13;
    
    // the setup routine runs once when you press reset:
    void setup() {                
      // initialize the digital pin as an output.
        pinMode(led, OUTPUT);     
        digitalWrite(13, HIGH);
        for(int i = 0; i < 10; i++){
        digitalWrite(13, !digitalRead(13));
        delay(50);
      }
      digitalWrite(led, LOW);
      delay(500);
      
    
    }
    
    void loop() {
      digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(100);               // wait for the blink of an eye
      digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
      delay(100);               // wait for a second
      digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);               // wait for a second
      digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
      delay(2000);               // wait for two seconds before reboot
     // CPU_REBOOT ;
     CPU_REBOOT ;
    
    }
    Last edited by mlmpenny; 02-18-2015 at 09:41 AM.

  25. #25
    Senior Member
    Join Date
    Jan 2015
    Location
    SF Bay Area
    Posts
    255
    Quote Originally Posted by kam42 View Post
    Nifty little trick I learned here on the forum to easily blink a light. From my experience with it, seems it is possible to call digitalRead on an output.

    Data downloaded via software serial over USB from the microSD card to a host computer.

    I currently have the restart set to run every time it detects the USB cable disconnected from the device.

    while you can use !digitalRead to blink LED, another option is to use the bitband toggle macro like this

    Code:
    *portToggleRegister(LEDPIN) = 1;

Tags for this Thread

Posting Permissions

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