Forum: Mikrocontroller und Digitale Elektronik ARM CMSIS-DSP / GCC Assembler ignoriert #ifdef etc.


von Ralf (Gast)


Lesenswert?

Hallo,

ich strauchel grad mit dem GCC (4.9.3 auf Windows). Ich möchte CMSIS-DSP 
nutzen, konkret geht es um eine FFT. Das FFT Frequency Bin Beispiel aus 
dem CMSIS Paket läuft.

Basierend darauf wollte ich das ganze auf die Verwendung der 
RFFT-Funktionen umstricken, also auf rein reelle Werte im Q15/Q31 
Format.

Die RFFT-Funktionen verwenden im Gegensatz zum Beispielprogramm 
zusätzlich Funktionen aus der CMSIS-Datei "arm_bitreversal2.S", also 
eine Assemblerdatei.
In der Assemblerdatei wird per Preprocessor-Anweisungen (#ifdef, etc.) 
abgefragt, durch welche Toolchain das ganze gejagt wird und in 
Abhängigkeit davon werden per #define entsprechende Textersetzungen für 
Schlüsselwörter des jeweiligen Assemblers generiert.
Das Problem ist nun, dass offenbar der Preprocessor da nicht oder nicht 
richtig arbeitet.

Die betreffende Datei kann hier eingesehen werden:
https://github.com/ARM-software/CMSIS/blob/master/CMSIS/DSP_Lib/Source/TransformFunctions/arm_bitreversal2.S

Die Fehlermeldung lautet, dass die Anweisungen direkt nach dem #endif 
(also CODESECT, THUMB, etc.) nicht erkannt werden, also die Ersetzung 
nicht vorgenommen wird.
Das ließ mich zuerst vermuten, dass das Symbol '__GNUC__' gar nicht 
definiert ist(ich interpretiere die GCC Doku aber so, dass dieses Symbol 
eigentlich immer vorhanden sein müsste).
Also hab ich für einen schnellen Test ganz am Anfang '#define __GNUC__' 
eingefügt, das hat aber auch nichts bewirkt, was mir nun die Frage 
aufwirft, ob der Preprocessor da überhaupt richtig arbeitet.

Geprüft habe ich die Dateiendung, sie ist auf meinem Windows-System mit 
einem großen 'S' (lt. Doku unterscheidet GCC bzgl verwendetem 
Preprocessor anhand der Groß-/Kleinschreibung der Dateiendung), 
testweise ein kleines 's' machte keinen Unterschied.
Was noch fehlt, wäre die Prüfung, ob man dem Assembler das Symbol im 
Aufruf übergeben kann (wäre zumindest ein Workaround, wobei ich wie 
gesagt dachte, dass das Symbol immer vorhanden ist).
Desweiteren habe ich gesehen, dass man auch das Preprozessorverhalten 
beeinflussen kann, hier muss ich noch schauen, ob und wie man das auf 
den Assembler anwenden kann.

Hat jemand Erfahrungen mit #define & Co in Assemblerdateien und eine 
Idee, was da schief läuft?

Mit welchen Parametern die Toolchain den Assembler aufruft werde ich 
noch nachreichen.
Ich hoffe ich hab keine wichtigen Informationen vergessen.

Ralf

von Jim M. (turboj)


Lesenswert?

Klingt als suchst Du die GCC Option "-x assembler-with-cpp".

von Axel S. (a-za-z0-9)


Lesenswert?

Ralf schrieb:
> Ich hoffe ich hab keine wichtigen Informationen vergessen.

Hast du. Deine Ausführung ist nichts anderes als eine etwas langatmige 
Variante von "geht nicht". Als Minimum hättest du deinen Code und die 
Fehlermeldung vom Compiler zeigen müssen. Dazu noch die genauen(!) 
verwendeten Versionen von Compiler und Libraries und es hätte jemand 
zumindest die Chance gehabt, das nachzustellen was du siehst.

Aber so? "Irgendwelcher Code, der (subtil) anders ist als 
funktionierender Beispielcode, funktioniert nicht." Toll. Wie soll man 
dir da überhaupt helfen können?

von Ralf (Gast)


Lesenswert?

Guten Morgen zusammen,

@Axel:
> Deine Ausführung ist nichts anderes als eine etwas langatmige Variante von "geht 
nicht".
Ich stimme dir zu dass es ein längerer Text ist. Andersrum les ich aber 
sonst immer "geht nicht ist keine klare Aussage und man kann nichts 
damit anfangen". Ergo: Egal wie man's macht, es ist immer verkehrt :)

> Als Minimum hättest du deinen Code...
Ich hab doch einen Link auf den Code angegeben.

> ...und die Fehlermeldung vom Compiler zeigen müssen.
Korrekt, die hatte ich aber um die Uhrzeit nicht mehr im Sinn.

> Dazu noch die genauen(!) verwendeten Versionen von Compiler...
Steht auch oben: GCC 4.9.3

>  ...und Libraries...
Welche Libraries meinst du? Die im CMSIS-Paket mitgelieferte GCC-Lib 
verwende ich vorerst nicht, und andere Libs außer der Mathematik-Lib 
habe ich nicht aktiv.

So, hier noch die fehlenden Angaben, der Aufruf des Assemblers:

arm-none-eabi-as.exe -mcpu=cortex-m3 -mthumb -I. 
-IGenerated_Source\PSoC5 
-alh=.\CortexM3\ARM_GCC_493\Debug/arm_bitreversal2.lst -g -o 
.\CortexM3\ARM_GCC_493\Debug\arm_bitreversal2.o 
..\..\CMSIS-SP-00300-r4p5-00rel0\CMSIS\DSP_Lib\Source\TransformFunctions 
\arm_bitreversal2.S

Und die Fehlermeldung:
\...\arm_bitreversal2.S:72: Error: bad instruction `codesect'
\...\arm_bitreversal2.S:73: Error: bad instruction `thumb'
etc.
Diese Fehlermeldungen ließen mich dann eben vermuten, dass die Ersetzung 
nicht vorgenommen wird.

@Jim:
> Klingt als suchst Du die GCC Option "-x assembler-with-cpp".
Danke, das ist genau der erwähnte Ansatz mit dem Beeinflussen des 
Preprocessorverhaltens, das probiere ich aus, sobald ich herausgefunden 
habe, wie ich der IDE sage, dass sie die Datei über GCC und nicht AS 
jagen soll.

Ralf

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ralf schrieb:
> arm-none-eabi-as.exe

Du rufst den Assembler von Hand auf?  Dann gilt das gleiche auch für den 
Präprozesser: vor dem Assemblieren von Hand aufrufen.

In fast allen Fällen ist es einfacher und weniger fehlerträchtig foo-gcc 
als Treiber für Präprozessor, Compiler, Assembler und Linker zu 
verwenden.

Ergo:  foo-gcc verwenden anstatt foo-as

Das erfordert i.d.R. das Anpassen von Flags.  -ahl= kannt gas aber nicht 
gcc, daher muss bei Verwendung von gcc -Wa,-ahl= oder -Xassembler -ahl= 
verwendet werden.

http://gcc.gnu.org/onlinedocs/gcc/Assembler-Options.html

Die Programme, die der gcc-Treiber unter der Haube aufruft, kannst du 
mit -v anzeigen lassen, und mit -### wird nur angezeugt, was gcc 
aufrufen würde ohne die Programme wie as dann tatsächlich aufzurufen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Und wenn du nur foo-as verwenden willst, dann darfst du nicht Code für 
den C-Präprozessor verwenden sondern musst den gas Präprozessor nehmen. 
Der hat aber eine andere Syntax, z.B. .macro

Das Ergebnis des C-Präprozessors kannst du mit -save-temps sichern 
lassen (als *.s).  Das Zwischenergebnis nach dem as-Präprozessor lässt 
sich AFAIK nicht speichern oder anzeigen.

von (prx) A. K. (prx)


Lesenswert?

Normalerweise ruft man den Assembler über "gcc" auf, mit *.S als 
Quellfile. Das hier betrachtete Quellfile setzt das offensichtlich 
voraus.

von Ralf (Gast)


Lesenswert?

Hallo Johann,

> Du rufst den Assembler von Hand auf?  Dann gilt das gleiche auch für den
> Präprozesser: vor dem Assemblieren von Hand aufrufen.
Ich ruf da gar nix auf, das macht alles die IDE -> Cypress PSoC Creator.

> In fast allen Fällen ist es einfacher und weniger fehlerträchtig foo-gcc
> als Treiber für Präprozessor, Compiler, Assembler und Linker zu
> verwenden.
> Ergo:  foo-gcc verwenden anstatt foo-as
Ich muss schauen ob ich das umbiegen kann.

> Das erfordert i.d.R. das Anpassen von Flags.  -ahl= kannt gas aber nicht
> gcc, daher muss bei Verwendung von gcc -Wa,-ahl= oder -Xassembler -ahl=
> verwendet werden.

> Und wenn du nur foo-as verwenden willst, dann darfst du nicht Code für
> den C-Präprozessor verwenden sondern musst den gas Präprozessor nehmen.
> Der hat aber eine andere Syntax, z.B. .macro
Mein Ziel ist es, das auf der IDE so ans Laufen zu bekommen, dass ich 
nix im CMSIS-Code ändern muss - weil ansonsten bei jeder neuen 
CMSIS-Version geändert werden muss.

Ralf

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ralf schrieb:
>> Du rufst den Assembler von Hand auf?  Dann gilt das gleiche auch für den
>> Präprozesser: vor dem Assemblieren von Hand aufrufen.
> Ich ruf da gar nix auf, das macht alles die IDE -> Cypress PSoC Creator.

Macht das einen Unterschied od du es aufrufst oder wer sonst?

von Ralf (Gast)


Lesenswert?

Hallo Johann,

>> Ich ruf da gar nix auf, das macht alles die IDE -> Cypress PSoC Creator.
> Macht das einen Unterschied od du es aufrufst oder wer sonst?
Ja, weil ich nicht einstellen kann, dass anstatt AS GCC verwendet wird. 
Und ich hab das o.g. so verstanden, dass es nur über GCC geht.

Ralf

von Axel S. (a-za-z0-9)


Lesenswert?

Ralf schrieb:

>>> Ich ruf da gar nix auf, das macht alles die IDE -> Cypress PSoC Creator.
>> Macht das einen Unterschied od du es aufrufst oder wer sonst?
> Ja, weil ich nicht einstellen kann, dass anstatt AS GCC verwendet wird.

Wenn man das nicht einstellen kann, dann ist das Cypress Tool kaputt. 
Und wenn es Quellcodefiles mit Extension .S direkt an den Assembler 
verfüttert, dann ist das auch kaputt. Die gängige Konvention ist: .s = 
Assembler ohne Präprozessor, .S = Assembler mit Präprozessor.

> Und ich hab das o.g. so verstanden, dass es nur über GCC geht.

Es geht schon auch ohne. Aber wenn du Assemblercode mit C-Präprozessor 
Makros drin übersetzen willst, dann hast du genau zwei Optionen:

1. den Präprozessor von Hand aufrufen oder
2. gcc verwenden, der das für dich macht

alternativ gibt es auch noch

3. keine C-Makros im Assemblercode verwenden

Mit 3. kannst du aber auch CMSIS knicken. Zumindest den Teil, der in 
Form von C-Headerfiles kommt.

von Ralf (Gast)


Lesenswert?

Hallo Axel,

> Wenn man das nicht einstellen kann, dann ist das Cypress Tool kaputt.
> Und wenn es Quellcodefiles mit Extension .S direkt an den Assembler
> verfüttert, dann ist das auch kaputt. Die gängige Konvention ist: .s =
> Assembler ohne Präprozessor, .S = Assembler mit Präprozessor.
Ja, ich denke dass die das da einfach nicht so genau genommen haben. Ich 
werd denen das mal schildern.

> Es geht schon auch ohne. Aber wenn du Assemblercode mit C-Präprozessor
> Makros drin übersetzen willst, dann hast du genau zwei Optionen:
Ich will schauen, dass Cypress das Tool so gestaltet, dass man das so 
lösen kann, wie man es möchte.

Ralf

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Axel S. schrieb:
> Die gängige Konvention ist: .s = Assembler ohne Präprozessor,
> .S = Assembler mit Präprozessor.

Dem Assembler ist das egal.  Der schluckt was man ihm vorwirft.

> .S = Assembler mit Präprozessor.

Damit bin ich unter Windoofs schon mal richtig auf die Fresse gefallen:

Ich übersetzte mit -save-temps, das Ergebniss des präprozessierten .S 
wird dann als .s gesichert.  Da .s immer temporär sind (auch die aus .c, 
.cpp, .C etc.) gab es im Makefile eine clean-Regel für .s.

Den Rest kannst du dir denken:  Weil Windoofs zu blöd war, Groß- und 
Kleinschreibung zu unterscheiden, würden per make clean die .S-Quellen 
entsorgt.

Es gibt keinen Grund, .S zu verwenden!  gcc als Treiber behandelt .sx 
genauso wie .S auch.  Und wenn einem .asm oder andere Endungen lieber 
sind, dann gibt es bekanntlich -x assembler-with-cpp

von Ralf (Gast)


Lesenswert?

Hallo,

folgender Stand:
- Typ der Assemblerdatei auf C geändert, so dass die GCC.exe verwendet 
wird und zusätzlich hab ich '-x assembler-with-cpp' übergeben
- Sachverhalt an Cypress per Supportticket

Momentan hat das für mich den Status 'Workaround' (genauso wie die 
Verwendung der mitgelieferten, vorkompilierten Lib im CMSIS-Paket), und 
man muss das dann eben wissen, sonst ist man erst mal verloren. Fakt ist 
aber, dass es soweit nun läuft und ich weiter machen kann.

Besten Dank an alle für die Unterstützung.

Ralf

von Dieter Graef (Gast)


Lesenswert?

Das Problem gabs schon mal hier 
Beitrag "CMSIS DSP Library richtig anwenden"

m.f.G.
Dieter

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.