Forum: Compiler & IDEs Atomic Blocks with AVR32


von Jan S. (Gast)


Lesenswert?

Hallo,

ich bin gerade am Lernen mit einem AVR32UC3A.
Nun würde ich an einer Stelle gerne einen Atomic Block einfügen.
In AVR32 Studio konnte ich allerdings die entsprechenden Macros 
(ATOMIC_BLOCK(FORCEON) ) nicht finden.
Ist es da ausreichend einfach Disable_global_interrupt() und 
Enable_global_interrupt() zu verwenden? Die Blöcke schalten doch auch 
nur kurz die Interrupts aus, wenn ich das Prinzip richtig verstanden 
habe.

Beste Grüße,

   Jan

von Andreas B. (andreasb)


Lesenswert?

Ja, es ist aber eine for-Schleife.

Damit vergisst du den "End-Block" sicher nicht.

1
#define ATOMIC_BLOCK(type) for ( type, __ToDo = __iCliRetVal(); \
2
                         __ToDo ; __ToDo = 0 )
3
4
5
static __inline__ uint8_t __iCliRetVal(void)
6
{
7
    cli();
8
    return 1;
9
}
10
11
#define ATOMIC_FORCEON uint8_t sreg_save \
12
  __attribute__((__cleanup__(__iSeiParam))) = 0
13
14
static __inline__ void __iSeiParam(const uint8_t *__s)
15
{
16
    sei();
17
    __asm__ volatile ("" ::: "memory");
18
    (void)__s;
19
}
(Auszug  aus util/atomic.h)

mfg Andreas

von Jan S. (Gast)


Lesenswert?

Hallo Andreas,

so eine ähnliche Dekleration hatte ich auch schonmal gefunden.
Die Macros scheinen aber aus Dateien für andere AVRs kopiert zu sein.
Kann ich diese einfach so auch für die AVR32 benutzen? Jedenfalls hab 
ich Probleme die include-Dateien für die verwendeten Befehle zu finden.

Hier hat jemand die Macros für AVR32 definiert:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=830416
1
static __inline__ void IntOnParam(const unsigned int *v) 
2
 { 
3
    Enable_global_interrupt(); 
4
    asm volatile(""); 
5
    (void)v; 
6
 } 
7
8
 static __inline unsigned int IntOffRetval(void) 
9
 { 
10
    Disable_global_interrupt(); 
11
    return 1; 
12
 } 
13
14
 #define  ATOMIC_BLOCK(type) for (type, t = IntOffRetval(); t; t = 0) 
15
16
 #define  FORCEON unsigned int sreg_save __attribute__((__cleanup__(IntOnParam))) = 0

Problem ist, dass die for-loop C99 als Compilerstandard braucht, um die 
Deklaration im Schleifenkopf zu verkraften.
Mit C99 produzieren allerdings viele Dateien des Frameworks Fehler.
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=686625

Hat jemand eine Idee, wie man das Macro auf C90 bekommt? Die 
typ-definition vor die for-Schleife packen, funktioniert ja nicht, wenn 
man mehr als einen Block in einer Funktion hat, wenn ich das richtig 
sehe.

Ansonsten werde ich wohl doch erstmal:
1
Disable_global_interrupt();
2
   doSomething;
3
Enable_global_interrupt();

verwenden und hoffen, dass ich da nichts vergesse.

Beste Grüße,

   Jan

von Andreas B. (andreasb)


Lesenswert?

Jan S. schrieb:
> Hallo Andreas,
>
> so eine ähnliche Dekleration hatte ich auch schonmal gefunden.
> Die Macros scheinen aber aus Dateien für andere AVRs kopiert zu sein.

Genau, Das ist auch nur das Prinzip, und nicht die Lösung...

> Hat jemand eine Idee, wie man das Macro auf C90 bekommt? Die
> typ-definition vor die for-Schleife packen, funktioniert ja nicht, wenn
> man mehr als einen Block in einer Funktion hat, wenn ich das richtig
> sehe.

ggf. noch micht #define und #ifndef, aber ist ein Gebastel, mach besser 
das wie du es hast. (funktioniert nämlich nur bedingt...)

Nur noch eine Anmerkung: Du aktivierst nach dem Block die Globalen 
Interrupts immer.

Das Makro aktiviert die globalen Interrupts nur dann wenn sie vorher 
aktiv waren.

Das ist kein Problem wenn du daran denkst was du gemacht hast;-)

mfg Andreas

von Jan S. (Gast)


Lesenswert?

Gut dann is ja alles klar. ;-)
So oft kommt das bei mir eh nicht vor, dass ich da beim momentanen 
Projekt den Überblick verliere.

Andreas B. schrieb:
> Nur noch eine Anmerkung: Du aktivierst nach dem Block die Globalen
> Interrupts immer.
> Das Makro aktiviert die globalen Interrupts nur dann wenn sie vorher
> aktiv waren.

Wobei ich dachte, das FORCEON so definiert ist, dass nach dem Block die 
Interrupts auch immer an sind. Und es dann eine noch einen zweiten Typ 
gibt (Namen hab ich wieder vergessen), der den Zustand vor dem Block 
wiederherstellt.

Beste Grüße,

   Jan

von Andreas B. (andreasb)


Lesenswert?

Jan S. schrieb:
> Andreas B. schrieb:
>> Nur noch eine Anmerkung: Du aktivierst nach dem Block die Globalen
>> Interrupts immer.
>> Das Makro aktiviert die globalen Interrupts nur dann wenn sie vorher
>> aktiv waren.
>
> Wobei ich dachte, das FORCEON so definiert ist, dass nach dem Block die
> Interrupts auch immer an sind. Und es dann eine noch einen zweiten Typ
> gibt (Namen hab ich wieder vergessen), der den Zustand vor dem Block
> wiederherstellt.

Jaja, ich hätte etwas überlegen sollen, warum heisst es wohl FORCE ON;-)


Du meinst den hier:
1
#define ATOMIC_RESTORESTATE uint8_t sreg_save \
2
  __attribute__((__cleanup__(__iRestore))) = SREG

Der Speichert auch das Register, der FORCEON hat ein "= 0" in der 
Zuweisung, siehe weiter oben...


mfg Andreas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.