Forum: Compiler & IDEs Abstürzender Controller?


von Tobias (Gast)


Lesenswert?

Hallo allerseits,

für einen Kunden hab' ich eine Schaltung mit einem Tiny861 /AVR GCC 
entwickelt und nächste Woche will er diese in einem Gerät ausstellen, 
doch irgendwo ist der Wurm drin.
Das Programm auf dem Controller scheint abzustürzen und zwar auf eine 
Art und Weise, die ich mir nicht aufgrund eines möglichen Fehlers im 
Code erklären kann.
Das kleine Segment unten zeigt einen Code- Ausschnitt.
Irgendwo im Programm wird ein Buzzer angesteuert, der eine Tonfolge 
ausgibt. Der Aufruf der beiden "play_tone" Funktionen erfolgt direkt 
hintereinander, sollte also auch durch einen Programmfehler nicht 
gestört werden können.
Dennoch meldete der Kunde, dass das System eindeutig bei einem Ton 
hängen blieb und bis zum Reset der Schaltung andauernd den einen Ton 
ausgab. Dies passierte ein einziges Mal innert 10 Stunden Testzeit.
Wie kann so etwas passieren?
Deutet dies vielleicht auf einen Stack- Overflow hin und wie kann ich 
dies ausschliessen?
Das Programm beinhaltet noch zwei ISRs: TIMER1_OVF sowie TIMER0_CAPT.
Die Allokation aller Variablen wurde dem GCC überlassen; es sollte also 
nicht zu Ueberlappungen kommen.
Kann es sein, dass ich beim Compilieren etwas falsch einstellte? Die 
eingestellten Optionen, siehe ganz unten in dieser Mail.
Was könnte es sonst sein?

Vielen herzlichen Dank für jede Hilfe!

Gruss, Tobias




_____________________________________________________
//Buzzer an PA2
#define BUZZER_INV  PORTA ^= 0x04

#include <util/delay.h>

....
if(...){
   play_tone(249, 84.9);
   play_tone(264, 73.5);
}

...



void play_tone(unsigned int length, double period){
  do{
    _delay_us(period);
    BUZZER_INV;
  } while(length--);
  BUZZER_OFF; //switch off buzzer
}



_____________________________________________________
-gdwarf-2
-std=gnu99
-Wall
-mcall-prologues
-DF_CPU=8000000UL
-O2
-funsigned-char
-funsigned-bitfields
-fpack-struct
-fshort-enums

(O2, da der Speicher langsam knapp wird)

von Εrnst B. (ernst)


Lesenswert?

Bei so seltenen Abstürzen: Hardware I.O? Abblockkondensatoren vorhanden?

Ansonsten:
_delay_us darf nur mit KONSTANTEN Parametern aufgerufen werden, sonst 
delay'ed der VIEL zu lange, weil er intern haufenweise 
float-berechnungen macht.

=> Dokumentation zu _delay_us durchlesen!

Würde auch erklären warum dein Flash schon bald voll ist.

von Tobias (Gast)


Lesenswert?

Danke für die wertvolle Hilfe!
Dass der Delay falsche Zeiten erzeugt, ist mir damals auch aufgefallen. 
Da ich damit aber nur diese Töne erzeuge, untersuchte ich das vorerst 
nicht genauer und irgendwann dachte ich nicht mehr an diese 
Unstimmigkeit; es funktionierte ja irgendwie (!) und ich kümmerte mich 
um anderes.
Werd' ich aber dringend ändern - ist vielleicht der Grund für das 
Desaster...

Der Controller wird mit 5V aus einem 7805 gespiesen, direkt neben den 
VCC / GND Pins befinden sich 100nF, SMD. AGND und AVCC sind auf dem 
kürzesten Weg mit den GND / VCC Pins verbunden. Auf dem Board gibt 
sicher es keine grossen Störquellen.

Danke und Gruss, Tobias

von Philipp B. (philipp_burch)


Lesenswert?

BOD und/oder Watchdog aktiviert? Könnte auch noch helfen. Damit kann der 
Controller zwar immer noch "abstürzen", jedoch nicht durch Einbrüche der 
Spannungsversorgung (BOD) und nach einer bestimmten Zeit wird er korrekt 
zurückgesetzt (Watchdog).

von Tobias (Gast)


Lesenswert?

Danke auch!
Die Schaltung läuft an 5V, der BOD ist auf 4V3 gesetzt.
Auch dein Tipp mit dem Watchdog ist gut. Der Watchdog ist aber bewusst 
noch nicht aktiv. Ich möchte ihn erst aktivieren (und im Programm 
behandeln), wenn das System absturzfrei läuft.

Inzwischen ruf' ich die _delay_us Routine nur noch mit Konstantem 
Parameter auf. Der Aufruf mit einer Variablen hat tatsächlich etwa 2kB 
Code erzeugt. Ja.. ich kann mich noch dran erinnern, wie ich mich 
fragte, ob mein Projekt nicht mal kleiner war... Man lernt nie aus...

Gruss, Tobias

von Philipp B. (philipp_burch)


Lesenswert?

Natürlich hilft der Watchdog nicht gegen die Abstürze, doch er bietet 
eine Möglichkeit, den Controller zu "retten" und herauszufinden, was die 
Absturzursache war. Du könntest beispielsweise beim normalen 
Programmstart den ganzen SRAM mit einem Bitmuster überschreiben (z.B. 
0x55 oder so) und beim Reset durch den Watchdog über eine Schnittstelle 
ausgeben. Dann solltest du erkennen können, ob ein Stapelüberlauf ein 
Problem ist. Das muss aber natürlich alles vor dem eigentlichen 
C-Programmstart passieren, also am Besten in .init0, gegebenenfalls mit 
Inline-ASM.

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.