ich habe ein Arduino nano3-Board und möchte darauf den ADC in Betrieb nehmen. Installiert ist WinAVR. Es gibt eine Datei main.c, eine adc.c und adc.h. Übersetzt wird durch Aufruf "make all" in einem DOS-Fenster. Eine LED brachte ich zum Blinken. Die Umgebung scheint also grundsätzlich ok. Seltsamerweise wird undefined reference to ADC_init gemeldet in Zeile 64. Dabei steht der Funktionsaufruf "ADC_init" gar nicht in 64, sondern in 66. Die Dateien sind hier www.mweisser.50g.com/prog/main.c www.mweisser.50g.com/prog/adc.c www.mweisser.50g.com/prog/adc.h www.mweisser.50g.com/prog/Makefile
:
Bearbeitet durch User
Matthias W. schrieb: > Die Dateien sind hier scheinbar nicht: Fehler 404: Zugriffsfehler kannst du sie nicht einfach hier hochladen?
Peter II schrieb: >> Die Dateien sind hier Sorry Peter. Ich habe sie in einen Ordner prog gesteckt. Das habe ich nun oben ergänzt.
:
Bearbeitet durch User
Matthias W. schrieb: > Sorry Peter. Ich habe sie in einen Ordner prog gesteckt. Das habe ich > nun oben ergänzt. geht immer noch nicht. lade sie jetzt hier hoch - oder willst du nur traffic auf deiner Seite generieren und keine Hilfe?
Peter II schrieb: > geht immer noch nicht. es geht nun. ADC war großgeschrieben. Nun ist es klein. Es geht mir nicht um sinnlosen Traffic auf der Seite. Im Gegenteil. Die Fehler sollen raus und dazu möchte ich die Änderungen jedesmal gleich wieder online stellen, statt sie hier im Forum breitzutreten.
Ich bezweifle, dass ADC.c überhaupt kompiliert und mitgelinkt wird, denn das hier
1 | SRC += \ |
2 | #usart.c \ |
3 | #dataflash.c \ |
4 | ADC.c \ |
5 | delay.c \ |
funktioniert sicher nicht so, wie von dir gewünscht.
Stefan Ernst schrieb: > funktioniert sicher nicht so, wie von dir gewünscht. Danke Stefan für den Hinweis. Du meinst die auskommentierten Zeilen funktionieren so nicht? Eigentlich sollte die Raute doch den Rest entwerten?
:
Bearbeitet durch User
Matthias W. schrieb: > Eigentlich > sollte die Raute doch den Rest entwerten? Richtig, den Rest der Zeile. Und was genau ist in dem Fall dieser "Rest"?
:
Bearbeitet durch User
Stefan Ernst schrieb: > Richtig, den Rest der Zeile. > Und was genau ist in dem Fall dieser "Rest"? bei der einen Zeile ist es "usart.c \" was nicht beachtet wird und bei der anderen Zeile ist es "dataflash.c \". Beachtet werden sollte also "ADC.c \". Was ist so falsch daran? Dieses Makefile funktionierte einwandfrei: http://www.mweisser.50g.com/prog/Makefile_old
Matthias W. schrieb: > Dieses Makefile funktionierte einwandfrei: > http://www.mweisser.50g.com/prog/Makefile_old es steht da: "If there is more than one source file, append them above, or modify and uncomment the following." kann man denn nicht zeilenweise "modifyen" oder "uncommenten"?
Matthias W. schrieb: > Beachtet werden sollte also "ADC.c \". Und genau das bezweifle ich. Welche Bedeutung hat das \ am Ende der Zeilen? Wie sieht also die "logische" Zeile aus? Was gehört demnach alles zum "Rest der Zeile" nach dem ersten #? Außerdem müsstest du doch am Output des make all direkt sehen können, ob es nun kompiliert/gelinkt wird, oder nicht.
Stefan Ernst schrieb: > Außerdem müsstest du doch am Output des make all direkt sehen können, ob > es nun kompiliert/gelinkt wird, oder nicht. er bricht ja mit dem Fehler ab. Die Frage eingangs war warum der Fehler in der falschen Zeile gemeldet wird. Wie ist das möglich? Normalerweise sollte GCC soll den Fehler in der richtigen Zeile melden. Oder nicht? Das war die Frage ganz oben: "Seltsamerweise wird undefined reference to ADC_init gemeldet in Zeile 64. Dabei steht der Funktionsaufruf "ADC_init" gar nicht in 64, sondern in 66."
Ohne einen Quellcode in diesem Thread ist der Thread für die Zukunft wertlos. Oft kommen Leute nach Jahren über einen Thread auf die Lösung Ihres Problems. Alleine aus diesem Grund würde ich mich schon weigern hier zu helfen.
Matthias W. schrieb: > "Seltsamerweise wird undefined reference to ADC_init gemeldet in Zeile > 64. Dabei steht der Funktionsaufruf "ADC_init" gar nicht in 64, sondern > in 66." poste mal den genauen Output.
Matthias W. schrieb: > er bricht ja mit dem Fehler ab. Aber davor ist doch noch diverser Output, z.B. auch die Kommandozeile fürs Linken. Da kann man dann doch sehen, ob da adc.o mit auftaucht, oder nicht. Matthias W. schrieb: > Die Frage eingangs war warum der Fehler > in der falschen Zeile gemeldet wird. Sorry, mein Fehler, ich dachte du wärst an der Beseitung des Fehlers interessiert.
Peter II schrieb: > poste mal den genauen Output. mit make all>text1.txt habe ich die Ausgabe umgeleitet: siehe http://www.mweisser.50g.com/prog/text1.txt leider fehlt am Ende etwas. Da steht main.o: In function 'main': C:\doc...../main.c:64 undefined reference to 'ADC_init' make: *** [main.elf] Error 1.
Stefan Ernst schrieb: > Aber davor ist doch noch diverser Output, z.B. auch die Kommandozeile > fürs Linken. Da kann man dann doch sehen, ob da adc.o mit auftaucht, > oder nicht. ado.o sehe ich da nicht. Das liegt schon an der Stelle wo Du vermutet hast. Wenn ich adc.c ganz oben hinschreibe geht es weiter bis zum nächsten Fehler. > Sorry, mein Fehler, ich dachte du wärst an der Beseitung des Fehlers > interessiert. ist nicht Dein Fehler. Mich interessiert beides. Der Fehler muss weg. Da bin ich dran und dank Dir ein Stück weiter. Außerdem würde ich gerne wissen warum der Fehler in der falschen Zeile gemeldet wird. Solche Fehler erschweren die Fehlersuche. Wenn es nur 2 Zeilen falsch ist wie hier mag es noch gehen. Wenn es jedoch 10 Zeilen sind oder mehr kann man sich ggf. totsuchen.
dort sieh man schön, das adc.c nicht kompiliert wird und auch dem linker nicht übergeben wird.
Matthias W. schrieb: > Außerdem würde ich gerne wissen warum der Fehler in der falschen Zeile > gemeldet wird. Solche Fehler erschweren die Fehlersuche. hier helfen sie aber nicht weiter. Du hast ein linker-Fehler. Da spielt der Quellcode zu 99% keine rolle mehr. Fehler mit "undefined reference" deuten auf eine fehlende lib oder ein fehlende Objekt hin.
Paul schrieb: > Ohne einen Quellcode in diesem Thread ist der Thread für die Zukunft > wertlos. Oft kommen Leute nach Jahren über einen Thread auf die Lösung > Ihres Problems. Alleine aus diesem Grund würde ich mich schon weigern > hier zu helfen. ich verstehe Deine Ansicht Paul. Es steht halt jede Menge Mist noch in meinem Code. Viel davon muss noch geklärt und bereinigt werden. Daran arbeite ich. Daher wollte ich das Forum nicht mit alledem dauerhaft belasten und hier nur das Wesentliche bringen das auch andere dann weiterbringt. In der main.c steht beispielsweise eine Menge auskommentierter Assembler. Wem nützt das später? Das kann raus wenn der Teil in C steht und arbeitet. Für mich ist das momentan eine Gedächtnisstütze. Ebenso steht eine Interruptvektortabelle in Assembler da. Da weiß ich noch gar nicht wie ich das brauchbar in C implementieren soll. Auch den UART-Teil muss ich noch machen. Das soll mit Interrupt gehen. Wenn ein Zeichen kommt wie z.B. "S", so soll der Wandler gestartet werden und z.B. 200 Zeichen hintereinander ins RAM ablegen. Das kann freilaufend sein - also z.B. alle 104us ein 10bit Datenwort ins RAM. Oder es wird über einen Timer gemacht. Freilaufend reicht mir am Anfang. Ich möchte die Zeitbasis des Oszis damit vermessen. Da ich kein DSO habe möchte ich es damit machen.
:
Bearbeitet durch User
Matthias W. schrieb: > Ebenso steht eine Interruptvektortabelle in Assembler da. Da weiß ich > noch gar nicht wie ich das brauchbar in C implementieren soll. Auch den > UART-Teil muss ich noch machen. Das soll mit Interrupt gehen. wäre es nicht sinnvoll sich vorher mal ein paar Grundlagen anzulesen? http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
Peter II schrieb: > hier helfen sie aber nicht weiter. Du hast ein linker-Fehler. Da spielt > der Quellcode zu 99% keine rolle mehr. und warum kommt dann die Meldung main.c:64? Ist mit 64 nicht die Zeile gemeint wo das Problem ist? > Fehler mit "undefined reference" deuten auf eine fehlende lib oder ein > fehlende Objekt hin. ja Peter, das ist ja auch so. Da hat der GCC recht. Dieser Fehler lag/liegt darin daß die Auskommentierungen die ich im Makefile machte so nicht verstanden werden. Daher habe ich nun die Zeile mit adc.c ganz nach oben über die Auskommentierungen geschoben. Da geht es.
Peter II schrieb: > wäre es nicht sinnvoll sich vorher mal ein paar Grundlagen anzulesen? > http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial Danke für den Link Peter. Mit Assembler lief das ja alles schon mal prima. Es ist mir auch klar daß man mit #include <avr/interrupt.h> das Include hinzunimmt. sei(); ist klar und cli(); Also nutze ich mit WinAVR2010 die neuen defines? #define INT0_vect _VECTOR(1) #define INT1_vect _VECTOR(2) #define TIMER2_COMP_vect _VECTOR(3) usw. und statt der Interrupttabelle nehme ich dann diese Funktionen? ISR(INT0_vect) { /* Interrupt Code */ } ISR(TIMER0_OVF_vect) { /* Interrupt Code */ } ISR(USART_RXC_vect) { /* Interrupt Code */ } so weit ist das dann klar. Macht es Sinn das erst mal mit WINAVR2010 zu machen oder ist es besser eine neuere Version zu nehmen?
Wahrscheinlich gammelt irgendwo noch ain altes main.o rum, weil durch das fehlerhafte Makefile auch main.c nicht compiliert wird. Der Linker zieht sich dann die Zeile zum undefinierten Symbols ADC_init aus dem alten main.o.
Johann L. schrieb: > Wahrscheinlich gammelt irgendwo noch ain altes main.o rum, weil durch > das fehlerhafte Makefile auch main.c nicht compiliert wird. Danke für den Hinweis Johann ! > Der Linker zieht sich dann die Zeile zum undefinierten Symbols ADC_init > aus dem alten main.o. das wäre denkbar. Nur dachte ich halt wenn man "make clean" macht - wird damit nicht das alte "main.o" gelöscht? Komisch.
Mit deinen komischen Kommentaren ist das Makefile nicht mehr valide. make bricht also bei ADC.c mit einem Fehler ab. Wo kein gültig Makefile, da auch kein make clean...
Johann L. schrieb: > Mit deinen komischen Kommentaren das war aus Auskommentierung gedacht. Viele Zeilen werden so auskommentiert im Makefile. > make bricht also bei ADC.c mit einem Fehler ab. Wo kein gültig > Makefile, da auch kein make clean... abgebrochen hat das "Makefile" nicht. Es wurde kompiliert und gelinkt. Nur eben ohne Einbeziehung von adc.c. Daher kam dann die Fehlermeldung mit Angabe der falschen Zeilennummer. Warum diese falsche Nummer? make clean arbeitet. Das löscht die main.o etc.
:
Bearbeitet durch User
Matthias W. schrieb: > das war aus Auskommentierung gedacht. Viele Zeilen werden so > auskommentiert im Makefile. Aber wenn die Zeile mit \ abgeschlossen wird, dann sagst Du damit aus, dass die logische Zeile in der nächsten physikalischen Zeile fortgeführt wird. Und damit hast Du den folgenden Rest auch auskommentiert. Ergo: Der Fehler sitzt zwischen den Ohren und nicht beim make.
Frank M. schrieb: > Und damit hast Du den folgenden Rest auch auskommentiert. ok. > Ergo: Der Fehler sitzt zwischen den Ohren und nicht beim make. Danke Frank. Das ist mir eine Weile klar und der Fehler auch behoben. Unklar ist mir nach wie vor die Fehlermeldung in main.c auf die falsche Zeile. Das ist mir noch immer nicht plausibel. Warum war das 2 Zeilen daneben? Das war die Anfangsfrage - siehe oben. Erklärungsversuche lauteten - er nimmt ein altes .o file. Er löscht diese mit make clean jedoch. Hat so ein Problem mit fehlerhafter Zeilennummer denn niemand jemals gehabt?
:
Bearbeitet durch User
Meine Erklärung wäre, daß durch Optimierung die Zeilenzuordnung nicht mehr stimmt. Der Linker muß die Infos über die Zeilennummer ja aus den Debug-Informationen holen, da es im o-File gar keine Zeilen mehr gibt. Und im Debugger ist es ja bekannt, daß bei eingeschalteten Optimierungen die Zeilen nicht mehr passen.
Danke Rolf. Die Zeilennummern sind ja der einzige Weg zum Fehler. Wenn die nicht stimmen wird es schwerer zu finden wo das ist. Bei längerem Code könnte der Unterschied deutlich größer sein. Dieser Code besteht bis zum Fehler ja nur ein ganz wenigen Zeilen. Eine LED wird an und ausgemacht - mehr nicht.
Matthias W. schrieb: > Die Zeilennummern sind ja der einzige Weg zum Fehler. Wenn > die nicht stimmen wird es schwerer zu finden wo das ist. Ach komm, jetzt übertreib mal nicht. Die Fehlermeldung enthält auch den Symbolnamen, und damit führt auch die Suchfunktion deines Editors zum Fehler.
hier der aktuelle Stand. make clean arbeitet (siehe make_clean.txt). make all arbeitet (siehe make_all.txt und make_all.png) und erzeugt eine Warnung in usart.c: Zeile 229. USART_RXC_vect appears to be a misspelled signal handler. In der Zeile steht: ISR(USART_RXC_vect). Muss das USART_RXC0_vect heißen? Weiter gibt es eine Fehlermeldung usart.o: In function USART_sendmsg: C:\.... usart.c:255 undefined reference to ADC2RAW. Der Fehler selbst ist klar. Die Funktion hatte ich auskommentiert. Unklar ist warum der Fehler in der falschen Funktion gemeldet wird - 19 Zeilen daneben. Ein Bug oder ein Feature?
Hallo Matthias, ich würde alle Headerdateien noch mit
1 | #ifdef _INCL_<HEADER_H>_INCL
|
2 | #define _INCL_<HEADER_H>_INCL
|
3 | :
|
4 | #endif
|
erweitern, um mehrfaches laden und auswerten zu vermeiden !
Uwe S. schrieb: > ich würde alle Headerdateien noch mit#ifdef _INCL_<HEADER_H>_INCL > #define _INCL_<HEADER_H>_INCL > : > #endif > erweitern, um mehrfaches laden und auswerten zu vermeiden ! Wozu soll denn deru Unterstrich am Anfang gut sein? Der ist eigentlich verboten.
Danke Magnus und Uwe ! Ich bin kein Fachmann für dies Mehrfach-Include-Thema. Auf der Seite http://stackoverflow.com/questions/14290026/linking-h-files-with-c-with-ifdef-header-guards steht ein Beispiel - hier angepasst an adc.h: "You need to include adc.h in all files that uses the functions that are defined in adc.h. So you need to put a #include <adc.h> in both files. To avoid that adc.h is loaded several times, you need the directives #ifdef: file adc.h #ifndef ADC_H #define ADC_H ... void func(..); void func(..); #endif und Datei adc.c: #include "adc.h" So müsste es doch gehen? Oder?
Matthias W. schrieb: > So müsste es doch gehen? Oder? Ja, das ist der richtige Weg. Manche machen würden vielleicht noch sowas wie ADC_H_included draus machen, um sicherzugehen, daß der Name nicht irgendwo schon für einen anderen Zweck verwendet wird. ADC_H könnte ja z.B. auch für das High-Byte des ADC-Ergebnisses stehen oder so. Bei solchen mehrfach-Belegungen wären schwer zu verstehende Fehlermeldungen des Compilers das Resultat.
Rolf Magnus schrieb: > Ja, das ist der richtige Weg. > Manche machen würden vielleicht noch sowas wie ADC_H_included draus > machen, um sicherzugehen Da hast Du sicher recht. Daher hat Uwe wohl das "_INCL" angehängt. Das kann ich ja machen. Weißt Du zufällig etwas zu dieser Warnung in usart.c: Zeile 229. "USART_RXC_vect appears to be a misspelled signal handler". In Zeile steht: ISR(USART_RXC_vect). Sollte das USART_RXC0_vect heißen? Es müsste doch eine Include-Datei geben wo das definiert ist?
Matthias W. schrieb: > Weißt Du zufällig etwas zu dieser Warnung in usart.c: Zeile 229. > "USART_RXC_vect appears to be a misspelled signal handler". In Zeile > steht: ISR(USART_RXC_vect). Sollte das USART_RXC0_vect heißen? Es müsste > doch eine Include-Datei geben wo das definiert ist? Suche mal in <avr/io.h> dann kommst Du zum Ziel oder schaust im Datenblatt nach.
:
Bearbeitet durch User
Matthias W. schrieb: > hier der aktuelle Stand. make clean arbeitet (siehe make_clean.txt). > make all arbeitet (siehe make_all.txt und make_all.png) und erzeugt eine > Warnung in usart.c: Zeile 229. USART_RXC_vect appears to be a misspelled > signal handler. In der Zeile steht: ISR(USART_RXC_vect). Muss das > USART_RXC0_vect heißen? Warum probierst Du es nicht einfach aus? Was für einen µC hast Du denn? Der Source scheint jedenfalls für einen ATmega328 zu sein. Für diesen stimmt das so. Welche Version von avr-gcc benutzt Du? Die Version 4.8.1 hat die Macke, bei jeder ISR diesen Fehler auszugeben, obwohl es kein Fehler ist. Also: Welcher µC? > Weiter gibt es eine Fehlermeldung usart.o: In function USART_sendmsg: > C:\.... usart.c:255 undefined reference to ADC2RAW. > Der Fehler selbst ist klar. Die Funktion hatte ich auskommentiert. Ja, in adc.c. > Unklar ist warum der Fehler in der falschen Funktion gemeldet wird - 19 > Zeilen daneben. Ein Bug oder ein Feature? Füge doch mal in usart.c oben ein paar Leerzeilen ein und schaue dann, ob sich die Fehlermeldung zeilenmäßig verschiebt. Wenn nicht, dann liegt bei Dir noch irgendwo ein anderes usart.o rum.
Folgende Ursachen fallen mir noch ein: - Header, die nicht mit einem Zeilenumbruch enden. - Alte Compilerversion (4.3). Die älteste noch unterstützte GCC-Version ist die 4.8. WinAVR selbst ist (fast komplett) tot. - -Wl,--relax wirkt auch auf Debug-info und evtl. Adresszuordnungen. Wenn der Assembler bekannte Symboldifferenzen aufglöst hat, können diese vom Linker natürlich nicht mehr angepasst werden. --> -mrelax anstatt -Wl,--relax nebst hinreichend neuen avr-Tools. Mit -v überprüfen, ob as mit relax aufgerufen wird. Überprüf mal ob mit -save-temps -P die Zeilennummer zum .i stimmt.
Uwe S. schrieb: > Suche mal in <avr/io.h> dann kommst Du zum Ziel prima Hinweis Uwe. Diese io.h bindet die iom328p.h ein. Am Ende steht die Vektortabelle. Die hatte ich gesucht. Schade daß die so nicht im Datenblatt steht. > oder schaust im Datenblatt nach. da fand ich leider nichts brauchbares. Das was da stand hat nicht funktioniert.
Matthias W. schrieb: > Schade daß die so nicht im > Datenblatt steht. nicht schade, denn die hätte da nix zu suchen. "USART_RXC0_vect" ist schließlich nur ein Name, der für einen µC in jeder Programmierumgebung anders sein kann...
Frank M. schrieb: > Matthias W. schrieb: >> Es steht: ISR(USART_RXC_vect). Muss das USART_RXC0_vect heißen? > Warum probierst Du es nicht einfach aus? das habe ich gemacht. So kam ich recht zäh voran. Weder das eine noch das andere klappte. > Was für einen µC hast Du denn? den ATmega328p. Standardbestückung Arduino nano3. > Der Source scheint jedenfalls für einen ATmega328 zu sein. Für diesen > stimmt das so. das dachte ich auch. Nur leider . . . ich fand dann eine Datei group__avr__interrupts.html im WinAVR-Ordner. Da steht das drin was ich wissen wollte. > Welche Version von avr-gcc benutzt Du? avr-gcc (WinAVR 20100110) 4.3.3 wird gemeldet. > Die Version 4.8.1 > hat die Macke, bei jeder ISR diesen Fehler auszugeben, obwohl es kein > Fehler ist. ok. Macht es dann einen Sinn für mich ein neueres WINAVR anzustreben? > Füge doch mal in usart.c oben ein paar Leerzeilen ein und schaue dann, > ob sich die Fehlermeldung zeilenmäßig verschiebt. Wenn nicht, dann liegt > bei Dir noch irgendwo ein anderes usart.o rum. Danke für den Hinweis Frank ! Mit dem heutigen Stand wird der Fehler undefined reference to ADC2RAW in usart.c:252 gemeldet. Notepad++ zeigt Zeile 268 an. Das sind 16 Zeilen Differenz. Wenn ich oben 10 weitere Leerzeilen einfüge meldet er den Fehler in usart.c:262. Notepad++ zeigt Zeile 278 an. Also noch immer 16 Zeilen Differenz.
Johann L. schrieb: > Folgende Ursachen fallen mir noch ein: Danke Johann. > - Header, die nicht mit einem Zeilenumbruch enden. das war bei mir der Fall. Nun ist überall ein "LF" am Ende. Gebracht hat das nichts. > - Alte Compilerversion (4.3). meine ist die AVR GCC 4.3.3. > Die älteste noch unterstützte GCC-Version > ist die 4.8. WinAVR selbst ist (fast komplett) tot. schaut so aus als ob es momentan keine offizielle neue Fassung gibt? Im Wiki ist nichts dazu eingetragen. > - -Wl,--relax wirkt auch auf Debug-info und evtl. Adresszuordnungen. > Wenn der Assembler bekannte Symboldifferenzen aufglöst hat, können > diese vom Linker natürlich nicht mehr angepasst werden. > --> -mrelax anstatt -Wl,--relax nebst hinreichend neuen avr-Tools. > Mit -v überprüfen, ob as mit relax aufgerufen wird. Du meinst die Zeilen 75-78 im Makefile verändern? CFLAGS = -g -O$(OPT) \ -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ -Wall -Wstrict-prototypes \ -Wa,-adhlns=$(<:.c=.lst) \ > Überprüf mal ob mit -save-temps -P die Zeilennummer zum .i stimmt. Du meinst "-save-temps -P" bei den CFLAGS als neue Zeile hinzufügen?
Justus Skorps schrieb: > nicht schade, denn die hätte da nix zu suchen. "USART_RXC0_vect" ist > schließlich nur ein Name, der für einen µC in jeder Programmierumgebung > anders sein kann... ok. Das war das Schöne beim Assembler. Die Beispiele konnte man direkt nutzen.
Justus Skorps schrieb: > Matthias W. schrieb: >> Schade daß die so nicht im >> Datenblatt steht. > > nicht schade, denn die hätte da nix zu suchen. "USART_RXC0_vect" ist > schließlich nur ein Name, der für einen µC in jeder Programmierumgebung > anders sein kann... Es steht dafür in der Doku der avr-libc, wo es auch hingehört.
Oder per Einzeiler:
1 | $ echo | avr-gcc -mmcu=atmega328 -g3 -xc - -include avr/io.h -E -dM | grep _vect\b | sort |
Das ergibt, schön alphabetisch sortiert, und ohne Tippfehler in der Doku oder Inkonsistenz weil Atmel mal wieder aus Langeweile die IRQ-Namen geändert hat:
1 | #define ADC_vect _VECTOR(21)
|
2 | #define ANALOG_COMP_vect _VECTOR(23)
|
3 | #define EE_READY_vect _VECTOR(22)
|
4 | #define INT0_vect _VECTOR(1)
|
5 | #define INT1_vect _VECTOR(2)
|
6 | #define PCINT0_vect _VECTOR(3)
|
7 | #define PCINT1_vect _VECTOR(4)
|
8 | #define PCINT2_vect _VECTOR(5)
|
9 | #define SPI_STC_vect _VECTOR(17)
|
10 | #define SPM_READY_vect _VECTOR(25)
|
11 | #define TIMER0_COMPA_vect _VECTOR(14)
|
12 | #define TIMER0_COMPB_vect _VECTOR(15)
|
13 | #define TIMER0_OVF_vect _VECTOR(16)
|
14 | #define TIMER1_CAPT_vect _VECTOR(10)
|
15 | #define TIMER1_COMPA_vect _VECTOR(11)
|
16 | #define TIMER1_COMPB_vect _VECTOR(12)
|
17 | #define TIMER1_OVF_vect _VECTOR(13)
|
18 | #define TIMER2_COMPA_vect _VECTOR(7)
|
19 | #define TIMER2_COMPB_vect _VECTOR(8)
|
20 | #define TIMER2_OVF_vect _VECTOR(9)
|
21 | #define TWI_vect _VECTOR(24)
|
22 | #define USART_RX_vect _VECTOR(18)
|
23 | #define USART_TX_vect _VECTOR(20)
|
24 | #define USART_UDRE_vect _VECTOR(19)
|
25 | #define WDT_vect _VECTOR(6)
|
Oder mit
1 | ... | sort -n -k 2 -t( |
falls man Sortierung nach IRQ-Nummer bevorzugt. Und da im Jahre 2014 shell-Skripte bereits erfunden sind, muß man das auch nicht immer wieder eintippseln... Matthias W. schrieb: > Johann L. schrieb: >> Überprüf mal ob mit -save-temps -P die Zeilennummer zum .i stimmt. > > Du meinst "-save-temps -P" bei den CFLAGS als neue Zeile hinzufügen? Wo immer es deinem Makefile beliebt Optionen an den Compiler zu reichen. Oder das komplette Kommando per Hand eingeben — zum Beispiel bei esotherischen Plattformen, die nicht erlauben die Compileroptionen zu ändern.
Justus Skorps schrieb: > nicht schade, denn die hätte da nix zu suchen. "USART_RXC0_vect" ist > schließlich nur ein Name, der für einen µC in jeder Programmierumgebung > anders sein kann... USART ist ein ziemlich eingebügerter Begriff. Der steht auch so im Datenblatt. RXCO ist so wunderlich auch nicht. Steht auch im Datenblatt. _vect. Deutet auf einen Vektor hin.
Rolf Magnus schrieb: >> "USART_RXC0_vect" .. > Es steht dafür in der Doku der avr-libc, wo es auch hingehört. Danke für den Hinweis Magnus. Dazu gehört laut http://nongnu.org/avr-libc/user-manual/modules.html zum Thema Interrupts <avr/interrupt.h>. Dies führt zu http://nongnu.org/avr-libc/user-manual/group__avr__interrupts.html. Das war das was ich auch gefunden hatte. Im Usermanual der avr-libc http://nongnu.org/avr-libc/user-manual/ steht auch etwas von Startup-Code: "The AVR Libc package.. provides the basic startup code needed by most applications." Startup-Code hatte ich selbst in die main.c geschrieben. Welche include-Datei hätte ich dazu nehmen sollen?
Johann L. schrieb: >
1 | > $ echo | avr-gcc -mmcu=atmega328 -g3 -xc - -include avr/io.h -E -dM | |
2 | > grep _vect\b | sort |
vielen Dank Johann für den prima Hinweis ! Das ist ja toll wenn man das so herausbekommen kann. Genial.
Matthias W. schrieb: > Startup-Code hatte ich selbst in die main.c geschrieben. Welche > include-Datei hätte ich dazu nehmen sollen? warum sollte man für den Startup-Code eine include brauchen? Das ist mehr teil vom linker, er führ noch ein paar befehle vor main aus und initialisiert damit globale Variablen. Wie hast du denn so etwas selber geschrieben?
Johann L. schrieb: >>> Überprüf mal ob mit "-save-temps -P" die Zeilennummer zum .i stimmt. Habe ich gemacht Johann: ohne diese Zutaten im Makefile wird undefined reference in Zeile 278 gemeldet. Der Fehler steht in Zeile 294. mit den Zutaten im Makefile wird beim Linken gemeldet: uart.o: In function USART_Tx_msg usart.i:207 undefined reference to ADC2RAW. Die gemeldete Funktion ist falsch und die Zeilennummer passt nicht zur usart.c. In der neu entstandenen Datei usart.i ist die Zeile 207 die letzte Zeile der Funktion USART_Tx_msg (die Klammer zu).
die positive Nachricht: Der ADC wandelt nun rasch (~alle 104us vermutlich) 500 ADC-Werte in Folge ins RAM. Die Werte werden dann per UART mit 115kbd als Integer zum PC geschickt. Das läuft - die Werte sehen recht plausibel aus. Damit habe ich nun den Anstieg der Zeitbasis erfasst.
Peter II schrieb: > warum sollte man für den Startup-Code eine include brauchen? was ist überhaupt gemeint mit "Startup-Code"? Warum steht dazu etwas in der avr-libc? > Das ist > mehr teil vom linker, er führ noch ein paar befehle vor main aus und > initialisiert damit globale Variablen. Wie hast du denn so etwas selber > geschrieben? dann verstehen wir da unterschiedliches darunter. Ich verstand unter "Startup-Code" das Festlegen bestimmter Register damit der Chip brauchbar arbeiten kann mit der Beschaltung die er hat. Offenbar ist der "Startup"-Code etwas was der Compiler für sich selbst benutzt. Damit habe ich als User also nichts zu tun.
Matthias W. schrieb: > Offenbar ist der "Startup"-Code etwas was der Compiler für sich selbst > benutzt. Ja. Aber nicht nur. Startup-Code ist alles, was notwendig ist, damit main überhaupt arbeiten kann. Auf einem Embedded System ohne dahinter liegendes Betriebssystem gehört da zb auch die Initialisierung eines Stack-Pointers dazu, sofern die CPU so etwas hat. Initialisierung der MMU, um ein anderes Beispiel zu nennen. Kurz und gut: alles, was im Vorfeld ablaufen muss, damit main() eine gesicherte Arbeitsumgebung vorfindet. Gibt es kein Betriebssystem, dann umfasst der Startup Code natürlich auch die Teile, die ein Betriebssystem beim Hochfahren erledigt um den Computer als ganzes sauber 'hochzufahren'. OK, auf einem AVR ist das nicht viel, ändert aber nichts am Prinzip.
:
Bearbeitet durch User
Karl Heinz schrieb: > Startup-Code ist alles, was notwendig ist, damit main überhaupt arbeiten > kann. Auf einem Embedded System ohne dahinter liegendes Betriebssystem > gehört da zb auch die Initialisierung eines Stack-Pointers dazu, ok. Danke Karl-Heinz. Bei meinem Assembler-Programm für ATmega8535 hatte ich den Stack in den ersten Zeilen belegt. Im C-Code des AVR-Butterfly fand ich nichts dazu. Beim Arduino nano3 mit ATmega328p soll der Stack sinnvoll vorbelegt sein nach Reset. Also dazu nichts nötig. > sofern die CPU so etwas hat. der ATmega 328 hat einen Stack und auch eine Menge andere Register, die man nicht immer in der default-Stellung belassen möchte. > Initialisierung der MMU, um ein anderes Beispiel zu nennen. Ähnliches wie init ADC, UART rufe ich in der main.c mit Hilfe von eigenen Initialisierroutinen auf. Im Assembler gab es auch eine Initialisierung. Auch der Watchdog gehört ggf. dazu. Bisher habe ich ihn ignoriert. Vermutlich ist er über eine Fuse deaktiviert. > Kurz und gut: alles, was im Vorfeld ablaufen muss, damit > main() eine gesicherte Arbeitsumgebung vorfindet. so sah ich das auch. > OK, auf einem AVR ist das nicht viel, ändert aber nichts am Prinzip. ok. Danke !
Matthias W. schrieb: > Johann L. schrieb: >>>> Überprüf mal ob mit "-save-temps -P" die Zeilennummer zum .i stimmt. > > Habe ich gemacht Johann: > ohne diese Zutaten im Makefile wird undefined reference in Zeile 278 > gemeldet. Der Fehler steht in Zeile 294. > > mit den Zutaten im Makefile wird beim Linken gemeldet: uart.o: In > function USART_Tx_msg usart.i:207 undefined reference to ADC2RAW. > > Die gemeldete Funktion ist falsch und die Zeilennummer passt nicht zur > usart.c. Die Meldung bezieht sich auf uart.i, nicht auf uart.c. Vergleiche also die Meldung für uart.i mit uart.i, nicht mit uart.c ;-) > In der neu entstandenen Datei usart.i ist die Zeile 207 die > letzte Zeile der Funktion USART_Tx_msg (die Klammer zu). Dann kann die Zeile nicht mehr bestimmt werden; in dem Fall ist die Angezeigte Stelle dann das Ende der Funktion; üblicherweise die schließende }. Ist mit der Location für die C-Datei wohl auch so.
:
Bearbeitet durch User
Johann L. schrieb: > Die Meldung bezieht sich auf uart.i, nicht auf uart.c. Vergleiche also > die Meldung für uart.i mit uart.i, nicht mit uart.c ;-) das habe ich gemacht Johann. >> In der neu entstandenen Datei usart.i ist die Zeile 207 die >> letzte Zeile der Funktion USART_Tx_msg (die Klammer zu). leider wird auch in usart.i der Fehlerort scheinbar falsch gemeldet. Ich verstehe den Mechanismus nicht nach dem dies geschieht. > Dann kann die Zeile nicht mehr bestimmt werden; in dem Fall ist die > Angezeigte Stelle dann das Ende der Funktion; üblicherweise die > schließende }. die Fehlermeldung hat mit der Funktion USART_Tx_msg nichts zu tun. > Ist mit der Location für die C-Datei wohl auch so. auch in der C-Datei wird das Ende der Funktion USART_Tx_msg als Fehlerort angegeben. Dasselbe Problem also.
:
Bearbeitet durch User
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.