mikrocontroller.net

Forum: Compiler & IDEs Cortex M3/M4 im Präprozessor erkennen


Autor: Walter T. (nicolas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

gibt es beim GCC eine Möglichkeit, per Präprozessor-Direktive zu 
erkennen, ob für einen Cortex M0, M3 oder M4 kompiliert wird?

Beim Keil-Compiler wird durch die Toolchain __CORTEX_M0, __CORTEX_M3, 
__CORTEX_M4 definiert, beim GCC nicht.

Gibt es beim GCC entsprechendes, oder läuft es darauf hinaus, eine 
entsprechende Präprozessorvariable selbst definieren zu müssen?

Oder anders gefragt: Wie stellt ihr fest, welche Intrisics für die 
Ziel-Plattform zur Verfügung stehen? Wie wählt ihr die richtige 
Header-Datei aus?
#if ????
    #include "core_cm3.h"
#elif ????
    #include "core_cm4.h"
#else
    #error "unknown target"
#endif




Viele Grüße
W.T.

: Bearbeitet durch User
Autor: Markus F. (mfro)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Walter T. schrieb:
> __CORTEX_M0, __CORTEX_M3,
> __CORTEX_M4

in der Form gibt's das nicht, aber hier:

http://micro-os-plus.sourceforge.net/wiki/Predefined_macros

gibt's eine hübsche Darstellung, wie man die Kerls trotzdem 
auseinanderhalten kann.

Autor: Walter T. (nicolas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auf die Makros bin ich auch schon gestoßen. Irgendwie erscheint es mir 
aber wie "hinten durch die Brust ins Auge":
#if defined(__arm__) && !defined(__ARM_FEATURE_SAT)
    #include "core_cm0.h"
#elif defined(__arm__) && defined(__ARM_FEATURE_SAT) && !defined(__ARM_FEATURE_SIMD32)
    #include "core_cm3.h"
#elif defined(__arm__) && defined(__ARM_FEATURE_SAT) && defined(__ARM_FEATURE_SIMD32)
    #include "core_cm4.h"
#else
    #error "unknown target"
#endif

Autor: eagle user (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Walter T. schrieb:
> Oder anders gefragt: Wie stellt ihr fest, welche Intrisics für die
> Ziel-Plattform zur Verfügung stehen? Wie wählt ihr die richtige
> Header-Datei aus?

Die Trennung nach M0/M3/M4... deckt ja nur einen winzigen Teil der 
Unterschiede von Chip zu Chip ab, jeder braucht seine eigenen 
Definitionen für die Hardware. Also gibt es hier ein Verzeichnis pro 
Chip. Bei allen M0-Chips steht da eine Kopie von "core_cm0.h" drin, bei 
den M3-Chips eine von "core_cm3.h"... Die Kopie heißt hier aber immer 
"asm.h".

Im Makefile wird das passende Chip-Header-Verzeichnis mit der Option 
"-I" angegeben und in den Quellen steht immer "asm.h".


So quasi das Gegenteil von deinem Wunsch ist wahrscheinlich möglich. Ein 
Quell-Datei kann angeblich die gcc-Option "-mcpu" umschalten:
https://gcc.gnu.org/onlinedocs/gcc/Function-Specif...

Autor: eagle user (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Es geht doch wenigstens etwas direkter:
touch foo.h
/opt/gcc/install/bin/arm-none-eabi-cpp -mthumb -mcpu=cortex-m3 -dM foo.h > m3
/opt/gcc/install/bin/arm-none-eabi-cpp -mthumb -mcpu=cortex-m4 -dM foo.h > m4
diff -c0 m4 m3
liefert alle predefined macros für die jeweilige CPU und diff zeigt die 
Unterschiede zwischen m3 und m4.
"grep ARCH" liefert:
                       m0   m3   m4   m7  m23
__ARM_ARCH              6    7    7    7    8
__ARM_ARCH_6M__         1   --   --   --   --
__ARM_ARCH_7M__        --    1   --   --   --
__ARM_ARCH_7EM__       --   --    1    1   --
__ARM_ARCH_8M_BASE__   --   --   --   --    1
__ARM_ARCH_PROFILE     77   77   77   77   77
__ARM_ARCH_ISA_THUMB    1    2    2    2    1
__ARM_ARCH_EXT_IDIV__  --    1    1    1    1

Autor: Walter T. (nicolas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe es dann doch noch ganz anders gemacht: Nämlich genauso wie in 
der arm_math.h:
#if defined(ARM_MATH_CM7)
  ...
#elif defined (ARM_MATH_CM4)
  ...
#elif defined (ARM_MATH_CM3)
  ...
#elif defined (ARM_MATH_CM0)
  ...
#else
  #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0"
#endif

Wenn ich diese Makros ohnehin global definieren muß, kann ich sie auch 
direkt anderweitig weiterverwenden.

Autor: Christopher J. (christopher_j23)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Grunde steckt doch alles in den CMSIS-Core Headern drin, auf denen 
jeder Hersteller dann seine ominösen Libraries aufbaut. Hast du z.B. 
einen STM32F446, dann wird (zumindest indirekt) irgendwo per #include 
eine "stm32f4xx.h" eingebunden. Dieser Header bindet dann wiederum je 
nachdem welcher #define für das eigentliche Device gesetzt ist einen 
spezifischeren Header ein. Für den F446 ist es "stm32f446xx.h" und hast 
du einen F407, dann ist es "stm32f407xx.h". In diesen 
(Device-spezifischen) Header-Dateien wird der passende Header für den 
Cortex-M Kern eingebunden, das heißt in diesem Beispiel (egal ob F407 
oder F446) jeweils "core_cm4.h". In dieser "core_cm4.h" gibt es dann 
direkt ein
#define __CORTEX_M (4U)

Wie genau die #defines für die anderen Cortex-M sind kannst du jeweils 
in der "core_cmX.h" herauslesen. Jedenfalls wird diese "core_cmX.h" ganz 
automagisch indirekt über den Device-Header eingebunden und das ist 
(soweit ich weiß) immer der Fall, nicht nur bei ST.

Autor: Walter T. (nicolas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das stimmt zwar  - aber wie nützt das?

Wie würdest Du die Defines und Includes einer *.C- und der zugehörigen 
*.H-Datei machen, die als "mathematische Library" Funktionen, die in 
Integer/Float32 gerechnet werden, zur Verfügung stellt?

Wenn ich für den Cortex M4 kompiliere, will ich die sättigenden 
Operationen und die Multiply-Accumulate natürlich nutzen, wenn ich für 
Windows kompiliere, soll natürlich der Ersatzcode für die M0/M3 zum 
Einsatz kommen.

Im Wesentlichen läuft das ja darauf hinaus, den richtigen Header zu 
includieren. Danach kann ich fallweise prüfen, ob die Intrinsics, die 
ich für eine Operation brauche, definiert sind und Ersatzcode 
bereitstellen (der GCC scheint ja die Idiome [noch?] nicht zu erkennen).

: Bearbeitet durch User
Autor: A. K. (prx)
Datum:

Bewertung
3 lesenswert
nicht lesenswert
Walter T. schrieb:
> Wenn ich für den Cortex M4 kompiliere, will ich die sättigenden
> Operationen und die Multiply-Accumulate natürlich nutzen, wenn ich für
> Windows kompiliere, soll natürlich der Ersatzcode für die M0/M3 zum
> Einsatz kommen.

Du willst also wissen, ob es gesättigte Arithmetik gibt, findest aber 
die dafür richtige Abfrage nach exakt dieser Feature per 
__ARM_FEATURE_SAT seltsam und bevorzugst die falsche Frage nach dem 
Core?

Autor: Seher (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In einer bunten IDE klickst du irgendwo den gewünschten µC an. Die 
deklariert dann das Makro.
Wenn du zu Fuß unterwegs bist, musst du es selber setzen. Egal, ob mit 
Keil oder GCC. Der Compiler kann deinen µC nicht erraten. Oder du nimmst 
den spezifischen Header für genau den µC. Da steckt es i. d. R. auch 
drin.

Autor: Carl D. (jcw2)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Seher schrieb:
> In einer bunten IDE klickst du irgendwo den gewünschten µC an. Die
> deklariert dann das Makro.
> Wenn du zu Fuß unterwegs bist, musst du es selber setzen. Egal, ob mit
> Keil oder GCC. Der Compiler kann deinen µC nicht erraten. Oder du nimmst
> den spezifischen Header für genau den µC. Da steckt es i. d. R. auch
> drin.

Egal ob IDE oder makefile, der Compiler will schon wissen ob er M3 oder 
M4 Code erzeugen soll. ARM ist nur bedingt gleich ARM.

Autor: Seher (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Carl D. schrieb:
> Egal ob IDE oder makefile, der Compiler will schon wissen ob er M3 oder
> M4 Code erzeugen soll.

Was verstehst du daran nicht?

Seher schrieb:
> Der Compiler kann deinen µC nicht erraten.

Autor: Walter T. (nicolas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Du willst also wissen, ob es gesättigte Arithmetik gibt,

Das auch - aber das war nicht meine Frage, weil es sich einfach 
herausfinden läßt. Meine Frage bezog sich darauf, den richtigen Header 
einzubinden.

Autor: Seher (Gast)
Datum:

Bewertung
-3 lesenswert
nicht lesenswert
Carl D. schrieb:
> der Compiler will schon wissen ob er M3 oder
> M4 Code erzeugen soll. ARM ist nur bedingt gleich ARM.

<Klugscheissmodus>
Es geht um Cortex und nicht reinen ARM. Code für den M0 ist ohne 
Änderung auf einem M3 oder M4 lauffähig. Das ist ein Entwicklungsprinzip 
der ARM-Company. Frag sie mal.
</Klugscheissmodus>

Autor: Christopher J. (christopher_j23)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Walter T. schrieb:
> Das stimmt zwar  - aber wie nützt das?
>
> Wie würdest Du die Defines und Includes einer *.C- und der zugehörigen
> *.H-Datei machen, die als "mathematische Library" Funktionen, die in
> Integer/Float32 gerechnet werden, zur Verfügung stellt?

Sorry, ich hatte die Frage nicht richtig verstanden. Was ich geschrieben 
habe ist für deine Anwendung natürlich quatsch. Die passendste Antwort 
hat denke ich Markus direkt zu Beginn gegeben.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.