Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

New thread "Spurious Interrupts" - was - Re: [lpc2000] Disabling/enabling interrupt causing a data abort

New thread "Spurious Interrupts" - was - Re: [lpc2000] Disabling/enabling interrupt causing a data abort

2004-04-20 by microbit

Glad to be of help, Curt.

I can't recall the exact circumstances of how this short few cclk cycles
in the VIC (between telling it to disable INT xyz and the INT actually being
masked off)
works, but there are a few seasoned ARM buffs here that enlightened me on
that.
(see copy of Bill's post at end)
The ultimate solution is to use a Global_IRQ_disable type func, then mask
off the INT
you want, and _then_  reenable Global_IRQ.
This avoids what I guess you could call "spurious INts".
I'm creating a new thread in case the gurus can fill us in on further nuts
and bolts.

I had weird things happening - with different optimisation levels, either a
direct write
to the TX/RX UART Int reg. would *seem* to make it behave, and then other
times
using a read-modify-write to mask would *seem* to make it behave.

I noticed that if you even just take the Default_IRQ, do ONLY the
prologue/epilogue,
and return to the caller - even with Branch-Link - the Interrupt is still
vectored
after leaving Default_IRQ (I knew I wasn't loosing chars in the circular
buffer for
UART0, as default IRQ wasn't doing anything).
But the advice of more experienced ARM users here was that this should *NOT*
be done,
the preferred method is the above ie. global disable IRQ, mask off INT,
reenable IRQ.

If you want to dig deeper, look for an earlier thread I called "UART TX
FIFOs and INT problem".
This was Bill Knight's advice at the conclusion (copy) :

>>>>>
Kris
It's the old spurious interrupt problem.
The fix is to disable global interrupts around the first read-modify-write
instruction.  Doing the direct write (U0IER = xxx) can still allow the
problem
to happen.  What happens is the interrupt occurs and is recognized while
the masking instruction is executing but before it has completed.  Then
when the instruction does complete, the interrupt can't find the vector
so uses the default.  So to fix:

Disable global interrupts
mask interrupt
Enable global interrupts

do your stuff
unmask interrupt

NOTE: I don't think this last modification of the mask register needs
protection.  Someone correct me if I am wrong.


Regards
-Bill Knight
R O SoftWare
>>>>>>>>>>>

Cheers,
Kris De Vos
Show quoted textHide quoted text
> Kris,
>
> I added an assembler harness to accept the default irq, loaded up
> VICDefVectAddr with its address, and let it fly.  The default handler is
> being called periodically (it just prints a diagnostic and returns) so
> it appears to be working- I can't give a definitive answer until it runs
> for a couple of hours, but so far so good.  Thanks so much for your
> insight.
>
> Curt

[LPC2000] New thread "Spurious Interrupts"

2004-04-20 by the ARM Patch

I'll hop in here for a second.  As an added note, I believe changing the
VIC as the original post stated, will just un-vector the interrupt.  I
would suggest the following sequence.
1) disable global IRQ
2) disable/enable external interrupt (you may need to do this by changing
   the pin to a GPIO input in the appropriate PINSEL register.  GURUs jump
   in here.)
3) enable global IRQ

Regards
-Bill Knight
R O SoftWare

Re: New thread "Spurious Interrupts"

2004-04-20 by embeddedjanitor

Spurious interrupts are a result of the asynchonous nature of 
interrupt handling. The asynchronous nature is caused by the delay 
between when the core detects an interrupt and when it processes the 
interrupt, and the VIC state changing during that period. ie 
something like:

1) VIC decides there is an interrupt and sends the NIRQ signal to the 
core.
2) Core latches the NIRQ state.
3) Processing continues for a few cycles due to pipelining.
4) Core loads IRQ address from VIC.

Now if the VIC state changes during step 3 (eg due to the VIC being 
modified so that the interrupt that triggered is no longer pending 
[eg. the interrupt got disabled]) then in step 4 the VIC says "What 
interrupt?". In this case, the VIC returns the default interrupt 
VicDefVectAddr (0xFFFFF034). If this is not set up properly then 
things go silly.

There are two things you can do here:
1. Set things up so that the spurious interrupts never happen. Just 
guarding changes to the VIC might not be enough since glitches on 
level sensitive interrupts can also cause spurious interrupts (well 
in some parts anyway).

