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
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.
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 ;)
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.
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.
Gerade bemerkt: sein unkoscheres Verhalten hat er nur, wenn ein
bestimmter Programmteil mitcompiliert wird?!
Die Versorgungsspannung wird, denke ich, da STK600, i.O. sein.
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.
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.
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.
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.
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?
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
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.
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?
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?
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.
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
voidconvertclock(unsignedlongs)
2
{
3
charbuff[10];
4
charbuff2[10];
5
unsignedints2;
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.)
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!
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.
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
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;")
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.
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.