Forum: Mikrocontroller und Digitale Elektronik Eclipse kompiliert Code nicht wer findet den Fehler?


von White Rabbit (Gast)


Lesenswert?

Hallo.
Ja, das ist kein neues Problem ... aber ich weiß nicht, warum es nicht 
klappt und hoffe, dass mir hier jemand einen Tipp geben kann....

Ich wollte dieses kleine Projekt kompilieren:
https://www.elektormagazine.com/articles/tiny-dice/6845
(in der PDF-Datei unten steckt der Sourcecode)

Dort steht auch, dass man es mit WinAVR (bzw der zugehörigen Toolchain) 
kompilieren kann ... das klappt aber nicht: Ein "[WinAVR] Make all" im 
Progammers Notepad liefert nur: "make.exe: No rule to make target "all". 
Stop"

Danach habe ich es unter Eclipse ausprobiert. Auch da klappt das 
Compilieren nicht (Neues C-Projekt erstellt usw ...) danach "Project --> 
Build All". Meldung:
---------------------------------
[...]
 ISR (PCINT_B_vect)
      ^
In file included from ../main.c:9:0:
/usr/lib/avr/include/util/delay.h:164:28: error: 
__builtin_avr_delay_cycles expects a compile time integer constant
  __builtin_avr_delay_cycles(__ticks_dc);
                            ^
make: *** [main.o] Error 1
----------------------------------

Was läuft da schief? Eigentlich gehe ich mal davon aus, dass der Code so 
wie er da abgedruckt ist, funktionieren müsste?!?

Danke für einen hilfreichen Tipp!

von Peter II (Gast)


Lesenswert?

White Rabbit schrieb:
> Eigentlich gehe ich mal davon aus, dass der Code so
> wie er da abgedruckt ist, funktionieren müsste?!?

macht er aber nicht.

_delay_ms(i*3);

ist nicht zulässig.

schreibe ein neue Funktion und rufe sie auf.
1
_delay_ms(i*3);   -> MyDelayMS(i*);
2
3
void MyDelayMS(int i ) 
4
{
5
while( i--) {
6
  _delay_ms(1);
7
}
8
}

von Christopher B. (chrimbo) Benutzerseite


Lesenswert?

Peter II schrieb:
> _delay_ms(i*3);

Zulaessig schon, aber es dauert nicht wie suggeriert 3 mal i 
Millisekunden, sondern deutlich laenger. Es sei denn der gcc wuerde hier 
Loop unrolling machen, dann waere i*3 ja vorausberechenbar...

Was aber viel schlimmer ist, dass ueberhaupt in der ISR gewartet wird. 
Und dann auch noch fuer 2340ms wenn ich mich nicht verrechnet habe.

von Christopher B. (chrimbo) Benutzerseite


Lesenswert?

White Rabbit schrieb:
> ISR (PCINT_B_vect)

Achso zu deinem eigentlichen Problem. Hast du vielleicht den Tiny2313 
ausgewaehlt? Der hat naemlich keinen PCINT_B_vect sondern nur PCINT_vect

von White Rabbit (Gast)


Lesenswert?

Nein, ich habe den tiny2313A ausgewählt. Ging aber trotzdem nicht.

Und warum läuft es unter WinAVR überhaupt nicht?? Mir fehlen die 
Basics .... aber offenbar ist es falsch, einfach eine Datei "main.c" 
anzulegen und zu hoffen, dass sie kompiliert wird??

Eclipse hat es ja immerhin angefangen und dann mit Fehlern abgebrochen 
-- immerhin!

von Peter II (Gast)


Lesenswert?

White Rabbit schrieb:
> Und warum läuft es unter WinAVR überhaupt nicht??

wissen wir nicht, irgendwo muss doch ein Fehler kommen. Was geht genau 
dort nicht?

von Christopher B. (chrimbo) Benutzerseite


Lesenswert?

White Rabbit schrieb:
> aber offenbar ist es falsch, einfach eine Datei "main.c"
> anzulegen und zu hoffen, dass sie kompiliert wird??

Oh, ich hab deinen Eingangspost nicht vollstaendig gelesen.

White Rabbit schrieb:
> Ein "[WinAVR] Make all" im
> Progammers Notepad liefert nur: "make.exe: No rule to make target "all".
> Stop"

