Sign in

username:

password:



Not a member?

Search Comp.Arch.Embedded



Search tips

embedded by Keywords

68HC11 | 68HC12 | 8051 | 8052 | ARM | ARM7 | Asic | AT91 | AT91RM9200 | Atmel | AVR | AVRStudio | Bootloader | CFP | CompactFlash | Cygnal | Cypress | Dataflash | DSP | eCos | EEPROM | Embedded Linux | Emulator | Endian | Ethernet | Firewire | FPGA | Freescale | GCC | GNUARM | GSM | H8 | HDLC | I2C | Infineon | Interrupts | Java | JTAG | LCD | LED | LPC2000 | MCU | Microchip | MMC | MPLAB | MSP430 | PC104 | PCB | PCI | PCMCIA | PowerPC | Rabbit | RS232 | RS485 | RTOS | SBC | SDRAM | Sensor | SPI | STK500 | UART | UML | USART | USB | Verilog | VHDL | VxWorks | Xilinx

Ads

Discussion Groups

Discussion Groups | Comp.Arch.Embedded | One of the 200 interrupts does not get executed sometimes due to a single statement

There are 25 messages in this thread.

You are currently looking at messages 0 to 10.

One of the 200 interrupts does not get executed sometimes due to a single statement - karthikbg - 08:36 14-12-06

Hi,

1)  I have 200 interrupts and the corresponding Interrupt service
routines for those.

ISR ()
{
   If (INTERRUPT_FLAG == 1)
        DO_ISR_ACTIVITY
   INTERRUPT_FLAG = 0;
}

When i am doing the 'INTERRUPT_FLAG=0' in the above code, One of the
interrupt gets fired, but not handled as it is at the end of ISR. How
to avoid this.
But, the clearing of the 'INTERRUPT_FLAG = 0' is required.

So, one of the 200 interrupts does not get executed sometimes.
How to avoid the above problem ?

2)   Further, i do suspect that an interrupt can come in the middle of
'DO_ISR_ACTIVITY' routine and that can also cause a problem of that
interrupt being left un-attended.
If this is the case, how to check this as there are 200 interrupts ?

Tonnes of Thx in advans,
Karthik Balaguru




Re: One of the 200 interrupts does not get executed sometimes due to a single statement - Arlet - 08:51 14-12-06

karthikbg wrote:

> Hi,
>
> 1)  I have 200 interrupts and the corresponding Interrupt service
> routines for those.
>
> ISR ()
> {
>    If (INTERRUPT_FLAG == 1)
>         DO_ISR_ACTIVITY
>    INTERRUPT_FLAG = 0;
> }
>
> When i am doing the 'INTERRUPT_FLAG=0' in the above code, One of the
> interrupt gets fired, but not handled as it is at the end of ISR. How
> to avoid this.
> But, the clearing of the 'INTERRUPT_FLAG = 0' is required.
>
> So, one of the 200 interrupts does not get executed sometimes.
> How to avoid the above problem ?
>
> 2)   Further, i do suspect that an interrupt can come in the middle of
> 'DO_ISR_ACTIVITY' routine and that can also cause a problem of that
> interrupt being left un-attended.
> If this is the case, how to check this as there are 200 interrupts ?

How about something like this:

ISR()
{
   if( interrupt_flag )
   {
      interrupt_flag = 0;
      do_isr_activity();
   }
}

That way, when a new interrupt comes in while you're processing the old
one, the interrupt flag will be set again. This assumes
'do_isr_activity()' can handle the case where multiple interrupts have
been received.


Re: One of the 200 interrupts does not get executed sometimes due to a single statement - 11:11 14-12-06

Arlet wrote:
> karthikbg wrote:
>
> > Hi,
> >
> > 1)  I have 200 interrupts and the corresponding Interrupt service
> > routines for those.
> >
> > ISR ()
> > {
> >    If (INTERRUPT_FLAG == 1)
> >         DO_ISR_ACTIVITY
> >    INTERRUPT_FLAG = 0;
> > }
> >
> > When i am doing the 'INTERRUPT_FLAG=0' in the above code, One of the
> > interrupt gets fired, but not handled as it is at the end of ISR. How
> > to avoid this.
> > But, the clearing of the 'INTERRUPT_FLAG = 0' is required.
> >
> > So, one of the 200 interrupts does not get executed sometimes.
> > How to avoid the above problem ?
> >
> > 2)   Further, i do suspect that an interrupt can come in the middle of
> > 'DO_ISR_ACTIVITY' routine and that can also cause a problem of that
> > interrupt being left un-attended.
> > If this is the case, how to check this as there are 200 interrupts ?
>
> How about something like this:
>
> ISR()
> {
>    if( interrupt_flag )
>    {
>       interrupt_flag = 0;
>       do_isr_activity();
>    }
> }
>
> That way, when a new interrupt comes in while you're processing the old
> one, the interrupt flag will be set again. This assumes
> 'do_isr_activity()' can handle the case where multiple interrupts have
> been received.

