This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: Re: DSR stops running after heavy interrupts. Spurious Interrupt!


Ok, found the source of the Spurious Interrupts, (your really going to love
this one). 

During my testing on determining why I was receiving occasional spurious
interrupts I noticed that the PXA2X0_ICIP (IRQ Interrupt Pending) register
was completely clear, even though the processor had just jumped to the IRQ
vector.

I checked the interrupt level register and even turned off all other
interrupts in the system but the problem still occurred.  It was like
something was clearing the interrupt before the IRQ vector jump occurred, or
some intermediate IRQ hardware flag was not getting cleared when the
PXA2X0_ICIP was getting cleared from the last interrupt.  I was really
scratching my head at this point.

My target is an Intel PXA255 xScale processor and I'm using the three built
in UARTs.

One of the events that the built in UART can generate an interrupt on is a
"Character Timeout".  The definition of this event is when at least one
character is in the Receive FIFO and no data has been received for four
character times.

Clearing this interrupt occurs if you read from the Receiver FIFO, set the
FCR[RESETRF] bit or A NEW START BIT IS RECEIVED!!!

So if the RX FIFO is below the trigger point and a timeout occurs an IRQ
request is generated, but if a new start bit is detected the IRQ request is
then immediately cleared. :(

Wow an interrupt that can clear its own IRQ request before service occurs!!!
That would surely cause a Spurious Interrupt.

If my conclusions are correct and I want don't want characters to hang out
in my RX FIFO I will either need to:
#1.  Stop using the UART FIFO.
#2.  Poll the FIFO for trailing characters.
#3.  Live with the Spurious Interrupts as a processor UART design issue.

I will probably follow through with #3 by commenting out lien 951 and 952 in
the /hal/arm/arch/current/src/vectors.S file.


Joe Porthouse
Toptech Systems, Inc.


-----Original Message-----
From: nickg@xl5.calivar.com [mailto:nickg@xl5.calivar.com] On Behalf Of Nick
Garnett
Sent: Monday, April 10, 2006 1:20 PM
To: jporthouse@toptech.com
Cc: ecos-discuss@sources.redhat.com
Subject: Re: [ECOS] Re: DSR stops running after heavy interrupts. Spurious
Interrupt!

"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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]