Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    Timer.Alarm callback is blocked by caller

    Scheduled Pinned Locked Moved Discussion
    alarmtimerblockinginterrupttimer.alarm
    3 Posts 2 Posters 1.4k Views 3 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • N Offline
      nathanh
      last edited by

      Hi,

      I am experiencing an issue in the way the Timer.Alarm functionality appears to be working on my project, in that if I setup an alarm to fire a callback in X seconds, and the calling process then works for Y seconds (sleep, loop etc) and Y>X, the Alarm callback won't fire until the caller has finished.

      For example (and yes I know this is not the best way but for illustrative purposes):

      def timer_callback(src):
          Timer.Alarm(timer_callback, 5)    
          t = utime.gmtime()
          print("{0:02}:{1:02}:{2:02} - Timer Callback".format(t[3], t[4], t[5]))
          utime.sleep(10)
      

      So this sets the callback to trigger every 5 seconds, prints out the current time and sleeps for 10 seconds

      >>> alarm_test.timer_callback(None)
      00:01:17 - Timer Callback
      00:01:22 - Timer Callback
      00:01:32 - Timer Callback
      00:01:42 - Timer Callback
      00:01:52 - Timer Callback
      00:02:02 - Timer Callback
      00:02:12 - Timer Callback
      

      So from this you can see that a Timer callback that sets an Alarm will block the timer until its processing has finished (as you can see with the output happening every 10 seconds, not 5). Is this the intended behavior? I would expect the alarm to trigger regardless of what the calling program is doing like an interrupt.

      Just for the sake of it I even implemented another function just to set the alarm and call it in a new thread

      def setalarm_thread(fn, alarmtime):    
          Timer.Alarm(fn, alarmtime)
      
      def timer_callback(src):
          _thread.start_new_thread(setalarm_thread, (timer_callback, 5))    
          t = utime.gmtime()
          print("{0:02}:{1:02}:{2:02} - Timer Callback".format(t[3], t[4], t[5]))
          utime.sleep(10)
      

      And the result is the exact same, the Alarm callback is blocked until the calling function has finished.

      So is this the expected behavior? Or am I doing something silly here? Any help would be greatly appreciated.

      robert-hhR 1 Reply Last reply Reply Quote 0
      • robert-hhR Offline
        robert-hh @nathanh
        last edited by

        @nathanh two things:
        a) usually, the time alarm is not enabled in the callback, at least not for periodic callbacks. You can do that one one_shot callbacks.
        b) Callbacks are comfortable variants of an Interrupt Service Routine (ISR). Like ISR's, they are meant to finish as soon as possible. Until they return, further calls to it are blocked. That is the intended behavior. So having a long sleep in a callback is clearly a DON'T. Having the callback working longer than the expected time between interrupts is a design problem.

        1 Reply Last reply Reply Quote 1
        • N Offline
          nathanh
          last edited by

          @robert-hh Thanks for that insight. My issue was that (unlike my example) the callback would trigger a separate function that included an additional but non-related alarm call back that would get 'stalled' from the original callback.

          Having worked out that as long as an alarm is created from the 'main' thread it will not be blocked by work from the caller I have adjusted my program to use a mix of sensor alarms and secondary "worker" threads which are triggered by not run from the alarm callback. Not sure if it is the best way but seems to allow things to run smoothly without blocking.

          1 Reply Last reply Reply Quote 0

          Hello! It looks like you're interested in this conversation, but you don't have an account yet.

          Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

          With your input, this post could be even better 💗

          Register Login
          • 1 / 1
          • First post
            Last post

          Pycom on Twitter

          Pycom