Ich wuerde sagen du hast kein Makefile

White Rabbit schrieb:
> Neues C-Projekt erstellt

Hast du in eclipse das AVR Plugin installiert?
Sonst weiss eclipse doch gar nicht, welchen Compiler du nutzen willst. 
Und da muss auch das Symbol _AVR_ATtiny2313A_ definiert sein.

von White Rabbit (Gast)


Lesenswert?

WinAVR:
Kein Makefile klingt gut .... ich frage mich dann nur, warum beim 
Sourcecode keins dabei ist bzw wo/wie ich eins erzeugen kann/muss??

Elcipse:
Klar, das AVR-Plugin ist installiert (hier Mars mit AVR-Plugin 2.4.2).
Gerade nochmal ganz neu angefangen und nochmal explizit auf
tiny2313a geachtet:

New C-Project -> dann "New File" --> "main.c" angelegt und da den 
Sourcecode eingefügt. Danach auf "Build all (STRG+B)"

Meldung dieses Mal:
-------------------------------------
14:30:20 **** Incremental Build of configuration Release for project 
Dice ****
make all
Building target: Dice.elf
Invoking: AVR C Linker
avr-gcc -Wl,-Map,Dice.map -mmcu=attiny2313a -o "Dice.elf"  ./main.o
/usr/lib/gcc/avr/4.8.2/../../../avr/bin/ld: cannot find crttn2313a.o: No 
such file or directory
collect2: error: ld returned 1 exit status
make: *** [Dice.elf] Error 1

14:30:20 Build Finished (took 71ms)
----------------------------------------
Verstehe ich nicht ... der Einstieg ist leider nicht sooooooo leicht :(

von White Rabbit (Gast)


Lesenswert?

Nachtrag:
locate crttn2313a.o
 --> /usr/lib/avr/lib/avr25/crttn2313a.o
Die Datei ist also da!

von beric (Gast)


Lesenswert?

White Rabbit schrieb:
> Kein Makefile klingt gut .... ich frage mich dann nur, warum beim
> Sourcecode keins dabei ist bzw wo/wie ich eins erzeugen kann/muss??

Wie schwierig ist es "make makefile" in Guggl einzutippen?

von Peter II (Gast)


Lesenswert?

White Rabbit schrieb:
> Kein Makefile klingt gut .... ich frage mich dann nur, warum beim
> Sourcecode keins dabei ist bzw wo/wie ich eins erzeugen kann/muss??

weil man es fürs Atmel-Studio nicht braucht.

von White Rabbit (Gast)


Lesenswert?

Ok, mir wäre es aber eh lieber, wenn es unter eclipse auch liefe.
Da scheint das makefile ja "im Hintergrund" selbst erzeugt zu werden?

Die Fehlermeldung bringt mich aber weiterhin nicht weiter :(

(Ach ja: In dem Elektor-Artikel wird explizit von WinAVR und eben NICHT 
von Atmel Studio gesprochen ... daher habe ich es natürlich auch damit 
(erfolglos) versucht...)

von Karl H. (kbuchegg)


Lesenswert?

White Rabbit schrieb:
> Nachtrag:
> locate crttn2313a.o
>  --> /usr/lib/avr/lib/avr25/crttn2313a.o
> Die Datei ist also da!

Und dein Eclipse bzw. das Plugin wissen auch, WO sich die gesuchte Lib 
befinden?

Genau das scheint das Problem zu sein. Irgendetwas ist in deiner 
Konfiguration faul.

von Karl H. (kbuchegg)


Lesenswert?

White Rabbit schrieb:

> (Ach ja: In dem Elektor-Artikel wird explizit von WinAVR und eben NICHT
> von Atmel Studio gesprochen ... daher habe ich es natürlich auch damit
> (erfolglos) versucht...)

WinAVR ist aber nicht Eclipse.
WinAVR im eigentlichen Sinne heisst nur, dass man den COmpiler von Hand 
aus einer Command Line heraus aufruft. Das kann man machen, auch wenn es 
heutzutage keiner macht. Den Hinweis auf WinAVR kannst du also 
eigentlich nur dazu benutzen, dass hier der gcc benutzt wird und sich 
die C-Syntax Erweiterungen auf diesen Compiler beziehen und nicht zb auf 
einen IAR Compiler.

Der/die Autoren gehen eben davon aus, dass derjenige wenigstens 
rudimentäre Kentnisse seiner Entwicklungsumgebung hat bzw. schon 
mindestens einmal damit etwas erfolgreich brennfertig übersetzt hat.

von White Rabbit (Gast)


Lesenswert?

> WinAVR ist aber nicht Eclipse.
Schon klar. WinAVR läuft hier in einer WinXP-VirtualBox ...
Eclipse direkt unter Linux

> Der/die Autoren gehen eben davon aus, dass derjenige wenigstens
> rudimentäre Kentnisse seiner Entwicklungsumgebung hat bzw. schon
Das merke ich auch gerade ...


Nochmal Eclipse: Wo sehe ich bzw stelle ich es ein, ob der Compiler die 
Libs kennt? Ist es richtig:
Rechtsklick auf main.c --> Properties --> C/C++ General --> Paths & 
Symbols?
Oder wie/wo geht das sonst?

Bei mir tauchen dort auf:
GNU C /usr/lib/gcc/avr/4.8.2/include
      /usr/lib/gcc/avr/4.8.2/incluce-fixed
      /usr/lib/avr/include

von hp-freund (Gast)


Lesenswert?

Hallo,

es scheint in der Tat ein Problem mit der crttn2313a.o zu geben.
Wenn Du einen link dieser Datei von:

/usr/lib/avr/lib/avr25/crttn2313a.o

nach

/usr/lib/avr/lib/crttn2313a.o

erstellst und die delay Probleme wie ober erklärt korrigierst 
funktioniert es.

von White Rabbit (Gast)


Lesenswert?

Also Atmel Studio (hier noch Version 4!) compiliert es tatsächlich (mit 
nur einer Warnung!). Ein erster Erfolg!

Eclipse:
Kann es sein, dass da oben ein Syntax-Fehler in der Zeile
_delay_ms(i*3);   -> MyDelayMS(i*);
ist? Ich erhalte da ein Fragezeichen mit der Meldung:

Multiple markers at this line
  - Line breakpoint: test.c [line: 52]
  - Syntax error

von beric (Gast)


Lesenswert?

Soll sein

  MyDelayMS(i);

von White Rabbit (Gast)


Lesenswert?

Sorry ... aber jetzt bekomme ich:

_delay_ms(i*3);   ->  MyDelayMS(i);

void MyDelayMS(int i )
{
while( i--) {
  _delay_ms(1);
}
}

------------------------------------
avr-gcc -Wall -Os -fpack-struct -fshort-enums -ffunction-sections 
-fdata-sections -std=gnu99 -funsigned-char -funsigned-bitfields 
-mmcu=attiny2313a -DF_CPU=1000000UL -MMD -MP -MF"test.d" -MT"test.d" -c 
-o "test.o" "../test.c"
../test.c: In function ‘__vector_11’:
../test.c:52:19: error: expected expression before ‘->’ token
 _delay_ms(i*3);   ->  MyDelayMS(i*);
                   ^
make: *** [test.o] Error 1
-------------------------------------

von hp-freund (Gast)


Lesenswert?

White Rabbit schrieb:
> expected expression before ‘->’ token

Denk mal nach ob das C sein kann ;-)

von Karl H. (kbuchegg)


Lesenswert?

White Rabbit schrieb:
> Sorry ... aber jetzt bekomme ich:
>
> _delay_ms(i*3);   ->  MyDelayMS(i);

Du sollst die Zeile
1
  _delay_ms(i*3);

durch die Zeile
1
  MyDelayMS(i);

ERSETZEN und nicht einfach nur den neuen Text dazu schreiben.

Ein wenig mitdenken musst du schon. Sonst wird das nichts mit dem 
Programmieren.

von Mathias O. (m-obi)


Lesenswert?

Mensch du sollst
_delay_ms(i*3);
durch
MyDelayMS(i);
ersetzen.

von White Rabbit (Gast)


Lesenswert?

Ja, auch das habe ich schon ausprobiert ... einfach nur:

MyDelayMS(i);

void MyDelayMS(int i )
{
while( i--) {
  _delay_ms(1);
}
}

Und siehe da:
-----------------------
make all
Building file: ../test.c
Invoking: AVR Compiler
avr-gcc -Wall -Os -fpack-struct -fshort-enums -ffunction-sections 
-fdata-sections -std=gnu99 -funsigned-char -funsigned-bitfields 
-mmcu=attiny2313a -DF_CPU=1000000UL -MMD -MP -MF"test.d" -MT"test.d" -c 
-o "test.o" "../test.c"
../test.c: In function ‘__vector_11’:
../test.c:52:1: warning: implicit declaration of function ‘MyDelayMS’ 
[-Wimplicit-function-declaration]
 MyDelayMS(i);
 ^
../test.c:54:6: warning: conflicting types for ‘MyDelayMS’ [enabled by 
default]
 void MyDelayMS(int i )
      ^
../test.c:54:6: error: static declaration of ‘MyDelayMS’ follows 
non-static declaration
../test.c:52:1: note: previous implicit declaration of ‘MyDelayMS’ was 
here
 MyDelayMS(i);
 ^
make: *** [test.o] Error 1

17:55:08 Build Finished (took 75ms)
----------------------------------------------
Weiterhin also kein Erfolg.

von Mathias O. (m-obi)


Lesenswert?

Du hast keinen Header. Also musst du sie noch am Anfang definieren. Und 
welchen Typ hat die Variable, welche du der Funktion übergibst?

von Karl H. (kbuchegg)


Lesenswert?

White Rabbit schrieb:


und jetzt ziehst du die Definition der Funktion

> void MyDelayMS(int i )
> {
> while( i--) {
>   _delay_ms(1);
> }
> }

vor die erste Verwendung.

Der Compiler liest den Code von oben nach unten.
Ehe du etwas verwenden kannst, muss es zuerst deklariert werden.
Sonst zuzelt sich der Compiler aus der Verwendung raus, wie die Funktion 
wohl aussehen wird. Und wie das nun eben bei Annahmen ist, kann das 
manchmal auch falsch sein.

von Karl H. (kbuchegg)


Lesenswert?

White Rabbit schrieb:

> Weiterhin also kein Erfolg.

Da du jetzt über das Stadium der Einrichtung der Entwicklungsumgebung 
hinaus bist:
Mit einem C-Buch und erlernen der Programmiersprache, würdest du deine 
Erfolgswahrscheinlichkeit drastisch erhöhen.

von Karl H. (kbuchegg)


Lesenswert?

Karl H. schrieb:

> Sonst zuzelt sich der Compiler aus der Verwendung raus, wie die Funktion
> wohl aussehen wird.

Nichts anderes sagt dir der Compiler hier
1
  .... warning: implicit declaration of function ‘MyDelayMS’

das 'implicit' ist hier der Schlüssel. Es bedeutet soviel wie: Ich habe 
Standardannahmen getroffen, so wie es die C Regeln vorsehen.

> Und wie das nun eben bei Annahmen ist, kann das
> manchmal auch falsch sein.

und das sagt er dir hier
1
.... conflicting types for ‘MyDelayMS’ ....

Im Klartext: leider sind die Standardannahmen falsch gewesen. Die passen 
nicht zu
1
void MyDelayMS(int i )
2
{
3
  while( i--) {
4
    _delay_ms(1);
5
  }
6
}

: Bearbeitet durch User
von hp-freund (Gast)


Lesenswert?

Mal ganz einfach gedacht:
1
_delay_ms(i*3);

wird zu:
1
uint8_t j;
2
for(j=0;j<=i*3;j++) _delay_ms(1);

und das
1
_delay_ms(100);

wird zu _delay_ms(1); und die Schleife wird nicht 300 mal sondern 30000 
mal durchlaufen.

von Karl H. (kbuchegg)


Lesenswert?

Es kann natürlich auch sein, dass der originale Autor die 
'unabsichtliche Verlängerung' der Zeiten durch die Nichtverwendung einer 
Konstanten mehr oder weniger gewollt in den Code eingebaut hat, indem er 
den Faktor 3 empirisch bestimmt hat, bis ihm die Geschwindigkeit 
zugesagt hat.

Das kann jetzt dazu führen, dass die eigentlich richtige Korrektur 
dieses Fauxpas dazu führt, dass das Timing jetzt nicht mehr stimmt. Also 
darauf vorbereitet sein, dass das Ausrollen des Würfels jetzt unter 
Umständen nicht ganz so abläuft, wie erwartet.

: Bearbeitet durch User
von hp-freund (Gast)


Lesenswert?

Und dann noch das delay in der ISR.

Das ganze Projekt sollte nur als Rahmen für ein eigenes dienen...

von Nil (Gast)


Lesenswert?

Wenn du per make compilieren willst, brauchst du ein makefile. Da du 
aber anscheinend von make keine Ahnung hast, solltest du das wohl am 
besten sein lassen (obwohl das mit ein bisschen Google-Hilfe wahrlich 
kein Hexenwerk ist).

Was du da mit der neuen delay-Funktion angestellt hast deutet zudem auch 
darauf hin, dass du allgemein von C nicht wirklich viel Ahnung hast.
Am besten setzt du einfach ein neues Projekt im Atmel/AVR Studio deiner 
Wahl auf, kopierst den Code in die Main.c und verbesserst o.g. 
delay-Fehler (und zwar so, wie es dir Karl Heinz oben erklärt hat). Dann 
sollte das eigentlich auch problemlos laufen.

von Karl H. (kbuchegg)


Lesenswert?

hp-freund schrieb:
> Und dann noch das delay in der ISR.
>
> Das ganze Projekt sollte nur als Rahmen für ein eigenes dienen...

Yep.
Das Programm ist trotz seiner Einfachheit ziemlich mies aufgebaut. Genau 
verkehrt herum. Die Würfellogik hätte ins main gehört und die 
Zeitabschaltung in eine Timer-ISR (wenn man sie nicht in main macht, was 
in diesem Fall auch gegangen wäre). Da sieht man wieder, wo diese 
'Taster werden per Interrupt ausgewertet'-Denke hinführt.

Tasterkontakte per Kondensator einfach kurzschliessen ist auch nicht die 
feine englische Art.

Elektor eben.

von Red Dragon (Gast)


Lesenswert?

White Rabbit schrieb:
> Also Atmel Studio (hier noch Version 4!) compiliert es tatsächlich (mit
> nur einer Warnung!).

Atmel Studio 4 gibt es gar nicht. AVR Studio 4.19 war die letzte Version 
unter dem Namen.

Dann kam Atmel Studio 6.0

von White Rabbit (Gast)


Lesenswert?

Ok, jetzt läuft es.
Danke für die Tipps ... ich komme um einen gescheiten C-Kurs offenbar 
nicht herum. "Einfach so" lernt man das jedenfalls nicht :(

Schön, dass es sich jetzt unter Eclipse und unter AVR Studio 4 
compilieren läßt. Auf das makefile und das Programmers Notepad verzichte 
ich jetzt mal. Andererseits hat Eclipse ja ein makefile unter "Release" 
angelegt -- müsste man doch verwenden können, oder?

Ich habe übrigens die absolut notwendige Option "Save automatically 
before build" unter Eclipse eingestellt ... vorher hatte ich mich immer 
über Meldungen gewundert, die eigentlich gar nicht mehr hätten 
auftauchen dürfen. Von allen LaTeX-Editoren bin ich es so gewohnt, dass 
automatisch gespeichert wird; daher auch hier ein absolutes Muss, finde 
ich! ... Warum das nicht per default so ist, weiß ich nicht!?

Was den Aufbau des Codes angeht: Kann ich natürlich nichts zu sagen. Ich 
hatte es mir nur ausgesucht, da es ein einfaches Projet zu sein schien 
und ich mal versuchen wollte, etwas zu compilieren und anschließend zu 
brennen. avrdude macht hier aber keine Probleme! Das habe ich schon ein 
paar Mal erfolgreich benutzt...

Übrigens ist es bei dem "Original-Würfel", den ich von Elektor als 
Werbegeschenk erhalten habe, so, dass das Erwürfeln des Ergebnisses 
durchaus etwas Zeit kostet ... vielleicht daher die genannten 3 
Sekunden?

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.