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?
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?
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?
Hast du in der Datei stm32f4xx.h die Zeile für dein Target aktiviert? Anbei mal ein Beispiel für den STM32F407.
Die RCC_AHB1PeriphClockCmd ist Teil der LowLevel-Library. Wie hast du die eingebunden?
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)
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
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.
Die Low-Level Bibliothek kann der Projektassistent der Cube IDE automatisch herunterladen und einrichten.
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.
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
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.
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
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...
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
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?
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ß.
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?
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
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.
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.
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.
Mhhh....sollte ich mich da wirklich geirrt haben? Ich werds testen.
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.
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
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.
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.
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.
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.