Cortex M3/M4 im Präprozessor erkennen

OP #5233532
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?
1
#if ????
2
    #include "core_cm3.h"
3
#elif ????
4
    #include "core_cm4.h"
5
#else
6
    #error "unknown target"
7
#endif




Viele Grüße
W.T.
OP #5233696
Auf die Makros bin ich auch schon gestoßen. Irgendwie erscheint es mir 
aber wie "hinten durch die Brust ins Auge":
1
#if defined(__arm__) && !defined(__ARM_FEATURE_SAT)
2
    #include "core_cm0.h"
3
#elif defined(__arm__) && defined(__ARM_FEATURE_SAT) && !defined(__ARM_FEATURE_SIMD32)
4
    #include "core_cm3.h"
5
#elif defined(__arm__) && defined(__ARM_FEATURE_SAT) && defined(__ARM_FEATURE_SIMD32)
6
    #include "core_cm4.h"
7
#else
8
    #error "unknown target"
9
#endif
Gast #5233862
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-Specific-Option-Pragmas.html
Gast #5241189
Es geht doch wenigstens etwas direkter:
1
touch foo.h
2
/opt/gcc/install/bin/arm-none-eabi-cpp -mthumb -mcpu=cortex-m3 -dM foo.h > m3
3
/opt/gcc/install/bin/arm-none-eabi-cpp -mthumb -mcpu=cortex-m4 -dM foo.h > m4
4
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:
1
                       m0   m3   m4   m7  m23
2
__ARM_ARCH              6    7    7    7    8
3
__ARM_ARCH_6M__         1   --   --   --   --
4
__ARM_ARCH_7M__        --    1   --   --   --
5
__ARM_ARCH_7EM__       --   --    1    1   --
6
__ARM_ARCH_8M_BASE__   --   --   --   --    1
7
__ARM_ARCH_PROFILE     77   77   77   77   77
8
__ARM_ARCH_ISA_THUMB    1    2    2    2    1
9
__ARM_ARCH_EXT_IDIV__  --    1    1    1    1
OP #5255436
Ich habe es dann doch noch ganz anders gemacht: Nämlich genauso wie in 
der arm_math.h:
1
#if defined(ARM_MATH_CM7)
2
  ...
3
#elif defined (ARM_MATH_CM4)
4
  ...
5
#elif defined (ARM_MATH_CM3)
6
  ...
7
#elif defined (ARM_MATH_CM0)
8
  ...
9
#else
10
  #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0"
11
#endif

Wenn ich diese Makros ohnehin global definieren muß, kann ich sie auch 
direkt anderweitig weiterverwenden.
#5256075
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
1
#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.
OP #5256123
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).
#5256133
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?
Gast #5256286
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.
#5256293
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.
Gast #5256329
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>
#5258242
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

Eine eigene Frage? Dieser Thread ist über 8 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.