Forum: Mikrocontroller und Digitale Elektronik STM32G474, bit banding


von Uli N. (uln)


Angehängte Dateien:

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                              /*//]*/

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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?

von Uli N. (uln)


Lesenswert?

Die bit banding Adresse von GPIOB/ODR12 errechnet sich zu:
0x42000000 + (0x0414 << 5) + (12 << 2) = 0x420082B0

von Bauform B. (bauformb)


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?

: Bearbeitet durch User
von Uli N. (uln)


Lesenswert?

Das Assembler Schnipsel realisiert das Macro bbENA_nCS_FRAM()
und genau dieses setzt bei mir GPIOB/ODR12 nicht auf 0.

von Uli N. (uln)


Lesenswert?

1
#define PERIPH_BB_BASE        (0x42000000UL) /*!< Peripheral base address in the bit-band region */
2
#define PERIPH_BASE           (0x40000000UL) /*!< Peripheral base address */

von Uli N. (uln)


Lesenswert?

(12 << 2) = (0x000C << 2) = 0x0030
(0x0414 << 5) = 0x8280
0x8280 + 0x0030 = 0x82B0

von Dieter S. (ds1)


Lesenswert?

Was genau schreibst Du zum Umschalten des Pins in die Adresse 
0x420082B0? Das sollte 1 bzw 0 zum Setzen/Löschen des entsprechenden 
Bits sein.

Das hier kennst Du vermutlich:

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

von Wastl (hartundweichware)


Lesenswert?

Lothar M. schrieb:
> "bit banging" = "auf das Bit draufschlagen"

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

von Andreas B. (abm)


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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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?

von (prx) A. K. (prx)


Lesenswert?

Lothar M. schrieb:
> Lieber einen anständigen R-M-W-Zugriff.

Eine Grundentscheidung der ARM Architektur war, genau solche Befehle 
nicht zu implementieren. Man kann allenfalls in Frage stellen, ob eine 
Load/Store Architektur die beste Wahl für einen Mikrocontroller ist, bei 
dem Bitbanging eine wesentliche Rolle spielen kann.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

(prx) A. K. schrieb:
> Eine Grundentscheidung der ARM Architektur war, genau solche Befehle
> nicht zu implementieren.
Geht ja nicht anders. Oder wie soll z.B. ein i++ anders gehen als mit 
einem RNW Zugriff?

(prx) A. K. schrieb:
> Bitbanging
Bitbanding... ;-)

von (prx) A. K. (prx)


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.

von (prx) A. K. (prx)


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.

: Bearbeitet durch User
von Irgend W. (Firma: egal) (irgendwer)


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
- 
https://www.st.com/content/ccc/resource/technical/document/programming_manual/6c/3a/cb/e7/e4/ea/44/9b/DM00046982.pdf/files/DM00046982.pdf/jcr:content/translations/en.DM00046982.pdf

von Bauform B. (bauformb)


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.

von Uli N. (uln)


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.

von Dieter S. (ds1)


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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Lothar M. schrieb:
> Ich fand das Gehurgel mit den Bitadressen aber schon beim 8051 und beim
> AVR unnötig.

Hat man bei ARM wohl auch erkannt: Cortex-M7 hat es nicht mehr.

https://community.arm.com/support-forums/f/architectures-and-processors-forum/10266/why-cortex-m7-doesn-t-support-bit-banding

von Peter D. (peda)


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.

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.