Forum: Compiler & IDEs ATtiny2313A: GCC Funktionsaufruf nicht erfolgreich


von mole (Gast)


Lesenswert?

Hallo zusammen,

ich versuche mich gerade an der Inbetriebnahme eines ATtiny2313A mit 
Atmel Studio 6.0. Ich kann über den AVR Dragon und ISP (wahlweise auch 
DEBUGwire) den AVR beschreiben und auch debuggen.

Jetzt habe ich ein kleines Programm geschrieben mit einer einzigen 
Funktion. sobald diese aufgerufen wird und fertig durchlaufen ist, 
springt der AVR direkt an den Anfang von main und startet quasi von neu. 
Irgendwann nach einigen Iterationen scheint er abzustürzen und nur ein 
Reset hilft.

Woran könnte es liegen? Auf mich wirkt es so, als wenn der Rücksprung 
nicht richtig funktioniert. Ich habe gelesen, dass es ein bekanntes 
Problem mit einer Fuse M103 bei den größeren AVRs gibt. Aber diese Fuse 
gibt es bei dem ATtiny2313A nicht. Habt Ihr eine Idee?

Danke für Eure Mithilfe
Mole

Hier der Code:
---8< Schnipp 8< ---------------------
#include <avr/io.h>
#include <avr/interrupt.h>  // Wird nur gebraucht bei der 
Interrupt-Version

int turnOn()
{

  PORTB |= (1<<2); // LED 3
  return 0;
}

int main()
{

  DDRB = 0xFF;
  PORTB |= (1<<4); // LED 2
  turnOn();

  return 0;
}
---8< Schnapp 8< ---------------------

von Cyblord -. (cyblord)


Lesenswert?

Und wieder einmal liegt das Problem NICHT in dem Code den du uns zeigst. 
Denn dieser Code wird funktionieren. Nur wenn ich sehe dass du da 
irgendwo noch Interrupts verwendest, dann denke ich liegt es vielleicht 
an einem Sprung in eine nicht vorhandene ISR, dass dein Controller neu 
startet.

gruß cyblord

von Achim M. (minifloat)


Lesenswert?

Wo ist die Mainloop?
Wieviel Stack ist schon im Ram?
Wieviel statische Daten liegen bis zum funktionsaufruf im Ram?

von Marian O. (marian_o)


Lesenswert?

Guten Abend Cyblord,

die Interrupts sollten nicht aktiviert sein, der Include kann also 
entfernt werden.

Wie kann ich prüfen, ob die Interrupts - wie Du schreibst - einen Sprung 
in eine nicht vorhandene ISR starten?

Gruß Mole

von Cyblord -. (cyblord)


Lesenswert?

Marian O. schrieb:
> Guten Abend Cyblord,
>
> die Interrupts sollten nicht aktiviert sein, der Include kann also
> entfernt werden.
>
> Wie kann ich prüfen, ob die Interrupts - wie Du schreibst - einen Sprung
> in eine nicht vorhandene ISR starten?
>
> Gruß Mole

Das kannst du nicht prüfen, du sollst sicherstellen dass keine 
Interrupts angeschaltet sind, für die es keine ISR gibt. Wenn du sicher 
Das I-Bit abgeschaltet hast, dann kann ja auch kein Interrupt auftreten.

Trotzdem, poste den ganzen Code. Dieser Fetzen hier bringt absolut nix. 
Und setze mal ein while(1); vor das return in der main. Der gcc müsste 
zwar eigentlich, nach dem Ende des Programmes, eine solche Schleife 
automatisch anfügen, aber trotzdem...

gruß cyblord

von Marian O. (marian_o)


Lesenswert?

Hallo Minifloat,

Statische Daten:
Program Memory Usage   :  116 bytes   5,7 % Full
Data Memory Usage :  0 bytes   0,0 % Full

Das Stackfenster fehlt hier gerade und ich finde die Einstellung im 
Atmel Studio nicht, um es wieder einzublenden...

Der Stackpointer steht allerdings bei 0xDD

von Marian O. (marian_o)


Lesenswert?

Cyblord,

