Kompilierfehler Keil uVision V5
-
Hi
Nach all den Optimierungen, bringe ich irgendwie den Fehler nicht mehr weg.
Was meint die Fehlermeldung?
-
Linker-Fehler, kein Kompilierfehler (das Bild ist links abgeschnitten).
Wo ist die entsprechende Funktion definiert und hast du diese Datei in der Projetmappe eingebunden?
-
Du kannst die Fehlermeldung (als Text) auch per Copy&Paste hier rein kopieren.
Dann kann jeder diese sofort lesen.
Die Meldung stammt vom Linker und besagt, dass er dieses select_blabla_... nicht kennt.
Wo das definiert ist, musst du wissen (ist dein Code).
Diesen Code oder Library musst du dem Linker noch mitteilen.Es kann auch ein simpler Schreibfehler von dir sein.
-
fdfere schrieb:
Linker-Fehler, kein Kompilierfehler (das Bild ist links abgeschnitten).
Wo ist die entsprechende Funktion definiert und hast du diese Datei in der Projetmappe eingebunden?der Fehler ist:
*** Using Compiler 'V5.06 update 4 (build 422)', folder: 'C:\Keil_v5\ARM\ARMCC\Bin' Build target 'Test_Timer' linking... Test_Timer\Test_Timer.axf: Error: L6218E: Undefined symbol select_ADC_Channel_to_Convert (referred from main.o). Not enough information to list image symbols. Finished: 1 information, 0 warning and 1 error messages. "Test_Timer\Test_Timer.axf" - 1 Error(s), 0 Warning(s). Target not created. Build Time Elapsed: 00:00:03
die Funktion ist als Inline im adc.h definiert und dieser auch im main eingebunden
/* USER CODE BEGIN Includes */ #include "config.h" #include "epc_regdef.h" #include "tim1funct.h" #include "tim2funct.h" #include "tim15funct.h" #include "tim16funct.h" #include "alltimfunct.h" #include "adc.h" #include "i2c.h" #include "uart.h" #include "spi.h" #include "epc.h" #include "epc_constants.h" #include "dma.h"
-
buell schrieb:
die Funktion ist als Inline im adc.h definiert
Zeigen.
-
camper schrieb:
buell schrieb:
die Funktion ist als Inline im adc.h definiert
Zeigen.
Sorry, ich kann leider keine Dateien uploaden..
Hier die Files unten.
Im Linker kann ich nur folgende Einstellungen vornehmen. (Bild)https://picload.org/view/rpggawar/linker.jpg.html#ifndef __ADC1_H__ #define __ADC1_H__ #include "stm32l4xx_hal.h" extern ADC_HandleTypeDef hadc1; /* Beim ADC ist es wichtig, dass Vor der Verwendung des ADC muss dieser vom DEEP POWER DOWN aufgeweckt werden und der Spannungsregler vom ADC enabled werden Da der Spannungsregler eine Zeit tADCVREG_STUP = 20us für das Aufstarten benötigt, muss dieser entsprechend schon vor dem Samplen gestartet werden, spricht vor ADEN=1 Zum Stromsparen kann der ADC nach der Operation immer wieder in den DEEP_PWR_DOWN mode zurück versetzt werden*/ void Init_ADC1(void); void Init_ADC1_Test_single(void); void Init_ADC1_Test_differential(void); inline void Start_ADC() { ADC1->CR |= ADC_CR_ADSTART; } inline void Set_ADC_to_DEEP_PWR_DOWN(void) { ADC_Disable(&hadc1); ADC1->CR |= ADC_CR_DEEPPWD; /* enter deep-power-down mode */ ADC1->CR &= ~ADC_CR_ADVREGEN; /* disable the ADC internal voltage regulator --> tADCVREG_STUP = 20us --> ADC voltage regulator start-up time*/ } inline void Reset_ADC_from_DEEP_PWR_DOWN(void) { ADC_Disable(&hadc1); ADC1->CR &= ~ADC_CR_DEEPPWD; /* exit deep-power-down mode */ ADC1->CR |= ADC_CR_ADVREGEN; /* enable the ADC internal voltage regulator --> tADCVREG_STUP = 20us --> ADC voltage regulator start-up time*/ } /** ADC_Channel_INx can be one of: PC0 ------> ADC1_Channel_IN1 PC1 ------> ADC1_Channel_IN2 PC2 ------> ADC1_Channel_IN3 PC3 ------> ADC1_Channel_IN4 PA2 ------> ADC1_Channel_IN7 PA3 ------> ADC1_Channel_IN8 PA4 ------> ADC1_Channel_IN9 PA5 ------> ADC1_Channel_IN10 PA6 ------> ADC1_Channel_IN11 PA7 ------> ADC1_Channel_IN12 PB1 ------> ADC1_Channel_IN16 */ inline void select_ADC_Channel_to_Convert(uint8_t ADC1_Channel_INx) { ADC1->CR &= ~ADC_CR_ADSTART; // must be 0 before setting the channel ADC1->SQR1 = ADC1_Channel_INx << ADC_SQR1_SQ1_Pos; } #endif
-
Vermutlich wurde dieses Projekt zuvor mit einem anderen Compiler benutzt, der inline nicht konform umsetzt (oder es hat halt zufällig funktioniert).
inline void select_ADC_Channel_to_Convert(uint8_t ADC1_Channel_INx)
Diese Definition sollte entwder static sein, oder es existiert noch eine .c - Datei die eine extern-Deklaration vornimmt (und die entsprechende Objektdatei/Bibliothek müsste mitgelinkt werden). Wenn du den Header nicht verändern möchtest, kannst du auch einfach die Deklaration in deinem eigenen Code nachreichen:
extern inline void select_ADC_Channel_to_Convert(uint8_t ADC1_Channel_INx);
Im Prinzip gilt das Gleiche auch für alle anderen inline Funktionen.
-
camper schrieb:
Diese Definition sollte extern oder static sein.
Du hast den Vogel direkt abgeschossen. Das wars
Ich verstehe nicht ganz. Im Prinzip will ich keine der Funktionen im Header jemals ändern und wieso sollte man diese überhaupt ändern wollen?
Demnach müssten ja alle anderen Funktionen ja auch static sein, oder nicht?
Das verstehe ich jetzt nicht so ganz.
-
Du benutzt C99? Dann s. Inline functions in C99 mode:
/* myfile.c */ #include "example_header.h" extern inline int my_function(int); // causes external definition.
-
Im Gegensatz etwa zu C++ erzeugt eine bloße inline-Definition (ohne extern) keine out-of-line Kopie der Funktion. Beim Aufruf der Funktion steht es dem Compiler allerdings frei, die inline-Definition direkt zu verwenden oder aber einen ganz normalen Funktionsaufruf durchzuführen. Wenn er Letzteres tut und keine out-of-line Kopie irgendwo im Projekt erzeugt wurde, kann der Linker die Funktion nat. nicht finden.
Ohne mich damit näher beschäftigt zu haben, vermute ich mal, dass der Grund für dieses Verhalten darin liegt, dass man auch extrem primitive Linker unterstützen möchte, die keine schwachen Symbole kennen. Zum Vergleich: in C++ erzeugt jede Übersetzungseinheit, die die Definition einer inline-Funktion (mit extern-Linkage) enthalten, eine Kopie dieser Funktion in der Objektdatei, und es ist dann Aufgabe des Linkers, sich für eine bestimmte Version zu entscheiden (weil es schwache Symbole sind, führt das gleichzeitige Vorhandensein in verschiedenen Objektdateien nicht zu Kollisionen. Und weil das Programm nat. immer noch ein bestimmtes Verhalten haben soll, legt der Standard gleich noch fest, wann Definitionen in verschiedenen ÜEs überhaupt äquivalent sind, und verlangt, dass alle vorliegenden Definitionen so ausgeführt wurden.
C ist da liberaler: Im Prinzip habden die extern- und inline-Defintionen nichts miteinander zu tun, ausser, das sie den gleichen Namen haben. Ob das tatsächlich irgendeinen praktischen Nutzen hat, ist nat. eine ganz andere Frage.
-
camper schrieb:
Im Gegensatz etwa zu C++ erzeugt eine bloße inline-Definition (ohne extern) keine out-of-line Kopie der Funktion. Beim Aufruf der Funktion steht es dem Compiler allerdings frei, die inline-Definition direkt zu verwenden oder aber einen ganz normalen Funktionsaufruf durchzuführen. Wenn er Letzteres tut und keine out-of-line Kopie irgendwo im Projekt erzeugt wurde, kann der Linker die Funktion nat. nicht finden.
Ohne mich damit näher beschäftigt zu haben, vermute ich mal, dass der Grund für dieses Verhalten darin liegt, dass man auch extrem primitive Linker unterstützen möchte, die keine schwachen Symbole kennen. Zum Vergleich: in C++ erzeugt jede Übersetzungseinheit, die die Definition einer inline-Funktion (mit extern-Linkage) enthalten, eine Kopie dieser Funktion in der Objektdatei, und es ist dann Aufgabe des Linkers, sich für eine bestimmte Version zu entscheiden (weil es schwache Symbole sind, führt das gleichzeitige Vorhandensein in verschiedenen Objektdateien nicht zu Kollisionen. Und weil das Programm nat. immer noch ein bestimmtes Verhalten haben soll, legt der Standard gleich noch fest, wann Definitionen in verschiedenen ÜEs überhaupt äquivalent sind, und verlangt, dass alle vorliegenden Definitionen so ausgeführt wurden.
C ist da liberaler: Im Prinzip habden die extern- und inline-Defintionen nichts miteinander zu tun, ausser, das sie den gleichen Namen haben. Ob das tatsächlich irgendeinen praktischen Nutzen hat, ist nat. eine ganz andere Frage.Dann verstehe ich das richtig? C99 verhält sich gleich wie C++, wenn ich die Inline static definiere und wenn nicht, dann muss ich im c-File extern einfügen?
-
ja.