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
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
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.