ATtiny2313A: GCC Funktionsaufruf nicht erfolgreich

Gast #2830481
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< ---------------------
#2830486
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
#2830500
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
#2830519
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
#2830534
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
Moderator Persönliche Seite #2830843
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
   }
#2830943
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
Gast #3525906
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren