Eine Nacht drüber geschlafen, und eine Sache ist mir aufgefallen:
1 | /** Eine oder mehrere neue Warnungen hinzufuegen oder loeschen
|
2 | *
|
3 | * @param[in] wrn: Bitmaske Warnungen
|
4 | * @param[in] to: true/false (setzen/loeschen)
|
5 | *
|
6 | * Auf STM32 werden die Bits threadsicher ueber die Bitbanding-Region geschrieben.
|
7 | * Bitbanding: Abbildung des Speicherbereichs 0x20000000-0x200FFFFF auf den
|
8 | * Bereich 0x22000000-0x23FFFFFF. clz() ist auf den Cortex M3/M4 billig. */
|
9 | static_inline void warning_setTo(enum warning_e wrn, bool to)
|
10 | {
|
11 | #if defined( STM32F4XX )
|
12 | /* Bitbanding-Region SRAM1 sicherstellen */
|
13 | /* Die Assertion ist teuer und verhindert Optimierungen.
|
14 | Mit einem Schreiben ins struct anstelle der Adresse des structs kann auch ohne
|
15 | Assertion sichergestellt werden, dass keine Flash-Region versehentlich ueber
|
16 | Bitbandig anzusprechen versucht wird. */
|
17 | //assert( (uint32_t) &WarnState>=0x20000000 && (uint32_t) &WarnState<= 0x200FFFFF);
|
18 |
|
19 | while(wrn)
|
20 | {
|
21 | int32_t bitNo = BBitOfMask(wrn); /* Erstes Bit der Maske */
|
22 | BBSram1Bit(WarnState.this, bitNo) = to; /* Bit ueber Bitbanding-Region setzen */
|
23 | wrn &= ~(1UL<<bitNo); /* Behandeltes Bit loeschen */
|
24 | }
|
25 |
|
26 | #else
|
27 | /* Auf anderen Plattformen hoffen */
|
28 | if( v )
|
29 | WarnState.this |= wrn;
|
30 | else
|
31 | WarnState.this &= ~wrn;
|
32 | #endif
|
33 | }
|
Wenn ich statt in einen Zeiger auf die Variable auf die Variable
schreibe, warnt mich der Compiler auch ohne Assertion davon, eine
Variable außerhalb des Bitbanding-Bereichs zu beschreiben. Eigentlich
sind ja nur Flash-Variablen nicht bitbandbar, aber sie sind sowieso
konstant und das wird mit einem Compiler-Fehler quittiert.
PittyJ schrieb:
> Ansonsten verstehe ich das eigentliche Problem gar nicht. Was ist das
> Problem mit der Bitmaske?
Ich will threadsicher Flags setzen und löschen.
PittyJ schrieb:
> Einfach mal so eine Anmerkung. Falls der Code jemals irgendwann auch auf
> C++ kompiliert wird, sollte man auf einen Bezeichner 'this' verzichten.
Stimmt. Wenn ich auf C++ umstellen sollte, ist das noch eine der
kleinsten Umstellungen. Was ist eigentlich in C++ das übliche Idiom für
"delta = this - last" oder "delta = new - this" ?