200 interrupts is a HUGE # of interrupts!  Do you really need that
many?

I'd also make sure that interrupts are disabled at the start of the ISR
and restored at the end of the ISR.  "do_isr_activity()" should also be
as short and simple as possible.  Calling O/S routines from an ISR is
also not a good idea.
HTH
-Dave Pollum


Re: One of the 200 interrupts does not get executed sometimes due to a single statement - Rufus V. Smith - 11:26 14-12-06

"Arlet" <usenet+5...@ladybug.xs4all.nl> wrote in message 
news:1...@f1g2000cwa.googlegroups.com...
>
> karthikbg wrote:
>
>> Hi,
>>
>> 1)  I have 200 interrupts and the corresponding Interrupt service
>> routines for those.
>>
>> ISR ()
>> {
>>    If (INTERRUPT_FLAG == 1)
>>         DO_ISR_ACTIVITY
>>    INTERRUPT_FLAG = 0;
>> }
>>
>> When i am doing the 'INTERRUPT_FLAG=0' in the above code, One of the
>> interrupt gets fired, but not handled as it is at the end of ISR. How
>> to avoid this.
>> But, the clearing of the 'INTERRUPT_FLAG = 0' is required.
>>
>> So, one of the 200 interrupts does not get executed sometimes.
>> How to avoid the above problem ?
>>
>> 2)   Further, i do suspect that an interrupt can come in the middle of
>> 'DO_ISR_ACTIVITY' routine and that can also cause a problem of that
>> interrupt being left un-attended.
>> If this is the case, how to check this as there are 200 interrupts ?
>
> How about something like this:
>
> ISR()
> {
>   if( interrupt_flag )
>   {
>      interrupt_flag = 0;
>      do_isr_activity();
>   }
> }
>
> That way, when a new interrupt comes in while you're processing the old
> one, the interrupt flag will be set again. This assumes
> 'do_isr_activity()' can handle the case where multiple interrupts have
> been received.
>

This will handle receiving multiple interrupts
during interrupt processing.

ISR()
{
   static int unhandled = 0;

   if (unhandled)
   {
        unhandled++;  // buffering interrupt counts
        interrupt_flag = 0;
   }
   else
   {
        unhandled++;  // first interrupt
        interrupt_flag = 0;
        while (unhandled) // handle interrupt, and others that may come in
        {
           do_isr_activity();
           unhandled--;
        }
    }
}

Rufus



Re: One of the 200 interrupts does not get executed sometimes due to a single statement - FreeRTOS.org - 12:07 14-12-06

"Rufus V. Smith" <n...@nospam.com> wrote in message 
news:45817976$0$20219$8...@news.teranews.com...
>
> "Arlet" <usenet+5...@ladybug.xs4all.nl> wrote in message 
> news:1...@f1g2000cwa.googlegroups.com...
>>
>> karthikbg wrote:
>>
>>> Hi,
>>>
>>> 1)  I have 200 interrupts and the corresponding Interrupt service
>>> routines for those.
>>>
>>> ISR ()
>>> {
>>>    If (INTERRUPT_FLAG == 1)
>>>         DO_ISR_ACTIVITY
>>>    INTERRUPT_FLAG = 0;
>>> }
>>>
>>> When i am doing the 'INTERRUPT_FLAG=0' in the above code, One of the
>>> interrupt gets fired, but not handled as it is at the end of ISR. How
>>> to avoid this.
>>> But, the clearing of the 'INTERRUPT_FLAG = 0' is required.
>>>
>>> So, one of the 200 interrupts does not get executed sometimes.
>>> How to avoid the above problem ?
>>>
>>> 2)   Further, i do suspect that an interrupt can come in the middle of
>>> 'DO_ISR_ACTIVITY' routine and that can also cause a problem of that
>>> interrupt being left un-attended.
>>> If this is the case, how to check this as there are 200 interrupts ?
>>
>> How about something like this:
>>
>> ISR()
>> {
>>   if( interrupt_flag )
>>   {
>>      interrupt_flag = 0;
>>      do_isr_activity();
>>   }
>> }
>>
>> That way, when a new interrupt comes in while you're processing the old
>> one, the interrupt flag will be set again. This assumes
>> 'do_isr_activity()' can handle the case where multiple interrupts have
>> been received.
>>
>
> This will handle receiving multiple interrupts
> during interrupt processing.
>
> ISR()
> {
>   static int unhandled = 0;
>
>   if (unhandled)
>   {
>        unhandled++;  // buffering interrupt counts
>        interrupt_flag = 0;
>   }
>   else
>   {
>        unhandled++;  // first interrupt
>        interrupt_flag = 0;
>        while (unhandled) // handle interrupt, and others that may come in
>        {
>           do_isr_activity();
>           unhandled--;
>        }
>    }
> }
>
> Rufus
>


