Forum: Mikrocontroller und Digitale Elektronik uint32_t arm-none-eabi-gcc atomic?


von Entwickler (Gast)


Lesenswert?

Hallo,

ist Schreibzugriff aus IRQ und normalem Code aus auf uint32_t durch
__disable_irq und __enable_irq zu schützen oder nicht?

Grüsse
Entwickler

von M. Н. (Gast)


Lesenswert?

Das hängt weniger vom Compile als vom konkreten System ab. Ich nehme mal 
an du hast einen Cortex-M irgendwas mit 32 bit Kern. Hier ist der 
Zugriff auf uint32_t und kleiner atomar*.

* Solange das 32 bit Wort auch an einer 32 bit aligned Adresse liegt. 
Das sollte bei automatischer Platzierung durch den Linker gegeben sein. 
Wenn das 32 bit Wort nicht aligned ist, dann kann bspw. ein Cortex M0 
gar nicht darauf zugreifen -> HardFault und ein Cortex M4 bspw. wird den 
Zugriff in zwei Zugriffe spalten, die dann nicht atomar sind.

von Entwickler (Gast)


Lesenswert?

Ja, das System ist Cortex-M4 und die Variable wird vom Compiler
im RAM alloziert. Kein cast von (uint8_t*) nach (uint32_t*) oder 
ähnliches.

Danke

von Norbert (Gast)


Lesenswert?

Entwickler schrieb:
> ist Schreibzugriff aus IRQ und normalem Code aus auf uint32_t durch
> __disable_irq und __enable_irq zu schützen oder nicht?

Nicht wenn du zB. auch DMA benutzt.

von Bauform B. (bauformb)


Lesenswert?

Read-Modify-Write ist auch nicht atomar, z.B.
1
count++;
2
flags |= FOO;
selbst wenn es einen Maschinenbefehl INC gäbe, wäre der beim M4 nicht 
atomar.

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Entwickler schrieb:
> ist Schreibzugriff aus IRQ und normalem Code aus auf uint32_t durch
> __disable_irq und __enable_irq zu schützen oder nicht?

Kannst du vielleicht auch mal nicht mit der Keule programmieren?

Bei jeder Gelegenheit mit dis/enable der Interrupts herumzufuchteln 
scheint mir eine tiefsitzende Unsitte von Leuten zu sein, die vom AVR 
herkommen. Nein, die Interrupts sollte man in Ruhe lassen und sich 
Methoden angewöhnen, die ohne solche Keulen auskommen.

Insofern kann man deine Frage mit JA oder NEIN beantworten, je nachdem 
wie du dich beim Programmieren anstellen willst. Aber das ist deine 
Obliegenheit.

W.S.

von Rolf M. (rmagnus)


Lesenswert?

W.S. schrieb:
> Entwickler schrieb:
>> ist Schreibzugriff aus IRQ und normalem Code aus auf uint32_t durch
>> __disable_irq und __enable_irq zu schützen oder nicht?
>
> Kannst du vielleicht auch mal nicht mit der Keule programmieren?

Was ist dein Problem? Er fragt doch extra nach, ob er das braucht oder 
nicht.

von M. Н. (Gast)


Lesenswert?

Bauform B. schrieb:
> Read-Modify-Write ist auch nicht atomar, z.B.count++;
> flags |= FOO;
> selbst wenn es einen Maschinenbefehl INC gäbe, wäre der beim M4 nicht
> atomar.

In diesem Fall kann mittels der exklusiven load und store Befehle der 
RMW Vorgang "atomar gekapselt werden". Das erfordert aber etwas 
Assembler.

von Bauform B. (bauformb)


Lesenswert?

M. H. schrieb:
> Bauform B. schrieb:
>> Read-Modify-Write ist auch nicht atomar, z.B.count++;
>
> In diesem Fall kann mittels der exklusiven load und store Befehle der
> RMW Vorgang "atomar gekapselt werden". Das erfordert aber etwas
> Assembler.

Hat schon mal jemand gewagt, das zu verwenden? Wie war das, das R in 
RISC steht für Ridiculous, oder? Es heißt ja nicht, dass es weniger zu 
lernen gibt.

Beitrag #7317609 wurde vom Autor gelöscht.
von Malte _. (malte) Benutzerseite


Lesenswert?

Faktisch ist ein uint32_t, wenn er denn aligned, ist, auf einem 32bitter 
wie ein Cortex-M bis auf weiteres mit gcc atomar.

Das ist aber wie ich gelernt habe nicht garantiert. Und zumindest beim 
Clang hab ich da sehr interessante Optimierungen beobachtet (die 
ungewöhnlich, aber nicht dem Standard widersprechen).
In etwa ging der Code so:
1
typedef struct {
2
 uint32_t a;
3
 uint8_t b;
4
} myType_t;
5
6
void foo(myType_t * x, myType_t * y) {
7
  y->a = x->a;
8
  y->b = x->b;
9
}
Der Zugriff auf a erfolgte nicht atomar. Stattdessen hat der clang 
selbstständig die Erlaubnis für nicht alignte Zugriffe angenommen und
einen 4 Byte Zugriff gemacht der 3 Byte von a und dann das 1 Byte von b 
beinhaltet hat. Dann einen 1 Byte Zugriff um das fehlende Byte von a zu 
kopieren.

von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?

M. H. schrieb:
> ..."atomar gekapselt werden".
> Das erfordert aber etwas Assembler.

Diese Arbeit kann man heutzutage durchaus dem Compiler überlassen:
- https://en.cppreference.com/w/cpp/atomic/atomic

von Wilhelm M. (wimalopaan)


Lesenswert?

Das wird regelmäßig hier gefragt (oft auch in Zusammenhang mit 
volatile):

Beitrag "Re: c volatile -> wann bracht mans wirklich?"

von M. Н. (Gast)


Lesenswert?

Bauform B. schrieb:
> Hat schon mal jemand gewagt, das zu verwenden?

Was heißt "gewagt"? Die Funktionalität ist weder besonders schwierig zu 
verstehen noch außergewöhnlich.

Hier ist schon in der Frage ein funktionales Beispiel:
Beitrag "STM32: LDREX/STREX vs Interruptsperre"

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Bauform B. schrieb:
> Hat schon mal jemand gewagt, das zu verwenden

Das geht sogar ganz einfach, wenn du die Atomic-Library verwendest:

https://en.cppreference.com/w/c/language/atomic
https://en.cppreference.com/w/cpp/atomic/atomic

Wenn ich mich recht erinnere, muss man noch bei 
Kontextwechseln/Interrupt-Eintritt noch ein CLREX ausführen.

Wenn du ein RTOS verwendest, basieren die Synchronisations-Primitive 
wahrscheinlich auch auf Atomics oder direkt auf den jeweiligen 
Assembler-Befehlen.

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Rolf M. schrieb:
> Was ist dein Problem? Er fragt doch extra nach, ob er das braucht oder
> nicht.

ICH brauche sowas nicht. Und ich habe auch kein Problem damit. Aber ob 
der TO bei seiner Programmierweise sowas braucht, kann eigentlich nur er 
selber sagen. Allenfalls kann er seine Programmierweise ändern - sofern 
er das will. Das ist der entscheidende Punkt.

W.S.

von M. Н. (Gast)


Lesenswert?

Niklas G. schrieb:
> Kontextwechseln/Interrupt-Eintritt noch ein CLREX ausführen.

Bei exceptions / Interrupts übernimmt das der Cortex von sich.

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.