Forum: Mikrocontroller und Digitale Elektronik Irrfahrt nach Neustart- was resettet der Reset alles?


von Stephan (Gast)


Lesenswert?

Hallo!

Mein Controller (At2560 auf STK600 mit AVRStudio) zeigt ein (für mich) 
ungenwöhnliches Verhalten:
nach dem Brennen beginnt er artig seinen Programablauf. Drücke ich 
jedoch RESET, so spuckt er fortan aus der UART nur noch gequirlte 
Sc____ße  aus. Weitere Resets bringen da auch nichts, nur erneutes 
Brennen "hilft". Der Hardware unterstelle ich, dass sie fehlerfrei ist.

Frage: bleiben nach einem RESET bspw. fehlerhafte Pointer o.Ä. zurück? 
Woran mag das Verhalten liegen?

Greetz
Stephan

von (prx) A. K. (prx)


Lesenswert?

Der Controller kennt keine Pointer und initialisiert auch das RAM nicht 
selbst. Das Programm wiederum hat die Aufgabe, alles zu initialisieren, 
was es benötigt und was nicht per Reset sowieso schon im gewünschten 
Zustand ist. Wenn da etwas unterbleibt sind seltsame Effekte möglich.

von David .. (david1)


Lesenswert?

Ich tippe auf die Versorgungsspannung.

Gescheites Netzteil dran?

Hätte kürzlich was ähnliches, kleine Schaltung mit nem Tiny13 und paar 
LEDs schnell zum testen der Platine zusammen gelötet und erstmal die Cs 
nich bestückt weil die grad irgendwie nicht greifbar waren.

Da kamen dann auch ganz lustige Sachen raus wie dass das Teil total 
gesponnen hat wenn der Programmer abgezogen war (ISP MKII), Cs drauf und 
ruhe war ;)


Normalerweise sollte einfach ein Reset passieren, aber ich tippe wie 
gesagt auf die Versorgung dass dort was nicht stimmt ;)

von Peter II (Gast)


Lesenswert?

Stephan schrieb:
> nach dem Brennen beginnt er artig seinen Programablauf

nach dem Brennen wird aber auch nur "Reset" losgelassen, die 
Versorgungsspannung bleibt ja auch erhalten. Dieser Reset ist genau das 
gleiche wie der Reset den du machst.

von Wusel D. (stefanfrings_de)


Lesenswert?

Soweit ich weiss resettet er nur die im Controller integrierte Hardware 
(also Timer, I/O Ports, UART). Alle Register werden auf die Default 
Werte gesetzt.

Mit einer Ausnahme: Der Watchdog wird nur beim Power-On Reset 
initialisiert, jedoch nicht bei einem Signal am Reset-Eingang.

von Stephan (Gast)


Lesenswert?

Gerade bemerkt: sein unkoscheres Verhalten hat er nur, wenn ein 
bestimmter Programmteil mitcompiliert wird?!

Die Versorgungsspannung wird, denke ich, da STK600, i.O. sein.

von Peter D. (peda)


Lesenswert?

Vielleicht ist der Reset-Taster nicht entprellt.

Du solltest nach einem Reset mindestens eine Bytezeit (10/Baudrate) 
warten, ehe Du sendest, sonst kann der Empfänger sich falsch 
synchronisieren.

von Stephan (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Du solltest nach einem Reset mindestens eine Bytezeit (10/Baudrate)
> warten, ehe Du sendest, sonst kann der Empfänger sich falsch
> synchronisieren.

Er sendet nicht nur Kauderwelsch, er sendet es auch noch völlig stur und 
massenweise. Ununterbrochen halt. Werde den Vorschlag aber mal 
einpflegen.

von Uwe (Gast)


Lesenswert?

Die Register und der RAM Inhalt bleiben bei einem Reset erhalten. Müßte 
ich aber im Datenblatt nachgucken.

von Karl H. (kbuchegg)


Lesenswert?

Stephan schrieb:
> Peter Dannegger schrieb:
>> Du solltest nach einem Reset mindestens eine Bytezeit (10/Baudrate)
>> warten, ehe Du sendest, sonst kann der Empfänger sich falsch
>> synchronisieren.
>
> Er sendet nicht nur Kauderwelsch, er sendet es auch noch völlig stur und
> massenweise.

höchstwahrscheinlich tut er das nicht.
Er sendet sehr wahrscheinlich komplett richtig.

Das Problem ist der Empfänger. Bzw. das Problem ist eigentlich, dass bei 
einer UART Übertragung es nicht möglich ist, mitten in eine Übertragung 
einzusteigen. Der Empfänger muss sich erst mal auf den Start eines 
Zeichens synchronisieren. Nur leider gibt es dafür keine eigene Leitung, 
die dem Empfänger sagen würde: jetzt fängt das nächste Zeichen an, 
sondern diese Information ist in den Daten selbst enthalten. Der 
Empfänger benötigt daher eine gewisse Sendepause, damit sichergestellt 
ist, dass die nächste Flanke an der Datenleitung mit Sicherheit das 
Beginn eines Zeichens ist.

von amateur (Gast)


Lesenswert?

An den im Kernbereich liegenden Registern bzw. RAM wird auf jeden Fall, 
beim Reset, rumgefummelt. Viele der im unteren Bereich liegenden 
Register haben sogar spezielle Initialwerte.
Wenn ich raten sollte, werden die normalen Speicherzellen in Ruhe 
gelassen. Nicht weil die Entwickler so nett sind, sondern weil unnötige 
Initialisierungen unnötig Zeit kosten.

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


Lesenswert?

Stephan schrieb:
> Gerade bemerkt: sein unkoscheres Verhalten hat er nur, wenn ein
> bestimmter Programmteil mitcompiliert wird?!

Und in diesem Programmteil wird nicht zufällig der Watchdog aktiviert,
aber vor dem Eintritt von main() wird er nicht sauber deaktiviert?

Geht's denn ohne Neuprogrammierung mit einem simplen Power-On wieder?

von spess53 (Gast)


Lesenswert?

Hi

>An den im Kernbereich liegenden Registern bzw. RAM wird auf jeden Fall,
>beim Reset, rumgefummelt.

Steht doch in den Datenbättern:

Resetting the AVR
   During reset, all I/O Registers are set to their initial values,...

Alles andere wird nicht verändert.

MfG Spess

von Stephan (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Und in diesem Programmteil wird nicht zufällig der Watchdog aktiviert,

Nein, da findet nur ein bissel Rumgerechne statt.


Karl Heinz Buchegger schrieb:
> Das Problem ist der Empfänger.

Der Empfänger ist HTerm. Kann HTerm aus 20 unsynchronisierten Zeichen 
etwa 20 ZEILEN Müll produzieren? Ich probier es aus.

Jörg Wunsch schrieb:
> Geht's denn ohne Neuprogrammierung mit einem simplen Power-On wieder?

Nein, Kauderwelsch.

von Stephan (Gast)


Lesenswert?

Jetzt wirds kurios.

Mein RESET-Knopf hat nun folgende (unfreiwillige) Funktion:

Drücken: Programm läuft an
Drücken: Programm läuft an und bleibt sofort stehen
Drücken: Programm läuft an
Drücken: Programm läuft an und bleibt sofort stehen
usw.usw.

In welche Tonne kommen Leiterplatten? Grau? Gelb?

von Patrick (Gast)


Lesenswert?

Stephan schrieb:
>> Geht's denn ohne Neuprogrammierung mit einem simplen Power-On wieder?
>
> Nein, Kauderwelsch.

Power-Down Reset aktiviert und Fuses auf einen sinnvollen Wert gesetzt?

Klingt so langsam wirklich nach einer unvollständigen bzw. fehlerhaften 
Initialisierung durch Spannungseinbruch - bitte Spannungsversorgung 
nochmals penibelst kontrollieren (d. h. auch mal Spannungseinbruch bei 
"Loslassen" des Reset oszilloskopieren).

Die Register werden beim Reset auf einen Defaultwert (s. Datenblatt) 
gesetzt - so auch der Stackpointer. Der RAM wird nicht explizit durch 
eine Routine "geleert" - wozu auch? Das ist Aufgabe des Programms, d. h. 
irgendwo bei Programmadresse [Einsprungadresse + 0] muss das Programm 
die von ihm benötigten Variablen auf dem Stack "anlegen" bzw. 
initialisieren.

Welcher Compiler, welche Settings?

von (prx) A. K. (prx)


Lesenswert?

Brownout-Reset eingeschaltet?

von Karl H. (kbuchegg)


Lesenswert?

Stephan schrieb:
> Karl Heinz Buchegger schrieb:
>> Das Problem ist der Empfänger.
>
> Der Empfänger ist HTerm. Kann HTerm aus 20 unsynchronisierten Zeichen
> etwa 20 ZEILEN Müll produzieren? Ich probier es aus.

Das du nur 20 Zeichen sendest höre ich jetzt zum ersten mal. Weiter oben 
war noch von ununterbrochen die Rede.

Dein Problem ist ganz einfach zu lösen.
Entweder es ist die Hardware oder es ist die Software. Wenn du nichts 
von beidem herzeigst kann man auch nichts sinnvolles dazu sagen.

Die Software, und sei es nur ein kleines Testprogramm welches das 
Verhalten zeigt, lässt sich einfacher kontrollieren.
Also würde ich deinem eigenen Interesse mal vorschlagen, dass du damit 
anfängst sie herzuzeigen.

von Stephan (Gast)


Lesenswert?

Patrick schrieb:
> Power-Down Reset aktiviert

= BrownOut Detection? Aktiviert, 2,7V (bei 3,3V Boardspannung)

Eigenartig: der Effekt tritt nur auf, wenn folgender Code mitcompiliert 
wird: er erzeugt aus einer Zeit in Sekunden eine n String, der diese 
Zeit als d,h,m,s darstellt.
1
void convertclock(unsigned long s)
2
{
3
  char buff[10];
4
  char buff2[10];
5
  unsigned int s2;
6
  
7
  s2=s/day;
8
  itoa(s2,buff2,10);
9
  strcat(buff,buff2);
10
  strcat(buff,"d,");
11
  s=s-(s2*day);
12
  
13
  if (s>hour)
14
  {
15
    s2=s/hour;
16
    itoa(s2,buff2,10);
17
    strcat(buff,buff2);
18
    strcat(buff,"h,");  
19
    s=s-(s2*hour);
20
  }  
21
  if(s>min)
22
  {
23
    s2=s/min;
24
    itoa(s2,buff2,10);
25
    strcat(buff,buff2);
26
    strcat(buff,"m,");  
27
    s=s-(s2*min);
28
  }  
29
  if(s>1)
30
  {  
31
    s2=s;
32
    itoa(s2,buff2,10);
33
    strcat(buff,buff2);
34
    strcat(buff,"s");
35
  }  
36
  
37
  strcpy(time_ascii,buff);
38
}
(Bevor Lektürehinweise auf mich einrpasseln: Habe mir ein C Buch 
gekauft: Softwareentwicklung in C für Mikroprozessoren und 
Mikrocontroller: C-Programmierung für Embedded-Systeme, aber leider 
lernt man da kaum C.)

von Stephan (Gast)


Lesenswert?

Heiliger Bimbam.
Ok, Array ausreichend dimensioniert und LÄUFT.
Aber... ist das auch logisch?

von Carsten W. (eagle38106)


Lesenswert?

Zu Beginn einer seriellen Übertragung einfach 2x 0xFF senden. Darauf 
rastet jeder Empfänger sauber ein.

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


Lesenswert?

Stephan schrieb:
> Aber... ist das auch logisch?

Ja, ist ein typischer Fall von „undefiniertem Verhalten“.

von Stephan (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Ja, ist ein typischer Fall von „undefiniertem Verhalten“.

Jetzt mal ernsthaft:
kann ein zu klein dimensioniertes Array dazu führen, dass eine Variable 
WÄHREND DES FLASHENS ihren Wert beibehalten? Genau das ist hier 
passiert: eine Zählvariable tickte im Sekundentakt hoch, verstummte 
während des Flashens und anschließend zählte sie weiter!

von Karl H. (kbuchegg)


Lesenswert?

Stephan schrieb:
> Jörg Wunsch schrieb:
>> Ja, ist ein typischer Fall von „undefiniertem Verhalten“.
>
> Jetzt mal ernsthaft:

ernsthaft

Du hast dir mit dem Array out of bounds irgendwas im Speicher 
zerschossen, was nincht hätte sein sollen. Was genau, das müsste man 
analysieren. Wenn dieses 'irgendwas' zufällig ein Teil einer Variablen 
ist, die normalerweise zb 0 sein sollte es dann aber nicht ist und du 
selber die nicht initialisiert hast, dann kann alles mögliche passieren. 
Inklusive 'es passiert gar nichts'.

Derartige Analysen zu führen ist meistens recht aufwändig. Aber es gibt 
mit Sicherheit eine Verkettung von Ereignissen die zu dem von dir 
beobachteten Verhalten führt. Hat man die Analyse erst mal, dann ist 
alles ganz leicht erklärbar, aber der Weg dorthin ist steinig.

von Stephan (Gast)


Lesenswert?

Ich verzichte auf die Analyse und pass besser auf. Erschreckend ist das! 
Vielen Dank an alle!

von Reinhard Kern (Gast)


Lesenswert?

Stephan schrieb:
> Ich verzichte auf die Analyse und pass besser auf.

Das ist eine Möglichkeit, sowas gehört zum normalen Lernprozess. Eine 
andere Möglichkeit, defensiv zu programmieren (ich weiss nicht, ob das 
mit dem verwendeten Compiler geht):

1. Arraylänge für Zeitstring als Konstante definieren, z.B. TimeLen

2. strlcat(buff,"m,",TimeLen);  verwenden

Gruss Reinhard

von PanOli (Gast)


Lesenswert?

Wobei da eventuell noch ein weiterer "Bock" drin ist:

 char buff[10];
 ...
 strcat(buff,buff2);

"buff" wird hier verwendet ohne das zuvor sichergestellt ist, dass das 
erste Zeichen in diesem Null ist (nicht jeder Compiler initialisiert 
"char buff[10];" automatisch mit Nullen). Somit kann der strcat wild im 
Speicher rumlaufen bis er irgendwo mal eine Null findet und ab da dann 
"buff2" hinkopiert.

Besser/Sicherer wäre hier für den ersten Kopie "strcpy" zu verwenden 
(oder am Anfang wenigstens ein "buff[0]=0;")

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


Lesenswert?

Stephan schrieb:
> dass eine Variable WÄHREND DES FLASHENS ihren Wert beibehalten

Der SRAM wird beim Programmieren nicht angefasst.  Nach dem Reset
steht in den Speicherzellen folglich noch der alte Wert. Wenn die
Firmware den nicht anschließend selbst löscht oder überschreibt
(was sie normalerweise tut), dann geht's halt hernach an der
alten Stelle weiter.

von Josef D. (jogedua)


Lesenswert?

PanOli schrieb:
> (nicht jeder Compiler initialisiert
> "char buff[10];" automatisch mit Nullen).

Da das hier eine Stack-Variable ist, sollte sie kein Compiler 
initialisieren.

Stephan schrieb:
> unsigned int s2;
>   ...
>   itoa(s2,buff2,10);

Hier wäre utoa(...) angebracht.

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.