STM32G474, bit banding

OP #7445394
Lesenswert?

Ich kann durch Tooglen von Bit GPIOB/ODR12 den Ausgang Port B12 hin- und herschalten. In der gleichenSituation funktioniert das aber unter Nutzung des bit banding aber nicht, obwohl die ins Register R3 geladene Adresse (0x420082B0) meinen Berechnungen nach korrekt ist. Was mache ich falsch bzw. was habe ich vergessen?

1
#define bbIOBIT(REG, BIT)                                                  /*//[
2
// brief                                                                     //[
3
// The macro bbIOBIT(...) realizes access to a single bit in IO space.    
4
// brief                                                                     //]                        
5

6
*/  (*(__typeof__(REG)*) ((PERIPH_BB_BASE + (((unsigned)&(REG) - PERIPH_BASE) << 5) + ((BIT) << 2))))
7
                                                                           /*//]*/
8
                                                                      
9
                                                                       
10
#define bbENA_nCS_FRAM()                                                   /*//[
11
// brief                                                                     //[
12
// The macro bbENA_nCS_FRAM() enables the FRAM.
13
// brief                                                                     //]
14
                                                                                
15
*/ bbIOBIT(GPIOB->ODR, GPIO_ODR_OD12_Pos) = 0                              /*//]*/
16

17
#define bbDIS_nCS_FRAM()                                                   /*//[
18
// brief                                                                     //[
19
// The macro bbCLR_nCS_FRAM() disables the FRAM.
20
// brief                                                                     //]
21

22
*/ bbIOBIT(GPIOB->ODR, GPIO_ODR_OD12_Pos) = 1                              /*//]*/
Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #7445405
Lesenswert?

Uli N. schrieb:

bit banding

"bit banging" = "auf das Bit draufschlagen"

Tooglen

"to toggle" = "umschalten"

Was mache ich falsch bzw. was habe ich vergessen?

Welcher Code funktioniert? Zu welchem Code gehört der Assembler-Schnipsel? Was sehen wir in deinen Screenshots? Und was sollte stattdessen zu sehen sein? Welche Werte haben diese vielen Konstanten?

obwohl die ins Register R3 geladene Adresse (0x420082B0) meinen Berechnungen nach korrekt ist.

Hat laut Screenshot das ODR nicht die Adresse x84000414?

#7445415
Lesenswert?

Uli N. schrieb:

obwohl die ins Register R3 geladene Adresse (0x420082B0) meinen Berechnungen nach korrekt ist.

Vermutlich gibt es im Macro bbIOBIT einen Überlauf bei ((BIT) << 2); Weil, 12 << 2 ist doch mehr als 32? Damit liefert das Macro nur noch bit_band_base + GPIOB.ODR.Bit0.

Wieso gibt der Compiler hier keine Warnung? Weil die << im Macro versteckt sind oder wie?

#7445587
Lesenswert?

PM0214: 0x40000000-0x400FFFFF Peripheral bit-band region RM0440: 0x48000000-0x48001BFF GPIOA-GPIOG

Also nix mit Bitbanding bei den GPIOs ...

Zumals das zumindest fürs ODR absolut überflüssig/unsinnig ist, wozu gibt's schließlich BSRR? Da kann man gleich mehrere Bits gleichzeitig(!) setzen und andere gleichzeitig(!) löschen. Oberdrein geht das viel schneller, denn beim Bitbanding wird erst das Word gelesen, modifiziert und dann zurückgeschreiben (also zwei Bus-Zugriffe), während beim BSRR alles mit einem(!) Schreibzugriff erledigt ist.

Moderator (Firma: Titel) Persönliche Seite #7445619
Lesenswert?

Wastl schrieb:

Irgendwie werde ich das Gefühl nicht los dass Lothar bisher noch nichts von "Bit Banding" gehört hat.

Tatsächlich. Man lernt nie aus.

Ich fand das Gehurgel mit den Bitadressen aber schon beim 8051 und beim AVR unnötig. Lieber einen anständigen R-M-W-Zugriff. Denn was bringt es mir, wenn ich zwar einzelne Bits atomar manipulieren kann, mich ein simpler Zähler oder sonst eine Wertänderung aber wieder an das Semaphorenproblem bringt?

#7445633
Lesenswert?

Lothar M. schrieb:

Denn was bringt es mir, wenn ich zwar einzelne Bits atomar manipulieren kann, mich ein simpler Zähler oder sonst eine Wertänderung aber wieder an das Semaphorenproblem bringt?

Das Semphorenproblem lässt sich auf diese Weise für Nebenläufigkeit durch Interrupts lösen. Bezogen auf Buszyklen hingegen wird stärkerer Tobak fällig, was bei mehreren parallelen Cores von Bedeutung ist und auch intelligente Peripherie einschliesst. R-W-M-Befehle mit ununterbrechbarem Buszyklus waren um 1980 herum unproblematisch, erwiesen sich im Zusammenhang mit Caches aber als extrem ineffiziente Höllenmaschine.

Die bei Load/Store-Architekturen an dessen Stelle verwendete load-and-reserve / store-conditional Technik (verschiedene andere Namen) ist vom Ablauf her sehr viel effizienter.

#7445636
Lesenswert?

Lothar M. schrieb:

Geht ja nicht anders. Oder wie soll z.B. ein i++ anders gehen als mit einem RNW Zugriff?

temp1 = mem temp2 = temp1 + 1 mem = temp2

Das sind im Ablauf 3 getrennte Schritte. Eine Architekturentscheidung ist, ob man das in einem Befehl implementiert, oder trennt.

Wie das auf dem Bus aussieht, ist dann wieder eine andere Frage. Inwieweit es bei Sema-Operationen ein einziger Buszyklus ist (68000), oder getrennte Buszyklen mit Lock-Signal (8086).

Bitbanding... ;-)

Nein, das meinte ich gerade nicht. Bitbanging als Begriff für im Kontext von µC gelegentliche auftretende Ablaufsteuerung von Einzelbits.

Bitbanding ist lediglich eine bei manchen ARMs implementierte Technik, um Einzelbitmanipulation zu erleichtern.

(Firma: egal) #7445708
Lesenswert?

Lothar M. schrieb:

Oder wie soll z.B. ein i++ anders gehen

Wo macht es dann Sinn eine 32Bit-Wert 1:1 auf einen I/O-Port zu geben und den dann Binär zu inkrementieren? Nachbildung einen "alten" Adressbusses um eine EPROM abzufragen?

Blos weil es hier noch eine Alternative zu RMW-Zugriffen gibt, heißt das ja noch lange nicht das dies eine Lösung für alle Arten von Anwendungen ist. Wenn man aber irgendwo einzelnen I/O hat die man ansteuern will ohne sich um die anderen auf demselben Port zu kümmern ist ganze recht praktisch. Gerade die Überlegungen ob einem der RMW durch irgendwas unterbrochen werden könnte, kann damit ggf. entfallen.

Steht ja jedem frei selbst zu entscheiden, welche der beiden Varianten des Zugriffes er für was verwendet. Wenn es denn ein Bereich ist wo überhaupt beide Optionen vorhanden sind, das ist schon etwas eingeschränkt:

Seite 32: 2.2.5 Bit-banding

#7445812
Lesenswert?

Irgend W. schrieb:

Lothar M. schrieb:

Oder wie soll z.B. ein i++ anders gehen

Wo macht es dann Sinn eine 32Bit-Wert 1:1 auf einen I/O-Port zu geben und den dann Binär zu inkrementieren?

Bei i++ geht es doch nicht um I/O-Ports. Für die gibt es ja Bit Banding und, noch viel besser, den BSRR Mechanismus. Aber das gewöhnliche i++ im RAM ist beim Cortex-M eben ziemlich umständlich, mangels echtem RMW-Befehl.

OP #7446981
Lesenswert?

Andreas B. schrieb:

PM0214: 0x40000000-0x400FFFFF Peripheral bit-band region RM0440: 0x48000000-0x48001BFF GPIOA-GPIOG

Also nix mit Bitbanding bei den GPIOs ...

Zumals das zumindest fürs ODR absolut überflüssig/unsinnig ist, wozu gibt's schließlich BSRR? Da kann man gleich mehrere Bits gleichzeitig(!) setzen und andere gleichzeitig(!) löschen. Oberdrein geht das viel schneller, denn beim Bitbanding wird erst das Word gelesen, modifiziert und dann zurückgeschreiben (also zwei Bus-Zugriffe), während beim BSRR alles mit einem(!) Schreibzugriff erledigt ist.

Im Zuge der Fehlersuche war ich schon auf die BSRR- und BRR-Register gestossen und hab' noch am Freitag damit begonnen, meinen Source-Code entsprechend umzuschreiben - dennoch wollte ich geklärt haben, weshalb die bis dato realisieren Zugriffe nicht funktionieren, nachdem lt. RM0440 2.3 "Bit banding" "both the peripheral registers and the SRAM" in die bit-banding region gemapped sind!

Thx für den Hinweis, dass das offenbar nicht auf alle "peripheral registers" zutrifft.

#7447012
Lesenswert?

Uli N. schrieb:

dennoch wollte ich geklärt haben, weshalb die bis dato realisieren Zugriffe nicht funktionieren, nachdem lt. RM0440 2.3 "Bit banding" "both the peripheral registers and the SRAM" in die bit-banding region gemapped sind!

Aus dem bereits weiter oben erwähnten Link:

https://www.mikrocontroller.net/articles/ARM_Bitbanding

"ARM Controller mit den Cores Cortex-M3 und -M4 sowie auch manche Cortex M0+ besitzen jedoch die Fähigkeit, einzelne Bits im RAM und im Peripheriebereich direkt adressieren zu können. Dazu existiert für den Peripheriebereich 0x40000000-0x400FFFFF ein weiterer Adressbereich 0x42000000-0x43FFFFFF und für den RAM-Bereich 0x20000000-0x200FFFFF der Bereich 0x22000000-0x23FFFFFF. Das sogenannte Bitbanding."

ODR liegt aber im Bereich ab 0x48000000.

#7447033
Lesenswert?

Lothar M. schrieb:

Ich fand das Gehurgel mit den Bitadressen aber schon beim 8051 und beim AVR unnötig. Lieber einen anständigen R-M-W-Zugriff. Denn was bringt es mir, wenn ich zwar einzelne Bits atomar manipulieren kann, mich ein simpler Zähler oder sonst eine Wertänderung aber wieder an das Semaphorenproblem bringt?

Da mußt Du den 8051 aber ausklammern. Der 8051 kann selbstverständlich auch ganze Ports atomar manipulieren (ANL, ORL, XRL, INC, DEC). Der AVR kann dagegen nur einzelne Bits atomar setzen oder löschen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren