Forum: Mikrocontroller und Digitale Elektronik STM32CubeIDE CMSIS Projektstrur Bibliotheken für STM32F4 ohne HAL!


von Daniel A. (daniel_a746)


Angehängte Dateien:

Lesenswert?

Guten Morgen zusammen,

ich versuche seit ein paar Tagen die Blibliotheken an den richtigen 
Stellen zu packen, sodass ich einige Programme fehlerfrei kompilieren 
kann. Als erstes habe ich mir gedacht starte ich damit den Systemtakt 
einzustellen um das dann mit dem SysTick durch toggeln einer LED 
abzuprüfen z. B. ~ 1s

Zum Erstellen der C-Programme nutze ich die STM32CubeIDE + CMSIS 
Bibliothek
Ausgeführt werden die Programme auf einem NUCLEO-64 Board mit einem 
STM32F411RE.

Ich habe einmal ein Screenshot von der jetzigen Projektstruktur gemacht.
In diesem Fall spuckt der Compiler "undefined reference to 
`RCC_AHB1PeriphClockCmd'" aus.

Das RCC_AHB1PeriphClockCmd ist in der stm32f4xx_rcc.h definiert und auch 
bereits in der main.c inkludiert. So richtig hab ich nicht verstanden, 
was ich falsch mache.

Kann mir da einer weiterhelfen?

von Ada J. Quiroz (inschnier)


Lesenswert?

Das bedeutet, dein Linker kennt diese Funktion nicht. Das bedeutet, sie 
wurde nicht übersetzt. Das bedeutet vermutlich, dass die entsprechende 
Sourcedatei in einem Verzeichnis liegt, welches nicht übersetzt wird, 
selbst wenn die Textsuche die Funktion finden kann.

Schonmal im zweiten Screenshot den Reiter Source Location überprüft?

von Steve van de Grens (roehrmond)


Lesenswert?


von Daniel A. (daniel_a746)


Angehängte Dateien:

Lesenswert?

Vielen Dank erstmal für die Hilfe.

Nialz schrieb:
> Das bedeutet, dein Linker kennt diese Funktion nicht. Das
> bedeutet, sie
> wurde nicht übersetzt. Das bedeutet vermutlich, dass die entsprechende
> Sourcedatei in einem Verzeichnis liegt, welches nicht übersetzt wird,
> selbst wenn die Textsuche die Funktion finden kann.

Nur warum?

> Schonmal im zweiten Screenshot den Reiter Source Location überprüft?
 Ja, alle Pfade sind drin.

Steve van de Grens schrieb:
> Ich mache das so: http://stefanfrings.de/stm32/cube_ide.html

Nach der Anleitung hab ich das ganze aufgesetzt, ebenfalls Project 
Properties>> C/C++ Build >> Settings "All configuration" usw.. alle 
Pfade drin.

Gleiche Fehlermeldung, habt ihr noch welche Ideen, woran es liegen 
könnte?

von Steve van de Grens (roehrmond)


Angehängte Dateien:

Lesenswert?

Hast du in der Datei stm32f4xx.h die Zeile für dein Target aktiviert?
Anbei mal ein Beispiel für den STM32F407.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Die RCC_AHB1PeriphClockCmd ist Teil der LowLevel-Library. Wie hast du 
die eingebunden?

von Daniel A. (daniel_a746)


Angehängte Dateien:

Lesenswert?

Steve van de Grens schrieb:
> Hast du in der Datei stm32f4xx.h die Zeile für dein Target
> aktiviert?
> Anbei mal ein Beispiel für den STM32F407.

Ja habe ich. Habs mal spaßeshalber wieder auskommentiert, dann kommt 
folgende Fehlermeldung: #error "Please select first the target STM32F4xx 
device used in your application (in stm32f4xx.h file)"

Niklas G. schrieb:
> Die RCC_AHB1PeriphClockCmd ist Teil der LowLevel-Library. Wie hast
> du
> die eingebunden?

LowLevel, ist damit die stm32f4xx_rcc.h, stm32f4xx_gpio.h etc. gemeint 
oder welche Dateien sind das? Wenn es das erste ist, befinden die sich 
im Ordner Inc (siehe Bild)

von Steve van de Grens (roehrmond)


Lesenswert?

Daniel A. schrieb:
> LowLevel,

Das eine andere Bibliothek die (wie HAL) von CMSIS abhängt aber nicht 
Bestandteil von CMSIS ist. Müsste da mit drin sein, denke ich:
https://www.st.com/en/embedded-software/stm32cubef4.html

Doku:
https://www.st.com/resource/en/user_manual/um1725-description-of-stm32f4-hal-and-lowlayer-drivers-stmicroelectronics.pdf

von Harald K. (kirnbichler)


Lesenswert?

Daniel A. schrieb:
> LowLevel, ist damit die stm32f4xx_rcc.h, stm32f4xx_gpio.h etc. gemeint

Das sind keine Libraries, sondern "include"- oder auch "Header"-Dateien.

Libraries heißen *.lib oder *.a und sind üblicherweise in einem 
Verzeichnis namens "lib" untergebracht.

von Steve van de Grens (roehrmond)


Lesenswert?

Die Low-Level Bibliothek kann der Projektassistent der Cube IDE 
automatisch herunterladen und einrichten.

von Steve van de Grens (roehrmond)


Lesenswert?

Harald K. schrieb:
> Das sind keine Libraries, sondern "include"- oder auch "Header"-Dateien.

War mal so. Die Bedeutung des Begriffes hat sich inzwischen verändert. 
Der Begriff gilt auch für Sammlungen von Quelltexten.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Daniel A. schrieb:
> LowLevel, ist damit die stm32f4xx_rcc.h, stm32f4xx_gpio.h etc. gemeint

Ich hab mich vertan: Diese beiden Files sind ein Teil der veralteten 
Standard Peripheral Library (SPL), aber es fehlen die dazugehörigen 
Source-Files.

Der Nachfolger der SPL ist die "LowLevel" (LL) -Library mit ähnlichen 
Konzepten aber nicht identisch. Die LowLevel Library befindet sich neben 
der HAL im STM32CubeF4-Paket ("stm32f4xx_ll_rcc.c" usw.).

Es empfiehlt sich die veraltete SPL nicht mehr zu nutzen sondern wenn 
schon die modernere LowLevel-Variante. Die ist zwar recht kompakt und 
effizient aber eben auch nicht besonders komfortabel.

Nehm's mir nicht übel, aber ich glaube bei deinem Wissensstand ist es 
einfacher, die HAL zu benutzen. Die IDE erzeugt mit der HAL automatisch 
direkt lauffähige Projekte, du kannst Code dafür generieren und die APIs 
sind recht abstrakt.

Es gibt recht wenig Grund noch die LL oder gar SPL zu nutzen außer man 
muss penibel an Speicher und Takten sparen.

: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

Steve van de Grens schrieb:
> War mal so. Die Bedeutung des Begriffes hat sich inzwischen verändert.

Nö. Da hat sich gar nichts geändert. Hier geht es um C.

von Steve van de Grens (roehrmond)


Lesenswert?

Harald K. schrieb:
> Da hat sich gar nichts geändert. Hier geht es um C.

Lies es selbst nach. Es geht schon beim Titel los:
https://www.st.com/en/embedded-software/stm32-standard-peripheral-libraries/documentation.html

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Steve van de Grens schrieb:
> Harald K. schrieb:
>> Das sind keine Libraries, sondern "include"- oder auch "Header"-Dateien.
>
> War mal so. Die Bedeutung des Begriffes hat sich inzwischen verändert.
> Der Begriff gilt auch für Sammlungen von Quelltexten.

Nur bei den Ardui****

Verdammt, beinahe hätte ich mch verquatscht. Also anders: bei allen, die 
wirklich wissen, was sie tun, gab es keine derartige 
Bedeutungsverschiebung des Begriffs...

von Steve van de Grens (roehrmond)


Lesenswert?

Ob S. schrieb:
> Nur bei den Ardui****

ST war schneller. Lies es selbst nach. Es geht schon beim Titel los:
https://www.st.com/en/embedded-software/stm32-standard-peripheral-libraries/documentation.html

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Ob S. schrieb:
> Also anders: bei allen, die
> wirklich wissen, was sie tun, gab es keine derartige
> Bedeutungsverschiebung des Begriffs...

Wie nennst du das Paket STM32CubeHAL oder CMSIS? Da ist keine *.lib oder 
*.a Datei drin.

Wie nennst du eine oder mehrere Header-Dateien welche Definitionen und 
Inline-Funktionen enthalten, welche für sich kein ausführbares Programm 
ergeben, aber als Komponente in viele verschiedene Programme eingebunden 
werden kann?

von Harry L. (mysth)


Lesenswert?

Niklas G. schrieb:
> Wie nennst du eine oder mehrere Header-Dateien welche Definitionen und
> Inline-Funktionen enthalten, welche für sich kein ausführbares Programm
> ergeben, aber als Komponente in viele verschiedene Programme eingebunden
> werden kann?

Header-Dateien - was denn sonst?
Inline-Funktionen gehören nicht in einen Header.

Ein Library enthällt min. auch Source-Files (.C(PP))
.a oder .lib sind nicht unbedingt ein Muß.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Harry L. schrieb:
> Header-Dateien - was denn sonst

Wie unterscheidest du so einen Header vom einem Header, der fester Teil 
eines einzelnen Programms ist?

Harry L. schrieb:
> Inline-Funktionen gehören nicht in einen Header.

Wohin sonst?

von Harry L. (mysth)


Lesenswert?

Niklas G. schrieb:
> Harry L. schrieb:
>> Inline-Funktionen gehören nicht in einen Header.
>
> Wohin sonst?

In den Quelltext (.C(PP))
Sie dürfen auch -genau wie jede andere Funktion- nur genau einmal den 
Compiler durchlaufen - sonst gibts Mecker vom Linker.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Harry L. schrieb:
> In den Quelltext (.C(PP))

Also in jede Quelltext-Datei kopieren? Was ist dann der Unterschied 
zwischen einer inline-Funktion und einer nicht-inline-Funktion?

Harry L. schrieb:
> Sie dürfen auch -genau wie jede andere Funktion- nur genau einmal den
> Compiler durchlaufen - sonst gibts Mecker vom Linker.

Nein, denn sie werden ja geinlined.

von Harry L. (mysth)


Lesenswert?

Niklas G. schrieb:
> Also in jede Quelltext-Datei kopieren? Was ist dann der Unterschied
> zwischen einer inline-Funktion und einer nicht-inline-Funktion?

Nein, genau einmal!

Niklas G. schrieb:
> Nein, denn sie werden ja geinlined.

Der Compiler fügt nur inline als Attribut hinzu.
Das eigentliche Inlining erledigt der Linker.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Harry L. schrieb:
> Nein, genau einmal!

Der GCC sagt dazu:
1
..\main.cpp:3:12: warning: inline function 'int max(int, int)' used but never defined
2
3
ld.exe: main.o:main.cpp:6: undefined reference to `max(int, int)'

