[ECOS] Re: DSR stops running after heavy interrupts. Spurious Interrupt!
Joe Porthouse
jporthouse@toptech.com
Mon Apr 10 16:41:00 GMT 2006
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. Was there a reason why interrupt_end() should not be
called on spurious interrupts?
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?
What modifications to eCos source or my project is in order for dealing with
spurious interrupts correctly?
#define CYGNUM_HAL_INTERRUPT_22 22
#define CYGNUM_HAL_INTERRUPT_21 21
#define CYGNUM_HAL_INTERRUPT_20 20
#define CYG_HAL_PRI_HIGH 0
static cyg_interrupt btuart_interrupt_new_object;
static cyg_handle_t btuart_interrupt_handle;
static cyg_vector_t btuart_interrupt_vector = CYGNUM_HAL_INTERRUPT_21;
static cyg_priority_t btuart_interrupt_priority = CYG_HAL_PRI_HIGH;
unsigned int isr_rx_count = 0;
cyg_uint32 btuart_interrupt_isr(
cyg_vector_t vector,
cyg_addrword_t data)
{
unsigned int iir, lsr, rbr;
iir = PXA255_BTIIR;
// check if RX FIFO interrupt
if((iir & PXA255_IIR_IID_INT_ID_MASK) ==
PXA255_IIR_IID_RX_FIFO_INT_PENDING)
{
lsr = PXA255_BTLSR;
while(lsr & PXA255_LSR_DR_DATA_READY)
{
rbr = PXA255_BTRBR;
isr_rx_count++;
lsr = PXA255_BTLSR;
}
}
cyg_interrupt_acknowledge(vector);
return(CYG_ISR_HANDLED);
}
void serial_port_start(void)
{
// GPIO and UART inits here...
cyg_interrupt_create(
btuart_interrupt_vector,
btuart_interrupt_priority,
0,
&btuart_interrupt_isr,
0,
&btuart_interrupt_handle,
&btuart_interrupt_new_object);
cyg_interrupt_attach(btuart_interrupt_handle);
cyg_interrupt_unmask(btuart_interrupt_vector);
// UART interupt enabled here...
}
Joe Porthouse
Toptech Systems, Inc.
-----Original Message-----
From: ecos-discuss-owner@ecos.sourceware.org
[mailto:ecos-discuss-owner@ecos.sourceware.org] On Behalf Of Nick Garnett
Sent: Monday, April 10, 2006 5:36 AM
To: Sergei Organov
Cc: ecos-discuss@sources.redhat.com
Subject: Re: [ECOS] Re: DSR stops running after heavy interrupts. Bug found?
Sergei Organov <osv@javad.com> writes:
> Andrew Lunn <andrew@lunn.ch> writes:
>
> [...]
>
> > However, from what you are saying it sounds like there needs to be
> > another comparison afterwards. Something like:
> >
> > and r0,r0,#2 // CYG_ISR_CALL_DSR
> > beq 17f
>
> No, bit checking of the ISR return value is performed inside the
> interrupt_end() routine:
>
> if( isr_ret & Cyg_Interrupt::CALL_DSR && intr != NULL )
intr->post_dsr()
Exactly. And there are other housekeeping things that go on in
interrupt_end() which cannot be skipped. The most important of these
is decrementing the scheduler lock.
I don't really see how the original poster's problem is fixed by
trying to skip interrupt_end(), I would only expect doing that to
aggravate the problem. The scheduler lock is acquired early in
interrupt processing -- before the ISR is called and we know whether
there is a DSR to call. interrupt_end() decrements the scheduler lock
and as a side-effect may cause any DSRs to be called.
As Andrew has suggested, I think Joe's best way of working out what is
happening is to switch on instrumentation and see if he can track down
the extra increments of the scheduler lock.
--
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
--
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