Forum: Mikrocontroller und Digitale Elektronik IAR Compiler , Bit in Register setzen (ST ARM)


von HERRMANN (Gast)


Angehängte Dateien:

Lesenswert?

Arbeiten uns gerade in den IAR Compiler für ARM Prozessoren ein. Im 
angehängten include file befindet sich ein Auszug der Deklaration des 
Registers RCC_APB2ENR (IOSTM32....). Wir möchten den UART einschalten 
also USART1EN setzen. Wie macht man das , ohne das ganze Register direkt 
mit einer Zahl zu beschreiben? Wir haben schon alles probiert, der 
Compiler bringt immer eine Fehlermeldung. Bei anderen Compiler wars so: 
RCC_APB2ENR |= (1<<USART1EN) wo aber der Compiler anmeckert, das er 
USART1EN nicht kennt.

von me (Gast)


Lesenswert?

probier mal, statt USART1EN die echte bit-Position(0..7)? in dem 
Register, wo es sich befinden sollte, einzutragen. Wenn es dann geht, 
kennt der Compiler den Namen für die bit-Position nicht. Habe aber von 
ARMs weiter keine Ahnung.

von Düsendieb (Gast)


Lesenswert?

HERRMANN schrieb:
> RCC_APB2ENR |= (1<<USART1EN)

dass heißt "USART1EN" ist nirgens definiert.


es geht aber RCC_APB2ENR |= (1<<5); wenn USART1EN das Bit 5 währe (weiß 
ich aber nicht)

von HERRMANN (Gast)


Lesenswert?

Das geht natürlich, es befriedigt mich aber nicht, da USART1EN im h file 
steht und so mit Sicherheit angewendet werden kann.

von me (Gast)


Lesenswert?

dann wirst du dich mit deinem Anliegen wohl an IAR Systems wenden 
müssen, wenn es im *.h file definiert und auch includiert wurde...

von robbse (Gast)


Lesenswert?

Guck mal in den Optionen nach, da gibt es irgendwo den Punkt "enable Bit 
definitions" oder so. Jedebfalls bei der Version für AVR.

von robbse (Gast)


Lesenswert?

Poject -> Options -> General Options -> System -> Häkchen bei "Enable 
bit definitions in I/O-Include files"

von HERRMANN (Gast)


Lesenswert?

Leider nein......

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Schon lange nichts mehr mit EWARM gemacht und auch nicht mehr 
installiert aber soweit erinnert, bietet der IAR Compiler die 
Möglichkeit Register direkt auf Bit-Felder "abzubilden". Der im 
TO-Beitrag angehängte Teil der Definitionen ist etwas knapp, um das 
nachzusehen. Testweise also:
RCC_APB2ENR.USART1EN=1;  Wie das intern umgesetzt wird, kann man dem 
erzeugen Assembler-Listing und/oder Disassembly entnehmen.

Das Konstrukt "mappen auf Bitfelder" sollte jedoch vermieden werden, 
wenn man portablen Code schreiben will. Beim GNU C-Compiler wurde diese 
Funktionalität meines Wissens z.B. erst jüngst in den Entwicklungs-Code 
aufgenommen (Google-Futter: -fstrict-volatile-bitfields). Ältere und 
aktuelle Versionen erkennen eine vermeindliche Optimierungsmöglichkeit 
und nutzen für Hardware-Register nicht zulässige Byte-Zugriffe).

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Martin Thomas schrieb:
> Das Konstrukt "mappen auf Bitfelder" sollte jedoch vermieden werden,
> wenn man portablen Code schreiben will. Beim GNU C-Compiler wurde diese
> Funktionalität meines Wissens z.B. erst jüngst in den Entwicklungs-Code
> aufgenommen (Google-Futter: -fstrict-volatile-bitfields). Ältere und
> aktuelle Versionen erkennen eine vermeindliche Optimierungsmöglichkeit
> und nutzen für Hardware-Register nicht zulässige Byte-Zugriffe).