Hier heißt es:

https://isocpp.org/wiki/faq/inline-functions#inline-nonmember-fns

Note: It’s imperative that the function’s definition (the part between 
the {...}) be placed in a header file, unless the function is used only 
in a single .cpp file. In particular, if you put the inline function’s 
definition into a .cpp file and you call it from some other .cpp file, 
you’ll get an “unresolved external” error from the linker.

Harry L. schrieb:
> Das eigentliche Inlining erledigt der Linker.

Welcher Linker kann das (mit Beleg bitte)? Der GNU LD offenbar nicht, 
selbst bei eingeschaltetem LTO.

von Harry L. (mysth)


Lesenswert?

Mhhh....sollte ich mich da wirklich geirrt haben?

Ich werds testen.

von Harry L. (mysth)


Lesenswert?

So, ich habs getestet:
Die inline-Funktion in der main.c geschrieben, in einer Header-Datei als 
extern definiert und in einer weiteren .c-Datei verwendet - 
funktioniert.

Ob C++ sich da anders verhält weis ich nicht.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Harry L. schrieb:
> Die inline-Funktion in der main.c geschrieben, in einer Header-Datei als
> extern definiert und in einer weiteren .c-Datei verwendet -

Welcher Compiler?

Bei MinGW32 (GCC v11) funktioniert es auch mit "extern" nicht, weder C 
noch C++. inline-Funktionen müssen, genau wie der Name es sagt, "inline" 
(typischerweise im Header) definiert werden, vor jeder Nutzung. Genau so 
steht es auch seit eh und je in allen C & C++ Büchern & Tutorials.

: Bearbeitet durch User
von Harry L. (mysth)


Lesenswert?

Niklas G. schrieb:
> Welcher Compiler?

Der GCC, der mit der CubeIDE kam.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Harry L. schrieb:
> Der GCC, der mit der CubeIDE kam.

Der wirft aber auch eine Warnung, weil es die Regel aus C verletzt, dass 
die Definition beim Kompilieren sichtbar sein muss.

Es funktioniert anscheinend nur mit "extern" an der Definition. Das 
dürfte aber eine GNU-spezifische Erweiterung sein.

von Harry L. (mysth)


Lesenswert?

Niklas G. schrieb:
> Der wirft aber auch eine Warnung, weil es die Regel aus C verletzt, dass
> die Definition beim Kompilieren sichtbar sein muss.

Definitiv keine Warnung.
--wall hab ich immer an.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Harry L. schrieb:
> Definitiv keine Warnung.

Spannend, bei mir schon.

Die Funktion wird dann auch nicht geinlined, sondern ganz normal 
aufgerufen. "inline" so zu verwenden ist also sinnlos.

von Harry L. (mysth)


Lesenswert?

Du hast recht!
Wieder was gelernt. - Danke für den Denkanstoss.

https://www.ibm.com/docs/en/xl-c-and-cpp-aix/16.1?topic=specifiers-inline-function-specifier

Dennoch wird eine Header-Datei dadurch nicht zu einem Library.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Harry L. schrieb:
> Dennoch wird eine Header-Datei dadurch nicht zu einem Library.

Welchen Begriff verwendest du für wiederverwendbare (Sammlungen von) 
Headerdateien? Hier findet sich z.B. eine ganze Reihe von solchen 
Paketen:

https://github.com/p-ranav/awesome-hpp

Die C++ -Community nennt so etwas schon lange "Header-Only Library". Wie 
würdest du es nennen? Einfach nur "Headersammlung" ist zu ungenau und 
klobig. Man möchte betonen, dass diese Sammlung als wiederverwendbarer 
Teil in Anwendungen eingebunden werden kann.

: Bearbeitet durch User
von Daniel A. (daniel_a746)


Lesenswert?

So weg jetzt mal von dem nervigen nicht wirklich hilfreichen unnötigen 
Offtopic..
--------------------------------
Habs hingekriegt, für den jenigen der vielleicht vor dem gleichen 
Problem steht hier die Lösung:

siehe Lösungsvorschlag von dem User 0______
https://stackoverflow.com/questions/68193192/cmsis-stm32-how-to-begin

Einfach von der CubeIDE alles generieren lassen und hinterher einfach 
die HAL-Files löschen. Dann funzt alles..

So jetzt dürft ihr weiter diskutieren, viel Spaß noch :D

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Daniel A. schrieb:
> Einfach von der CubeIDE alles generieren lassen und hinterher einfach
> die HAL-Files löschen. Dann funzt alles..

Die generierte main.c enthält aber jede Menge Aufrufe an HAL-Funktionen, 
insbesondere eben auch RCC. Wie funktioniert das?

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.