2. Set up a VIC default handler and test it properly.

-- Charles

--- In lpc2000@yahoogroups.com, "the ARM Patch" <thearmpatch@c...> 
wrote:
> I'll hop in here for a second.  As an added note, I believe 
changing the
> VIC as the original post stated, will just un-vector the 
interrupt.  I
> would suggest the following sequence.
> 1) disable global IRQ
> 2) disable/enable external interrupt (you may need to do this by 
changing
>    the pin to a GPIO input in the appropriate PINSEL register.  
GURUs jump
Show quoted textHide quoted text
>    in here.)
> 3) enable global IRQ
> 
> Regards
> -Bill Knight
> R O SoftWare

Re: [lpc2000] Re: New thread "Spurious Interrupts"

2004-04-20 by David Willmore

> 1) VIC decides there is an interrupt and sends the NIRQ signal to the 
> core.
> 2) Core latches the NIRQ state.
> 3) Processing continues for a few cycles due to pipelining.
> 4) Core loads IRQ address from VIC.

So, you're saying the VIC is BAD--Broken As Designed.  There should
be a latch *in the CPU core* that holds the vector when the NIRQ
is asserted and an acknowledge to clear the VIC.

Yes, yes, I know, one can live with this, but it's more in the realm
of "documented bugs are features" rather than something one would
actually want to work this way.

I take it this came from the ARM2/3 days when there was one physical
IRQ to the CPU and a peripherial handled combining IRQs?

Cheers,
David

Re: [lpc2000] Re: New thread "Spurious Interrupts"

2004-04-20 by Lewin A.R.W. Edwards

> I take it this came from the ARM2/3 days when there was one physical
> IRQ to the CPU and a peripherial handled combining IRQs?

Huh? What do you mean "from the ARM2/3 days..."? There are still only
two interrupts on the ARM7 (ARM4 core) - FIQ and IRQ. Vectoring of IRQs
is handled by a peripheral.

-- 
-- Lewin A.R.W. Edwards (http://www.zws.com/)
Learn how to develop high-end embedded systems on a tight budget!
http://www.amazon.com/exec/obidos/ASIN/0750676094/zws-20

Re: [lpc2000] Re: New thread "Spurious Interrupts"

2004-04-20 by microbit

> > 1) VIC decides there is an interrupt and sends the NIRQ signal to the
> > core.
> > 2) Core latches the NIRQ state.
> > 3) Processing continues for a few cycles due to pipelining.
> > 4) Core loads IRQ address from VIC.
>
> So, you're saying the VIC is BAD--Broken As Designed. There should
> be a latch *in the CPU core* that holds the vector when the NIRQ
> is asserted and an acknowledge to clear the VIC.
>
> Yes, yes, I know, one can live with this, but it's more in the realm
> of "documented bugs are features" rather than something one would
> actually want to work this way.
I agree here David.
When I banged my head on a brick wall with this, determined to find what
was wrong, my final conclusion was that I considered it to be a flaw in the VIC
as far as I'm concerned. (as naively posted by me some time ago :-)
A "bug" of course would constitute a silicon problem where eg. another ARM part
doesn't do this.
I've only worked with LPC2000 so far, I don't know if macrocells from different
vendors behave the same, I presume someone would have said so by now if that
was the case, ....so I take credit for word of the more seasoned die-hard ARM-ers here :-)
I was still puzzled to find that in my case letting it run where the default_IRQ just returns
from the ISR, that I wasn't missing processing in my actual ISRs that were supposed to have been
vectored. This implies to me that a branched default IRQ that simply returns leaves the actual
vectored interrupt still pending ......
Confused ?
You won't be after this episode of SOAP... :-)
B rgds
Kris

Re: New thread "Spurious Interrupts"

2004-04-20 by embeddedjanitor

--- In lpc2000@yahoogroups.com, "Lewin A.R.W. Edwards" <larwe@l...> 
wrote:
> 
> > I take it this came from the ARM2/3 days when there was one 
physical
> > IRQ to the CPU and a peripherial handled combining IRQs?
> 
> Huh? What do you mean "from the ARM2/3 days..."? There are still 
only
> two interrupts on the ARM7 (ARM4 core) - FIQ and IRQ. Vectoring of 
IRQs
> is handled by a peripheral.

