[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] avr-libc: interrupt.h, ISR and ISR_NOBLOCK

From: Georg-Johann Lay
Subject: Re: [avr-gcc-list] avr-libc: interrupt.h, ISR and ISR_NOBLOCK
Date: Mon, 30 Apr 2012 19:13:59 +0200
User-agent: Mozilla Thunderbird 1.0.7 (Windows/20050923)

Weddington, Eric schrieb:

Johann Lay

AVR-LIbC's ISR-macros lead to confusing results for code like, e.g.

#include <avr/io.h>
#include <avr/interrupt.h>

void *p;

    char c[10];
    p = c;

which resolves a.a. to

void __vector_21 (void)
__attribute__ ((signal,used,externally_visible)) __attribute__((interrupt));

Which states that IRQs are turned off (signal) and IRQs are turned on
(interrupt) at the same time.

I haven't looked at the avr-libc code in a long time; I didn't know
it actually generated that. :-/

I agree that it shouldn't do that, and it should generate clean code.

This leads to unexpected code generated by the compiler.

BTW, the code for ATmega is like

        push r1
        push r0
        in r0,__SREG__
        push r0
        clr __zero_reg__
        push r24
        push r25
        push r28
        push r29
        in r28,__SP_L__
        in r29,__SP_H__
        sbiw r28,10
        out __SP_H__,r29
        out __SP_L__,r28
/* prologue: Interrupt */
/* frame size = 10 */
/* stack size = 17 */
.L__stack_usage = 17
        movw r24,r28
        adiw r24,1
        sts p+1,r25
        sts p,r24
/* epilogue start */
        adiw r28,10
        in __tmp_reg__,__SREG__
        out __SP_H__,r29
        out __SREG__,__tmp_reg__
        out __SP_L__,r28
        pop r29
        pop r28
        pop r25
        pop r24
        pop r0
        out __SREG__,r0
        pop r0
        pop r1

The assignment at the end of prologue is not IRQ-safe because the
function is "signal".

"interrupt" just says that "interrupts will be enabled inside the
function" but IMO it's a reasonable assumption that the compiler
generates according code.

The second set of SP is IRQ-save because I changed the code to
be more conservative because there is no knowledge if the
used did SEI by hand.

This leads to 3 more instructions, but to definitely know a new
function attribute would be needed like "no_sei" or "no_irq"
where the user ensures that he never sets I-flag, at least not
an a way that affects writes to SP. E.g. code like yield() as in


would not require "no_sei" in a "signal" as it cannot affect SP atomicy.

"no_sei" would be incompatible with "OS_task" and "interrupt".

Or maybe it's better to name it "no_interrupt[s]" that is similar to
-mno-interrupts command option.

Thus, I'd like to introduce an error in avr-gcc saying

"function can only be one of 'interrupt', 'signal', 'OS_task', 'OS_main'
at the same time"

What should OS_task and OS_main be? OS_main as uninterruptable?
OS_task as interruptable?

It's basically as in
which I found as mentioned in
But as I read it now, there is a wrong "call-saved".

I have no problem with throwing an error in avr-gcc, as long as
we get avr-libc fixed at the same time.


I just don't see a trick how to add "signal" only if NO_INTERRUPT
is not specified.

The compiler could be changed to handle it, of course.
But I am no fan of trying to support mutually exclusive/contradicting


reply via email to

[Prev in Thread] Current Thread [Next in Thread]