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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Nick Garnett Sent: Monday, April 10, 2006 1:20 PM To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: Re: [ECOS] Re: DSR stops running after heavy interrupts. Spurious Interrupt! "Joe Porthouse" <[EMAIL PROTECTED]> 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