Hallo,
z.B. bei Cortex3 gibt es den Bit Banding Zugriff. Wenn man Programme
fuer den Zugriff auf Peripherie schreibt, kommen haeufig Sequenzen wie
Setze Bit 1 in Register 1 der Peripherieregisterstruktur,
Loesche Bit 2 in Register 2,
Setze Bit 3 in Register 3.
Hat man die Basisadresse der BitBand Region der Registerstruktur (BBR)
ausgerechnet, ware dann eine Pseudeassemblersequenz
MOV RY, 1
MOVE RZ, 1
MOV RX, LowWord(BBR)
MOVT RX, HighWord(BBR)
STR RY, [RX, (1<<5 + 1<<2)]
STR RZ [RX, (2<<5 + 2<<2)]
STR RY, [RX, (3<<5 + 3<<2)]
Bisher habe ich gcc aber nur bei Zugriffen wie RCC->CFG dazu gebracht,
Zugriffe mit "immediate offset" zu generieren. Egal, wie ich den Zugriff
formuliere, der Zugriff erfolgt ohne Offset uns sieht wie folgt aus
MOV RY, 1
MOVE RZ, 1
MOV RX, LowWord(BBR + 1<<5 + 1<<2]
MOVT RX, HighWord(BBR + 1<<5 + 1<<2]
STR RY, [RX, 0]
MOV RX, LowWord(BBR + 2<<5 + 2<<2]
MOVT RX, HighWord(BBR + 2<<5 + 2<<2]
STR RY, [RX, 0]
MOV RX, LowWord(BBR + 3<<5 + 3<<2]
MOVT RX, HighWord(BBR + 3<<5 + 3<<2]
STR RY, [RX, 0]
GCC ist gcc version 4.6.0 (GCC).
Ist das ein Manko von GCC oder hat jemand andere Hinweise
Blöde Frage, aber welche Optimierungsstufe (-O) verwendest Du? Bei mir
(CS 4.5.2) sieht "-Os" ganz anders aus als "-O2".
Außerdem müsste man auch Deinen C Code sehen.
A. K. schrieb:> Ich mache das so:
Ich glaube, das wäre durchaus mal einen Wiki-Artikel hier im
mikrocontroller.net-Wiki wert. ARM ist dort nach wie vor eher
unterbelichtet, finde ich.
Würdest du das selbst machen wollen?
@A. K.
Typeof() und __builtin_clz sind kein Ansi-Standard. Und
BBasedBit(p,reg1,4) = 1;
ist auch nicht mehr besonders gut lesbar. Und fuer z.B. TIM_TypeDef wird
die struct S{} definition auch recht lang.
Ich verwende bisher
#define CM3BBREG(base, regstruct, reg, bit) *(volatile uint32_t *)
&(((uint8_t *) ((base & 0xF0000000) + 0x02000000 + ((base &
0xFFFFF)<<5))) [(offsetof(regstruct, reg) <<5) + (bit <<2)] )
Das kommt ohne die nicht Ansi Konstrukte aus, gibt allerdings Zugriffe
ohne "immediate offset"
@Jim
Ich hatte es mit -O0 und -O2 probiert. -Os erkennt zumindestens
aufeinanderfolgende Zugriffe auf Bits eines Registers, aber auch nicht
immer
Uwe Bonnes schrieb:> Typeof() und __builtin_clz sind kein Ansi-Standard. Und
__builtin_clz lässt sich durch
((x) & 0x80000000 ? 31 :
(x) & 0x40000000 ? 30 :
...
ersetzen. Steht bei mit als Alternative auch drin, ich hatte es hier
aber der Übersichtlichkeit halber weggelassen.
Ohne eine solche Umsetzung von Masken in Bits sind diese Definitionen
ziemlich sinnlos, jedenfalls beim STM32, da die Bits in den
Include-Files leider ziemlich konsequent als Maske statt als Bitnummer
angegeben sind. Und solche Bits als Zahl statt als Bitname in den
Quelltext zu schreiben widerstrebt mir.
> BBasedBit(p,reg1,4) = 1;> ist auch nicht mehr besonders gut lesbar.> Ich verwende bisher> #define CM3BBREG(base, regstruct, reg, bit)
Inwiefern deine Variante lesbarer ist erschliesst sich mit nicht.
Wobei bei deiner Variante problematisch sein könnte, dass du stets auf
32-Bit Worte zugreifst. Ich hatte meine Variante mit voller Absicht so
konstruiert, dass der Datentyp erhalten bleibt, d.h. auf ein als 16-Bit
Typ deklariertes Register wird auch mit einem 16-Bit Lade/Speicherbefehl
zugegriffen. Das könnte bei irgendwelchen Peripheriemodulen von
Bedeutung sein. Nur kommt man dann nicht ohne typeof aus.
> Und fuer z.B. TIM_TypeDef wird> die struct S{} definition auch recht lang.
Das war nur ein ad hoc hingeschriebenes Beispiel für eine bereits
vorhandene Struct, wie sie üblicherweise von den Herstellern oder bei
den IDEs mitgeliefert werden. Da muss nichts selbst geschrieben werden.
Ein weiteres Problem deiner Version entsteht möglicherweise bei
generischen Device Drivern. Also bei Softwaremodulen, die sich ohne
Änderung nur durch einen Parameter auf verschiedene Instanzen der
Periphierie eignet, wie die diversen USARTs. Du musst dann darauf
vertrauen, dass die immer und immer wieder hingeschriebene Umrechnung
der nicht konstanten Basisadresse von der CSE Optimierung des Compilers
erfasst wird.
Ich hatte hier auch nur die Version hingeschrieben, die sich für solch
ggf. variable Basiszeiger eignet. In einfachen Fällen in denen zwischen
Basis und Offset nicht unterschieden werden muss sieht es bei mir auch
etwas anders aus.
Jörg Wunsch schrieb:> Ich glaube, das wäre durchaus mal einen Wiki-Artikel hier im> mikrocontroller.net-Wiki wert. ARM ist dort nach wie vor eher> unterbelichtet, finde ich.>> Würdest du das selbst machen wollen?ARM Bitbanding