Shop OBEX P1 Docs P2 Docs Learn Events
Object start timeout — Parallax Forums

Object start timeout

Don MDon M Posts: 1,652
edited 2013-08-14 06:45 in Propeller 1
I'm wondering if it's possible to start an object as part of the main program and somehow set a timeout limit so if it does not start properly have it reboot and start over.

I have a display that sometimes comes up with some gibberish and doesn't return the value from it's start up method so the program hangs. If I had a way of doing a timeout so that if the result isn't received in say 1 second that it reboots.

Anyone have any ideas they'd like to share on how this could be done?

Comments

  • Don MDon M Posts: 1,652
    edited 2013-08-13 14:34
    Here's the beginning of the Main method:
    PUB Main | rslt
    
      rslt := \display.start  
    
    

    So if rslt isn't returned in 1 second it would reboot and try again.
  • Don MDon M Posts: 1,652
    edited 2013-08-13 14:43
    I tried this and it doesn't work.
    PUB Main | rslt
    
      repeat
        rslt := \display.start
        if rslt == -1
          quit
        else  
          reboot
             
    
  • Don MDon M Posts: 1,652
    edited 2013-08-13 14:58
    Looking at the FDS rxtime method I tried something like this and it doesn't work either.
    PUB Main | rslt, t
    
    
      t := cnt
      repeat until (cnt - t) / (clkfreq / 1000) > 1000 OR rslt == -1
        rslt := \display.start
    
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-08-13 16:03
    I think you need your timeout timer in a cog that doesn't call the problematic method.
  • Don MDon M Posts: 1,652
    edited 2013-08-13 17:08
    Duane Degn wrote: »
    I think you need your timeout timer in a cog that doesn't call the problematic method.

    I'm not sure I follow what you're saying here... do I need to launch a timer object in it's own cog? Just to clarify- when the display does start up ok (-1) the program continues and runs.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-08-13 18:32
    Don M wrote: »
    I'm not sure I follow what you're saying here... do I need to launch a timer object in it's own cog?

    If the Start method doesn't always return a value then another cog would need to monitor it.

    If you already have another cog running Spin code, you could use it to do the monitoring but if don't have another cog running Spin code, then launching a timer cog should work.
    PUB Main 
      
      globalDisplayReturn := -2 ' some impossible return value
      watchdogCog := newcog(Watchdog(1000), @stack) 'watchdogCog would need to be global as it is used in this program
    
      globalDisplayReturn := \display.start
       
      ' do the rest of your program
    
    PUB Watchdog(watchInterval) | timer
      
      watchInterval *= clkfreq / 1000
      timer := cnt
      repeat while (cnt - timer) < watchInterval and globalDisplayReturn == -2
        
      if  globalDisplayReturn == -2
        reboot
      else
        cogstop(watchdogCog)
         'cogstop(cogid)  ' I think this is another option for a cog to stop itself.
         
    

    I have not tested the above code, but I think something like that should work.
  • kwinnkwinn Posts: 8,697
    edited 2013-08-13 18:33
    Have the new cog set a variable in the main program to a specific value and have the main program check that variable after the timeout period.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-08-13 18:40
    I think you could simplify the code I posted a bit.
    PUB Main | rslt, watchdogCog
      
      watchdogCog := newcog(Watchdog, @stack) 
    
       rslt := \display.start ' rslt isn't used in watchdog function
      
      cogstop(watchdogCog) ' watchdog is no longer need
     
      ' do the rest of your program
    
    PUB Watchdog
      
      waitcnt(clkfreq + cnt)
    
      reboot
    
    
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-08-13 18:56
    kwinn wrote: »
    Have the new cog set a variable in the main program to a specific value and have the main program check that variable after the timeout period.

    It sounds like the main program freezes if the display driver doesn't launch properly. If this is the case the main program can't check anything.

    The code in post #9 assumes if the display driver returns any value, then the program isn't frozen and there's not a need to reboot.

    Is there a return value which would indicate there's a problem? If so you'd want to add a check for this after the display is started.
  • kwinnkwinn Posts: 8,697
    edited 2013-08-13 19:06
    Good point. Time to use PST and some debug statements in the "display.start" code to see where it hangs up then?
  • Don MDon M Posts: 1,652
    edited 2013-08-13 19:06
    Duane-

    That looks like something that may work. Shop is shut down for tonight but will check it out in the morning.

    I think it could be even simpler:
    PUB Main | watchdogCog
      
      watchdogCog := newcog(Watchdog, @stack) 
    
      display.start
      
      cogstop(watchdogCog) ' watchdog is no longer need
     
      ' do the rest of your program
    
    PUB Watchdog
      
      waitcnt(clkfreq + cnt)
    
      reboot
    

    This way if the display starts then fine otherwise it should invoke the WatchDog and reboot.
  • cavelambcavelamb Posts: 720
    edited 2013-08-13 20:15
    Dunno, Don, about that simpler code.
    It make recover after a non-start of the display part (what;s that all about anyway??)
    But it doesn't provide a way to know that the display.start failed.
    And the next thing you do is stop it, so whay bother starting it in the first place??

    See Duane's (#10)
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-08-13 21:53
    cavelamb, I'm not sure what your asking about.

    The code in post #12 is just about the same as the code in post #9. I originally had the same code Don posted but then remembered he had an abort trap and a return value. I figured he would want the return value if the object aborted. I figured an abort was different than a freeze.

    The code stops the watchdog cog after the Start call since if the Start method doesn't freeze, the watchdog is no longer need. I gather the only information to be gain from adding a return value is that the driver was successfully started. The return value doesn't exist when there is a problem.
  • Don MDon M Posts: 1,652
    edited 2013-08-14 05:08
    Here's is what I implemented into my code and so far it works good.
    PUB Main | WatchDogCog
    
      WatchDogCog := cognew(WatchDog, @stack)               ' Launch WatchDog for display startup
    
      display.start                                         ' Start display
    
      cogstop(WatchDogCog)                                  ' If display started ok then stop WatchDog
    
    PUB WatchDog | t
    
      t := cnt - 1776                                       ' sync with system counter
        repeat 750                                          ' Set delay for 750 mS
          waitcnt(t += MS_001)
    
      reboot
    

    Thanks Duane for your help!
  • Don MDon M Posts: 1,652
    edited 2013-08-14 06:45
    kwinn wrote: »
    Good point. Time to use PST and some debug statements in the "display.start" code to see where it hangs up then?

    What I'm using is a NewHaven Display 20x4 OLED in 4 bit parallel mode. I had to modify the OBEX 4 bit LCD driver to work with this display. I consulted with NewHaven as to their requirements for initializing the display. That part I got fixed.

    So my main program runs through a repeat loop reading a rotary encoder to select from different menu options. It repeats the "moveto (line, col)" and then displays a message at that line. The problem that I am having is that if you download new code to the Prop or happen to reset the Prop via USB then I would intermittantly get a screen full of gibberish and the program locked up because it couldn't get past the initialization of the OLED display. So basically when the display has already been running and you do a warm reset / restart.

    What I discovered today thanks to the WatchDog code (thanks Duane!) is what causes the problem. It has to do with the continual commands being sent to the display in the repeat loop and if the Prop happens to be reset in the middle of one of those commands then the display gets "lost" the next time it is initialized from reboot. If you reboot it one more time it straightens out. Always.

    So next I need to find out if there is anything else I can do to force the display to re-initialize if it would have happened to be in the middle of a command instruction and was interrupted.
Sign In or Register to comment.