Reading and writing unhandled in a nested interrupt?  Is write access 
atomic?


Regards,
Richard.

+ http://www.FreeRTOS.org
+ http://www.SafeRTOS.com
for Cortex-M3, ARM7, ARM9, HCS12, H8S, MSP430
Microblaze, Coldfire, AVR, x86, 8051, PIC24 & dsPIC



Re: One of the 200 interrupts does not get executed sometimes due to a single statement - Arlet - 12:42 14-12-06

Rufus V. Smith wrote:

> "Arlet" <usenet+5...@ladybug.xs4all.nl> wrote in message
> news:1...@f1g2000cwa.googlegroups.com...
> >
> > karthikbg wrote:
> >
> >> Hi,
> >>
> >> 1)  I have 200 interrupts and the corresponding Interrupt service
> >> routines for those.
> >>
> >> ISR ()
> >> {
> >>    If (INTERRUPT_FLAG == 1)
> >>         DO_ISR_ACTIVITY
> >>    INTERRUPT_FLAG = 0;
> >> }
> >>
> >> When i am doing the 'INTERRUPT_FLAG=0' in the above code, One of the
> >> interrupt gets fired, but not handled as it is at the end of ISR. How
> >> to avoid this.
> >> But, the clearing of the 'INTERRUPT_FLAG = 0' is required.
> >>
> >> So, one of the 200 interrupts does not get executed sometimes.
> >> How to avoid the above problem ?
> >>
> >> 2)   Further, i do suspect that an interrupt can come in the middle of
> >> 'DO_ISR_ACTIVITY' routine and that can also cause a problem of that
> >> interrupt being left un-attended.
> >> If this is the case, how to check this as there are 200 interrupts ?
> >
> > How about something like this:
> >
> > ISR()
> > {
> >   if( interrupt_flag )
> >   {
> >      interrupt_flag = 0;
> >      do_isr_activity();
> >   }
> > }
> >
> > That way, when a new interrupt comes in while you're processing the old
> > one, the interrupt flag will be set again. This assumes
> > 'do_isr_activity()' can handle the case where multiple interrupts have
> > been received.
> >
>
> This will handle receiving multiple interrupts
> during interrupt processing.
>
> ISR()
> {
>    static int unhandled = 0;
>
>    if (unhandled)
>    {
>         unhandled++;  // buffering interrupt counts
>         interrupt_flag = 0;
>    }
>    else
>    {
>         unhandled++;  // first interrupt
>         interrupt_flag = 0;
>         while (unhandled) // handle interrupt, and others that may come in
>         {
>            do_isr_activity();
>            unhandled--;
>         }
>     }
> }
>
> Rufus

Usually, the ISR isn't reentrant, as it disables any further
interrupts, so this wouldn't do anything.

I was referring to a situation where there are many h/w interrupts, but
where it was okay to occasionally miss one, for instance if the
peripheral has a FIFO.

If every interrupt is important, the OP needs to make sure the ISR is
finished before the next interrupt is received.


Re: One of the 200 interrupts does not get executed sometimes due to a single statement - tbroberg_nospam@hifn.com - 12:57 14-12-06

Arlet wrote:
> ISR()
> {
>    if( interrupt_flag )
>    {
>       interrupt_flag = 0;
>       do_isr_activity();
>    }
> }

I have run into cases where I had problems with this code when the
interrupt flag is a register on a PCI target.

The code was just like this, only it looped to handle as many interrupt
conditions as possible - replace "if" with "while" above.

PCI would post the write, which would get backed off by target stop so
long that the ISR had returned before the write finally posted. This
sometimes cleared not only the current interrupt condition(s), but the
next one as well resulting in a lost interrupt.

