Question about WaitForInterrupt()

Started by Don Kinzer July 23, 2004
When a task executes WaitForInterrupt() and then the interrupt
occurs, the waiting task is activated next according to the docs.
I'm guessing that it is possible for that task to be superseded on
the very next timer tick (which could be immediately).

If this is so, it seems that it would be a good idea for the task to
lock itself before the WaitForInterrupt() call so that it will be
locked when it resumes. This may not work, however, depending on how
the BasicX VM is coded.

Comments, please.



> ... for the task to lock itself before the WaitForInterrupt() call so
that it will be locked when it resumes...

If it blocks task switching and, therefore, interrupts, how could it
ever resume? Sounds like a deadlock to me but, you're right, the OS
might handle it as a special case. Tom
Tom Becker
--... ...--
www.RighTime.com
The RighTime Clock Company, Inc., Cape Coral, Florida USA
+1239 540 5700



--- In , "Tom Becker" <gtbecker@r...> wrote:
> If it blocks task switching and, therefore, interrupts, how could it
> ever resume?

I doubt that locking a task blocks interrupts - just task switching.
If it did block interrupts, the RTC wouldn't run, you couldn't do any
serial I/O, etc. when locked.

I was thinking that the WaitForInterrupt() might be a special case
since the calling task is essentially blocked until the interrupt
occurs anyway. Moreover, it seems that if you are trying to
synchronize with the external event, you might not want any tasks
intervening and the only way to do that reliably is to lock the task
before the wait begins unless the OS automatically locks the task for
you when the interrupt is received. The manual, however, is silent
on the subject.

A little help, please, from NetMedia?



> ... if you are trying to synchronize with the external event, you
might not want any tasks intervening...

WaitForInterrupt(), by definition, blocks its task; execution within
it's task will not proceed until the interrupt occurs. Meanwhile, one
hopes, other tasks can run unimpeded, fully expecting that when the
interrupt occurs they will lose control to the handler. Those other
tasks do not intervene; they are deferred and might be entirely
invisible to the interrupt handler.

Once the interrupt has occurred, the statement after the
WaitForInterrupt() gets control; if you need to prevent further
interruption of continuous execution of that code, perhaps you need to
disable interrupts altogether. I will be surprised to learn that the
interrupt handler code can itself be interrupted before its first
statement execution so, I expect, you can disable interrupts with the
first post-interrupt statement and be safe from disturbance until you
reenable them.

Interrupts are not necessarily intended to synchronize but they do help
provide more prompt response to stimulus than when polling for that
stimulus, and they allow multitasking to make better use of the machine
resources than otherwise spinning, testing and waiting allows.

As it happens, I'm moving two-axis quadrature code from polling to
interrupt as I write this. Over the next few days, I'll have your
answer if Netmedia doesn't provide it here sooner. Tom
Tom Becker
--... ...--
www.RighTime.com
The RighTime Clock Company, Inc., Cape Coral, Florida USA
+1239 540 5700



--- In , "Tom Becker" <gtbecker@r...> wrote:
> Once the interrupt has occurred, the statement after the
> WaitForInterrupt() gets control...

Ah, yes! If that statement were Call LockTask(), that would prevent
another task from intervening until it was unlocked.

While pondering this, I also wondered what would happen if one task
were to execute WaitForInterrupt() and then another were to do the
same. Would the second return immediately, block forever, block
until the second interrupt, or ???


> ... When a task executes WaitForInterrupt() and then the interrupt
occurs, the waiting task is activated next according to the docs. I'm
guessing that it is possible for that task to be superseded on the very
next timer tick (which could be immediately)...

You are correct, Don, but it does not seem to interrupt before the first
interrupt handler statement.

Initially, my interrupt handler was, indeed, frequently interrupted by
the tick, lengthening the handler's execution time by ~1.95mS; my
interrupt handler code itself takes ~1.1mS, so a tick almost triples the
handler maximum duration.

I placed a Call LockTask() as the first statement of the interrupt
handler code, immediately after the WaitForInterrupt(), and a Call
UnlockTask() at the end of my handler code and the ticks no longer
interferred. Conveniently, since my code handles the interrupt and then
loops back to the WaitForInterrupt(), the UnlockTask() is not necessary;
the WaitForInterrupt() implicitly unlocks the task anyway.

Also, FWIW, once a WaitForInterrupt() is executed, its task is suspended
until the interrupt pin, BX-24 pin 11, toggles as specified in the
WaitForInterrupt() parameter. If the pin isn't toggled the interrupt
remains forever pending and its task nevers regains control. This makes
some code techniques unsuitable for the handler; in my case, for
instance, I can no longer detect motion stall in the quadrature
interrupt code alone. You can, however, break the interrupt task
deadlock - from another task - by toggling pin 11. You could, for
example, have another timing task detect the stall and break the
interrupt deadlock, much like a watchdog. Tom
Tom Becker
--... ...--
www.RighTime.com
The RighTime Clock Company, Inc., Cape Coral, Florida USA
+1239 540 5700



--- In , "Tom Becker" <gtbecker@r...> wrote:
> ... it does not seem to interrupt before the first
> interrupt handler statement.

Thanks for researching this reporting the result. I was just about
to embark on that experiment myself.

Don in Portland, OR


BTW, the BX-24 interrupt latency is on the order of 100-150uS. I don't
think I've ever seen that expressed. Tom
Tom Becker
--... ...--
www.RighTime.com
The RighTime Clock Company, Inc., Cape Coral, Florida USA
+1239 540 5700