[ECOS] Re: DSR stops running after heavy interrupts. Spurious Interrupt!

Nick Garnett nickg@ecoscentric.com
Mon Apr 10 17:20:00 GMT 2006

"Joe Porthouse" <jporthouse@toptech.com> writes:

> Nick,
> Thanks for you reply.
> Your right.  Not calling the interrupt_end() routine would cause the lock
> not to be released.  After your comment I started looking closer at my
> modification.
> My original modification of:
> /hal/arm/arch/current/src/vectors.S file at line 951.
>   cmp     v1,#CYGNUM_HAL_INTERRUPT_NONE   <-- from this
>   cmp     r0,#CYGNUM_HAL_INTERRUPT_NONE   <-- to this
> v1 originally contained the interrupt vector.  But I mistakenly believed
> this was the check of the return value from the ISR.  I modified it to look
> at r0, the return value from the isr. The return value from the isr will be
> 0-3 (really 1 or 3).  The CYGNUM_HAL_INTERRUPT_NONE is -1! (for some reason
> I thought it was +1 looking at the assembly listing) 
> Bottom line, my modification made sure that interrupt_end() would always be
> called, even when v1 == CYGNUM_HAL_INTERRUPT_NONE (spurious interrupt).
> I just did a quick test with the original code and verified that when a
> spurious interrupt occurs, the interrupt_end() routine is not called and the
> lock is not released and my problem occurs.
> Calling the interrupt_end() routine with a spurious interrupt did not seem
> to break anything.

This all makes sense.

> Was there a reason why interrupt_end() should not be
> called on spurious interrupts?

I guess it was an attempt to avoid doing more than the absolute
minimum on spurious interrupts. It looks like there is a bug in there,
since the scheduler lock doesn't get decremented. In general, spurious
interrupts shouldn't happen, which is why it has managed to lurk here
for so long.

> Now to figure out why I am getting a spurious interrupt with the simple UART
> code listed below?
> What should I look for in attempting to eliminate spurious interrupts?  Can
> they be eliminated?

The CYGNUM_HAL_INTERRUPT_NONE return from hal_IRQ_handler() only
happens when an interrupt occurs but the interrupt controller denies
all knowledge of it. One possibility is that hal_IRQ_handler() is
decoding a real interrupt wrongly and generating -1 by mistake.

What you need to do is find out why hal_IRQ_handler() is returning
this value. If you can put a breakpoint in hal_IRQ_handler()
where CYGNUM_HAL_INTERRUPT_NONE is returned, then you should be able
to look at all the relevant device and interrupt controller registers
and find out what is going on.

Also, enable assertions, it might tell you something.

Nick Garnett                                 eCos Kernel Architect
http://www.ecoscentric.com            The eCos and RedBoot experts

Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

More information about the Ecos-discuss mailing list