I had accessed two different busses and assumed that I had some notion
of the order in which the accesses would happen. Wrong.

Now whenever I catch myself thinking "before" or "after" I stop and
check for synchronization issues.

    - Tim.


Re: One of the 200 interrupts does not get executed sometimes due to a single statement - David T. Ashley - 13:30 14-12-06

"karthikbg" <k...@lntinfotech.com> wrote in message 
news:1...@j72g2000cwa.googlegroups.com...
> Hi,
>
> 1)  I have 200 interrupts and the corresponding Interrupt service
> routines for those.
>
> ISR ()
> {
>   If (INTERRUPT_FLAG == 1)
>        DO_ISR_ACTIVITY
>   INTERRUPT_FLAG = 0;
> }
>
> When i am doing the 'INTERRUPT_FLAG=0' in the above code, One of the
> interrupt gets fired, but not handled as it is at the end of ISR. How
> to avoid this.
> But, the clearing of the 'INTERRUPT_FLAG = 0' is required.
>
> So, one of the 200 interrupts does not get executed sometimes.
> How to avoid the above problem ?
>
> 2)   Further, i do suspect that an interrupt can come in the middle of
> 'DO_ISR_ACTIVITY' routine and that can also cause a problem of that
> interrupt being left un-attended.
> If this is the case, how to check this as there are 200 interrupts ?

First, check the data book carefully for the required style of interaction 
with the control register.  Many micros have control registers interfaced in 
unusual ways where a RMW instruction can cause a pending interrupt to be 
lost (in the digital logic, if the interrupt becomes asserted appromixately 
during the M part of the instruction).  Lost interrupts can easily be due to 
mishandling the type of statement you've called:

>   INTERRUPT_FLAG = 0;

Second, as another poster mentioned, you want to rearrange things to:

ISR ()
{
 If (INTERRUPT_FLAG == 1)
   {
    INTERRUPT_FLAG = 0;
    DO_ISR_ACTIVITY
   }
}

This covers the case where another interrupt occurs during the ISR.

Third, you want to [in general] think about the paradigm you're using for 
dealing with the interrupts when they are occurring rapidly.  One way to 
handle it is to use the two suggestions above and let the ISR be entered 
again and again if an interrupt is pending at the time you exit the ISR. 
This is fine if you can spare the context switch overhead.  However, it may 
be more efficient to do two operations per ISR, which handles the interrupt 
latency "double-bounce" case (there is seldom a performance improvement from 
handling more than two operations per ISR, and I won't get into the reasons 
for that here).  Then the pseudo-code would be:

#define MAX (2)

ISR ()
   {
   int iteration = 0;

   while ((INTERRUPT_FLAG == 1) && (iteration < MAX))
      {
       INTERRUPT_FLAG = 0;
       DO_ISR_ACTIVITY();
       iteration++;
       }
   }

Fourth, you need to be aware that interrupt-related issues are, as a rule of 
thumb, responsible for about 80% of the intermittent bugs in small systems. 
You need to pay careful attention to this.

I do admire your style in posting just an abstraction of your problem (your 
post was brief and very readable).  However, in this case, posting the 
entire ISR as well as identifying the micro would have been helpful.

Dave. 




Re: One of the 200 interrupts does not get executed sometimes due to a single statement - karthikbg - 22:01 14-12-06

v...@verizon.net wrote:
> Arlet wrote:
> > karthikbg wrote:
> >
> > > Hi,
> > >
> > > 1)  I have 200 interrupts and the corresponding Interrupt service
> > > routines for those.
> > >
> > > ISR ()
> > > {
> > >    If (INTERRUPT_FLAG == 1)
> > >         DO_ISR_ACTIVITY
> > >    INTERRUPT_FLAG = 0;
> > > }
> > >
> > > When i am doing the 'INTERRUPT_FLAG=0' in the above code, One of the
> > > interrupt gets fired, but not handled as it is at the end of ISR. How
> > > to avoid this.
> > > But, the clearing of the 'INTERRUPT_FLAG = 0' is required.
> > >
> > > So, one of the 200 interrupts does not get executed sometimes.
> > > How to avoid the above problem ?
> > >
> > > 2)   Further, i do suspect that an interrupt can come in the middle of
> > > 'DO_ISR_ACTIVITY' routine and that can also cause a problem of that
> > > interrupt being left un-attended.
> > > If this is the case, how to check this as there are 200 interrupts ?
> >
> > How about something like this:
> >
> > ISR()
> > {
> >    if( interrupt_flag )
> >    {
> >       interrupt_flag = 0;
> >       do_isr_activity();
> >    }
> > }
> >
> > That way, when a new interrupt comes in while you're processing the old
> > one, the interrupt flag will be set again. This assumes
> > 'do_isr_activity()' can handle the case where multiple interrupts have
> > been received.
>
> 200 interrupts is a HUGE # of interrupts!  Do you really need that
> many?
>
> I'd also make sure that interrupts are disabled at the start of the ISR
> and restored at the end of the ISR.  "do_isr_activity()" should also be
> as short and simple as possible.  Calling O/S routines from an ISR is
> also not a good idea.
> HTH
> -Dave Pollum

I use nested interrupts, so it is not possible to disable the
interrupts at the start of the ISR
and restoring at the end of the ISR.
Even though, we make the 'do_isr_activity()' short and simple, how to
protect it when an interrupt arrives in that short span of time of
execution of 'do_isr_activity()'.

Regards,
Karthik Balaguru


Re: One of the 200 interrupts does not get executed sometimes due to a single statement - karthikbg - 22:37 14-12-06

Arlet wrote:
> Rufus V. Smith wrote:
>
> > "Arlet" <usenet+5...@ladybug.xs4all.nl> wrote in message
> > news:1...@f1g2000cwa.googlegroups.com...
> > >
> > > karthikbg wrote:
> > >
> > >> Hi,
> > >>
> > >> 1)  I have 200 interrupts and the corresponding Interrupt service
> > >> routines for those.
> > >>
> > >> ISR ()
> > >> {
> > >>    If (INTERRUPT_FLAG == 1)
> > >>         DO_ISR_ACTIVITY
> > >>    INTERRUPT_FLAG = 0;
> > >> }
> > >>
> > >> When i am doing the 'INTERRUPT_FLAG=0' in the above code, One of the
> > >> interrupt gets fired, but not handled as it is at the end of ISR. How
> > >> to avoid this.
> > >> But, the clearing of the 'INTERRUPT_FLAG = 0' is required.
> > >>
> > >> So, one of the 200 interrupts does not get executed sometimes.
> > >> How to avoid the above problem ?
> > >>
> > >> 2)   Further, i do suspect that an interrupt can come in the middle of
> > >> 'DO_ISR_ACTIVITY' routine and that can also cause a problem of that
> > >> interrupt being left un-attended.
> > >> If this is the case, how to check this as there are 200 interrupts ?
> > >
> > > How about something like this:
> > >
> > > ISR()
> > > {
> > >   if( interrupt_flag )
> > >   {
> > >      interrupt_flag = 0;
> > >      do_isr_activity();
> > >   }
> > > }
> > >
> > > That way, when a new interrupt comes in while you're processing the old
> > > one, the interrupt flag will be set again. This assumes
> > > 'do_isr_activity()' can handle the case where multiple interrupts have
> > > been received.
> > >
> >
> > This will handle receiving multiple interrupts
> > during interrupt processing.
> >
> > ISR()
> > {
> >    static int unhandled = 0;
> >
> >    if (unhandled)
> >    {
> >         unhandled++;  // buffering interrupt counts
> >         interrupt_flag = 0;
> >    }
> >    else
> >    {
> >         unhandled++;  // first interrupt
> >         interrupt_flag = 0;
> >         while (unhandled) // handle interrupt, and others that may come in
> >         {
> >            do_isr_activity();
> >            unhandled--;
> >         }
> >     }
> > }
> >
> > Rufus
>
> Usually, the ISR isn't reentrant, as it disables any further
> interrupts, so this wouldn't do anything.
>
> I was referring to a situation where there are many h/w interrupts, but
> where it was okay to occasionally miss one, for instance if the
> peripheral has a FIFO.
>
> If every interrupt is important, the OP needs to make sure the ISR is
> finished before the next interrupt is received.



Thx for all your replies which have given some enough ideas.
I do agree on this method/idea of coding change for nested hardware
interrupts .

ISR()
 {
   if( interrupt_flag )
   {
      interrupt_flag = 0;
      do_isr_activity();
   }
}

How do you say that there is a possibility of missing an interrupt
ocassionaly.
I do not find flaw in the above idea ? Do i miss anything ?

I would like to clarify that i am talking about nested interrupts .

But, Is the above method very suitable for handling some 121 software
interrupts ?
(Nested interrupts)

Regards,
Karthik Balaguru


| 1 | 2 | 3 | next