[En-Nut-Discussion] Interrupts on at91 plattform: Edge vs. level triggered

Thiago A. Corrêa thiago.correa at gmail.com
Wed Feb 4 06:08:43 CET 2009


Hi Ole,

   This might be completely unrelated, but while I'm trying to figure
out what to do and where with the AVR32, I'm looking at the arm code
and I just noticed something:

#else /* NUT_CRITICAL_NESTING_STACK */

extern unsigned int critical_nesting_level;

#define NutEnterCritical() \
if (critical_nesting_level++ == 0) { \
    int temp_; \
    asm volatile (             \
            "@ NutEnterCritical"    "\n\t" \
            "mrs     %0, cpsr"      "\n\t" \
            "orr     %0, %0, #0xC0" "\n\t" \
            "msr     cpsr, %0"      "\n\t" \
            : "=r" (temp_) : : "cc"); \
}

Shouldn't we disable interrupts first then change the variable? It
looks unsafe the way it is implemented

#define NutExitCritical() \
if (critical_nesting_level) { \
    int temp_; \
    asm volatile (             \
            "@ NutExitCritical"     "\n\t" \
            "mrs     %0, cpsr"      "\n\t" \
            "bic     %0, %0, #0xC0" "\n\t" \
            "msr     cpsr, %0"      "\n\t" \
            : "=r" (temp_) : : "cc"); \
    critical_nesting_level--; \
}

Same here, I think the variable update should be done before enabling
interrupts.

What do you think?

Kind Regards,
    Thiago A. Correa

On Tue, Feb 3, 2009 at 3:19 PM, Ole Reinhardt
<ole.reinhardt at embedded-it.de> wrote:
> Hey!
>
> I just noticed several times problems with drivers using edge triggered
> interrupts on the arm platform. At least you remember the UART bug,
> fixed at 2008-07-26 by Harald (see Changelog).
>
> I noticed similar problems with the GPIO level change interrupts as
> well. If I leave the interrupts in their default trigger mode (edge
> triggered) the interrupt handler will not be triggered again after some
> thousand interrupts where generated before. It seems that this might
> happen if the Interrupts are disabled by a critical section just in the
> moment when the interrupt occurs. It seems that the interrupt flag is
> set in the meantime and therefore will never change again until it is
> cleared. But it will only be cleared in the interrupt handler which was
> not called as there was no "change" detected when interrupts where
> enabled.
>
> So two questions:
>
> - Is there any reason to use edge triggered interrupts instead of level
>  triggered for the internal peripherals?
> - If yes: Is there any way to workaround this problem? For example by
>  checking if an interrupt should have been triggered when leaving the
>  critical section?
>
> We should carefully check all existing drivers if this problem might
> occur there too. Especialy this could solve the problems with the TWI
> driver too (not yet checked).
>
> Regards,
>
> Ole Reinhardt
>
> --
>  _____________________________________________________________
> |                                                             |
> | Embedded-IT          Hard- und Softwarelösungen             |
> |                                                             |
> | Ole Reinhardt        Tel. / Fax:        +49 (0)271  7420433 |
> | Luisenstraße 29      Mobil:             +49 (0)177  7420433 |
> | 57076 Siegen         eMail:    ole.reinhardt at embedded-it.de |
> | Germany              Web:         http://www.embedded-it.de |
> |                      UstID / VAT:       DE198944716         |
> |_____________________________________________________________|
>
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
>


More information about the En-Nut-Discussion mailing list