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.
Die Register und der RAM Inhalt bleiben bei einem Reset erhalten. Müßte ich aber im Datenblatt nachgucken.
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 | 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.)
Heiliger Bimbam. Ok, Array ausreichend dimensioniert und LÄUFT. Aber... ist das auch logisch?
Zu Beginn einer seriellen Übertragung einfach 2x 0xFF senden. Darauf rastet jeder Empfänger sauber ein.
Stephan schrieb: > Aber... ist das auch logisch? Ja, ist ein typischer Fall von „undefiniertem Verhalten“.
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.
Ich verzichte auf die Analyse und pass besser auf. Erschreckend ist das! Vielen Dank an alle!
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.