Bitfelder sind im ARM ABI ausführlich dokumentiert. Insbesondere ist es 
vorgeschrieben, dass die Größe der Zugriffe auf volatile Bitfelder deren 
Containergröße entsprechen muss. Das Verhalten der betroffenen GCC 
Versionen ist somit fehlerhaft und hat nichts mit Portabilität zu tun.

--
Marcus

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Marcus Harnisch schrieb:
> Bitfelder sind im ARM ABI ausführlich dokumentiert. Insbesondere ist es
> vorgeschrieben, dass die Größe der Zugriffe auf volatile Bitfelder deren
> Containergröße entsprechen muss.

Ja, das wird auch als Grund für die Erweiterung in der GNU compiler 
collection angegeben.

> Das Verhalten der betroffenen GCC
> Versionen ist somit fehlerhaft und hat nichts mit Portabilität zu tun.

Ja, dass das Verhalten bei volatilen Bitfeldern in bisherigen GCC C/C++ 
Versionen mag im Sinne von ARMs Vorgaben fehlerhaft sein. Vermeidet man 
aber Bitfelder 'über Hardwareregistern' und nutzt stattdessen 
'*(volatile uint32_t *)' und Bitoperationen, kann man Quellcode mit 
allen Compilern für ARM in lauffähigen Maschinencode übersetzten. Ich 
bezeichne das dann als portablen Code. Lerne aber gerne eine korrektere 
Defintion.

Weiteres ist in einem neuen Thread besser aufgehoben.

von HERRMANN (Gast)


Lesenswert?

Also bei RCC_APB2ENR.USART1EN=1; kommt eben "expression must have struct 
oder union Type" Ich gebs jetzt vorläufig mal auf und werde später 
wieder auf das Problem zurückgehen, wenn ich mit dem Prozessor etwas 
firm bin....

von Karl H. (kbuchegg)


Lesenswert?

HERRMANN schrieb:
> Das geht natürlich, es befriedigt mich aber nicht, da USART1EN im h file
> steht und so mit Sicherheit angewendet werden kann.

Dann würde ich mal an dieser Stelle im .h File anfangen.

Wie genau ist USART1EN dort eingetragen?
Ich nehm mal an, dass dort so etwas steht wie

#define USART1EN 5


Von dort gehts jetzt weiter nach aussen:
Steht dieser #define in einem #ifdef?
Wenn ja, welche Bedingung (anderes #define) muss es daher dafür geben? 
Wo kommt das wiederrum her?
Dieses .h File, wird das von einem anderen .h File includiert?

etc, etc.
Solange bis du genau weßt, waann und warum der #define für UART1EN aktiv 
ist und welche anderen Symbole das steuern.

Und dann sieht man nach, wie man das auf der Oberfläche regeln kann, 
dass das erste Symbol definiert wird, welches dann alles weitere 
triggert.

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Martin Thomas schrieb:
> Vermeidet man aber Bitfelder 'über Hardwareregistern' und nutzt
> stattdessen '*(volatile uint32_t *)' und Bitoperationen, kann man
> Quellcode mit allen Compilern für ARM in lauffähigen Maschinencode
> übersetzten.

Und wer garantiert, dass der Zugriff auf ein (volatile uint32_t) in
jedem Fall von jeder beliebigen Compilerversion durch einen
Wortzugriff erfolgt? Du gehst davon aus, weil es in der ABI (sec
7.1.5) so definiert ist und erwartest, dass der Compiler sich daran
hält.

Man kann den Einsatz von bit-fields für sinnvoll halten oder nicht
(durchaus auch fallweise), aber in diesem Zusammenhang einen
Compilerfehler als Begründung seiner Präferenz zu bemühen ist schon
arg weit hergeholt.

Notfalls kann man sich den Registerwert in eine lokale Variable
kopieren, auf dieser Kopie arbeiten und das Ergebnis wieder zurück
schreiben. Bei der Manipulation mehrerer bits ist das in beiden
Fällen ohnehin nötig.

Gruß
Marcus

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.