The vectoring is handled by the VIC which is a peripheral yes, but 
the nature of how the VIC works, together with the way the core 
works, opens up some holes where there spurious interrupts can show 
up.

Whether this is a bad design is open to interpretation, but it comes 
down to being one of those compromises we encounter. ie. I'm sure the 
ARM folk could have added interlocking etc to prevent spurious 
interrupts from happening, but that would force a tighter coupling 
between the VIC and the core. It would probably also have caused 
performance implications (eg. pipeline flushing everytime there is an 
interrupt).

-- Charles

Re: New thread "Spurious Interrupts"

2004-04-20 by embeddedjanitor

--- In lpc2000@yahoogroups.com, "microbit" <microbit@c...> wrote:
> > > 1) VIC decides there is an interrupt and sends the NIRQ signal 
to the 
> > > core.
> > > 2) Core latches the NIRQ state.
> > > 3) Processing continues for a few cycles due to pipelining.
> > > 4) Core loads IRQ address from VIC.
> > 
> > So, you're saying the VIC is BAD--Broken As Designed.  There 
should
> > be a latch *in the CPU core* that holds the vector when the NIRQ
> > is asserted and an acknowledge to clear the VIC.
> > 
> > Yes, yes, I know, one can live with this, but it's more in the 
realm
> > of "documented bugs are features" rather than something one would
> > actually want to work this way.
> 
> I agree here David.
> When I banged my head on a brick wall with this, determined to find 
what
> was wrong, my final conclusion was that I considered it to be a 
flaw in the VIC
> as far as I'm concerned. (as naively posted by me some time ago :-)
> 
> A "bug" of course would constitute a silicon problem where eg. 
another ARM part
> doesn't do this.
> I've only worked with LPC2000 so far, I don't know if macrocells 
from different
> vendors behave the same, I presume someone would have said so by 
now if that 
> was the case,  ....so I take credit for word of the more seasoned 
die-hard ARM-ers here :-)
> 
> I was still puzzled to find that in my case letting it run where 
the default_IRQ just returns
> from the ISR, that I wasn't missing processing in my actual ISRs 
that were supposed to have been
> vectored. This implies to me that a branched default IRQ that 
simply returns leaves the actual
> vectored interrupt still pending ......
> 
> Confused ?
> You won't be after this episode of SOAP... :-)

The spurious interrupt thing also happens on other ARM devices and is 
reasonably well known in ARM land.

What you have to do in the default interrupt handler depends on the 
particular VIC. For instance, the ATMEL AT91xxx VIC has a spurious 
interrupt handler slot, with the documentation insisting that you 
must acknowledge the spurious interrupt (like you do with other 
interrupts) to clear the spurious interrupt condition. It would seem 
from what you write here that this is not required for the LPC21xx.

Could it be that you're doing level sensitive interrupt handling and 
some "glitch" is propagated before the "real" interrupt? If so, then 
perhaps the "glitch" triggers a spurious interrupt and the "real" 
signal causes the intended activity.

-- CHarles

Re: [lpc2000] Re: New thread "Spurious Interrupts"

2004-04-21 by David Willmore

> > I take it this came from the ARM2/3 days when there was one physical
> > IRQ to the CPU and a peripherial handled combining IRQs?
> 
> Huh? What do you mean "from the ARM2/3 days..."? There are still only
> two interrupts on the ARM7 (ARM4 core) - FIQ and IRQ. Vectoring of IRQs
> is handled by a peripheral.

I misspoke.  I should have said "two physical IRQs".

Cheers,
David

Re: [lpc2000] Re: New thread "Spurious Interrupts"

2004-04-24 by microbit

Hi Charles,

> What you have to do in the default interrupt handler depends on the
> particular VIC. For instance, the ATMEL AT91xxx VIC has a spurious
> interrupt handler slot, with the documentation insisting that you
> must acknowledge the spurious interrupt (like you do with other
> interrupts) to clear the spurious interrupt condition. It would seem
> from what you write here that this is not required for the LPC21xx.
>
> Could it be that you're doing level sensitive interrupt handling and
> some "glitch" is propagated before the "real" interrupt? If so, then
> perhaps the "glitch" triggers a spurious interrupt and the "real"
> signal causes the intended activity.

In my tests there was only ONE interrupt enabled at that time - the UART0
TX/RX. (I dislike UARTs that don't have separate RX and TX vectors :-)
Loading new chars from the low level putch() style function, and then
enabling the RX/TX Interrupt on UART0 would cause default IRQ
exceptions on an asynchronous basis.
For example, running char output at a fixed "pattern" (RS232 flow wise)
would run fine.
Running my own SW (a Basic interpreter), would be OK too, but executing
very specific BASIC programs would cause Defaults.
Then, to make it more fun, the enabling/disabling of the INT mask by direct
write (ie. rewrite the register) vs. read-modify-write would affect this
behaviour
as well (more understandable from instruction level point of view).
The pipelining explanation and its interaction with the VIC seems very
plausible.
"Global" IRQ disable/enable "fixed" this.

The bizarre thing was that eg. merely lighting a LED when Default IRQ had
been
vectored BUT not doing anything else in the ISR clearly demonstrated that
despite
"spurious" defaults, the UART0 INT would still remain pending after leaving
the Default ISR,
as there were clearly _no_ chars missing in the UART0 TX output flow.

I ended up settling for the global IRQ protection, but wanted to know what
this really
was about. When I write code, I expect specific things - and if that doesn't
happen
I tend to want to know _why_ it doesn't work the way I perceived it should,
instead
of just changing methodology... I must be stubborn :-)

Cheers,
Kris

Re: New thread "Spurious Interrupts"

2004-04-26 by embeddedjanitor

Hi Kris

Your experiences here definitely agree with what I would expect.

When you modify the VIC mask to gate interrupts wou will get the 
sequence that leads to spurious interrupts.

Internal to the VIC, the interrupt is still "waiting", but is not 
enabled.  Therefore when you go reenable the mask for this interrupt 
it immediately executes. This explains why you don't lose any data.

The spurious interrupts should be benign, but chew some extra CPU. 
They should, IMHO, be used as an indicator that something is not 
right (ie. you should not really be having spurious interrupts in a 
finished product).

-- CHarles

--- In lpc2000@yahoogroups.com, "microbit" <microbit@c...> wrote:
> Hi Charles,
> 
> > What you have to do in the default interrupt handler depends on 
the
> > particular VIC. For instance, the ATMEL AT91xxx VIC has a spurious
> > interrupt handler slot, with the documentation insisting that you
> > must acknowledge the spurious interrupt (like you do with other
> > interrupts) to clear the spurious interrupt condition. It would 
seem
> > from what you write here that this is not required for the 
LPC21xx.
> >
> > Could it be that you're doing level sensitive interrupt handling 
and
> > some "glitch" is propagated before the "real" interrupt? If so, 
then
> > perhaps the "glitch" triggers a spurious interrupt and the "real"
> > signal causes the intended activity.
> 
> In my tests there was only ONE interrupt enabled at that time - the 
UART0
> TX/RX. (I dislike UARTs that don't have separate RX and TX 
vectors :-)
> Loading new chars from the low level putch() style function, and 
then
> enabling the RX/TX Interrupt on UART0 would cause default IRQ
> exceptions on an asynchronous basis.
> For example, running char output at a fixed "pattern" (RS232 flow 
wise)
> would run fine.
> Running my own SW (a Basic interpreter), would be OK too, but 
executing
> very specific BASIC programs would cause Defaults.
> Then, to make it more fun, the enabling/disabling of the INT mask 
by direct
> write (ie. rewrite the register) vs. read-modify-write would affect 
this
> behaviour
> as well (more understandable from instruction level point of view).
> The pipelining explanation and its interaction with the VIC seems 
very
> plausible.
> "Global" IRQ disable/enable "fixed" this.
> 
> The bizarre thing was that eg. merely lighting a LED when Default 
IRQ had
> been
> vectored BUT not doing anything else in the ISR clearly 
demonstrated that
> despite
> "spurious" defaults, the UART0 INT would still remain pending after 
leaving
> the Default ISR,
> as there were clearly _no_ chars missing in the UART0 TX output 
flow.
> 
> I ended up settling for the global IRQ protection, but wanted to 
know what
> this really
> was about. When I write code, I expect specific things - and if 
that doesn't
> happen
> I tend to want to know _why_ it doesn't work the way I perceived it 
should,
Show quoted textHide quoted text
> instead
> of just changing methodology... I must be stubborn :-)
> 
> Cheers,
> Kris

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.