vielen Dank. Ich habe einen frischen von der "Stange" genommen und der 
funktioniert. Das gesetzte Interrupt-Bit müsste ich allerdings in der IO 
View finden, oder?

Gibt es eine Möglichkeit, den AVR mit dem High-Voltage-Programmer 
irgendwie komplett in den Auslieferungszustand zurückzusetzen?

Gruß
Mole

von Cyblord -. (cyblord)


Lesenswert?

Marian O. schrieb:
> Cyblord,
>
> vielen Dank. Ich habe einen frischen von der "Stange" genommen und der
> funktioniert. Das gesetzte Interrupt-Bit müsste ich allerdings in der IO
> View finden, oder?

Keine Ahnung von welcher IO View du redest. Ich nutze z.B. Eclipse. 
Nicht jeder arbeitet mit dem AVR-Studio oder sonst was, also solltest du 
deine Tools schon irgendwie dazusagen.
Aber das I-Bit ist nach jedem Reset 0 (wie im Datenblatt beschrieben) 
und man muss es schon mit einem SEI Aufruf explizit setzen. Also 
solltest du schon wissen ob dein Programm dieses Bit setzt oder nicht. 
Immerhin hast du es ja geschrieben oder?

>
> Gibt es eine Möglichkeit, den AVR mit dem High-Voltage-Programmer
> irgendwie komplett in den Auslieferungszustand zurückzusetzen?

Nein wozu denn? Was gibt es denn schon an persistenten Daten die man da 
zurücksetzen will? 3 Fuse-Bytes, den FLash und den EEPRom. Und der Flash 
wird bei jedem programmieren gelöscht. EEPRom meist auch. Also, das ist 
nicht nötig.
Wieso überprüfst du deinen "defekten" Chip nicht einfach mal schnell, ob 
da irgendwelche Fuses verstellt sind, und machst eine Chip Erase und 
haust das Programm nochmal drauf? Zu einfach?

Dein Problem liegt woanders, ka wo.

gruß cyblord

von ich (Gast)


Lesenswert?

> Dein Problem liegt woanders, ka wo.
da:
> Wo ist die Mainloop?

von Cyblord -. (cyblord)


Lesenswert?

ich schrieb:
>> Dein Problem liegt woanders, ka wo.
> da:
>> Wo ist die Mainloop?

Nö. Braucht man nicht. Macht der gcc alleine.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

cyblord ---- schrieb:

>>> Wo ist die Mainloop?
>
> Nö. Braucht man nicht. Macht der gcc alleine.

Naja.  Nicht wirklich fürs praktische Leben empfehlenswert.  Das
ist keine Mainloop, sondern die Funktion _exit(), die da in einer
Endlosschleife rumrennt.  Mittlerweile schaltet sie meiner Meinung
nach aber dafür die Interrupts ab, was sie für alle praktischen
Belange als Mainloop untauglich macht.

Eine leere Mainloop kann ja durchaus guter Programmierstil sein
(alles wird von den Interrupts erledigt), allerdings ist dann noch
besser diese hier:
1
...
2
   for (;;) {
3
      sleep_mode();
4
   }

von Cyblord -. (cyblord)


Lesenswert?

Jörg Wunsch schrieb:
> cyblord ---- schrieb:

>
> Eine leere Mainloop kann ja durchaus guter Programmierstil sein
> (alles wird von den Interrupts erledigt), allerdings ist dann noch
> besser diese hier:

1.) _exit reicht aus damit das Programm stehen bleibt und eben der 
Controller nicht dauernd neu startet. Mehr will der TE momentan einfach 
nicht.

2.) Ich hatte ihm doch bereits geraten eine extra while(1) einzubauen. 
Irgendwelche sleep Spitzfindigkeiten sind doch hier gar nicht von 
Belang.

gruß cyblord

von Mole (Gast)


Lesenswert?

Servus zusammen,

vielen Dank für Eure Antworten, die Lösung des Problems war der AVR 
DRAGON Programmer.

Nachdem ich die ISP Leitung verkürzt und einen zusätzlichen ELKO auf den 
DRAGON zur Spannungsstabilisierung aufgelötete habe, hat es einwandfrei 
funktioniert.

Gruß
Mole

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.