Verhalten: Auf einem ATmega128 läuft das Programm nicht stabil.
Irgendwann hängt der Controller oder läuft in einen Resetvektor.
In einem Terminal sieht die Ausgabe in etwa so aus:
1
dgartztkuzjuze etaear weeu tatawet rtaf
2
sdfgd 165 etgaga
3
dgartztkuzjuze etaear weeu tatawet rtaf
4
sdfgd 1291 etgagaaga
5
dgartztkuzjuze etaear weeu tatawet rtaf
6
sdfgd 690 etgaga
7
dgartztkuzjuze etaear weeu tatawet rtaf
8
sdfgd 1137 etgaga
9
dgartztkuzjuze etaear weeu tatawet rtaf
10
sdfgd 386 etgaga
11
dgartztkuzjuze etaear weeu tatawet rtaf
12
sdfgd 960 etgagagaga
Ersetzt man den sprintf-Aufruf in der while-Schleife durch
1
sprintf(z,"sdfgd etgaga\r");
tritt das Problem nicht mehr auf
Auch wenn ich
1
uart_send_string(z);
aus der Schleife entferne, besteht das Problem weiterhin.
Da geht also definitiv was beim sprintf() schief und auch nur wenn
Umwandlungszeichen im Formatstring verwendet werden.
Lasse ich das Programm für einen ATmega2561 oder ATmega32 compilieren
und laufen, tritt das Problem auch nicht auf.
Kennt jemand dieses Verhalten und hat eine Lösung dafür?
Danke vielmals
Boxi
Boxi Boxitec schrieb:> Verhalten: Auf einem ATmega128 läuft das Programm nicht stabil.> Irgendwann hängt der Controller oder läuft in einen Resetvektor.
Was heißt hier "irgendwann"? Dass nach jedem "sdfgd..." wieder ein
"dgartzt..." kommt, zeigt doch, dass schon beim ersten
Schleifendurchlauf etwas gewaltig schief läuft.
Die M103C-Fuse ist aber schon aus, oder?
Stefan Ernst schrieb:> Die M103C-Fuse ist aber schon aus, oder?
Richtich. Hat das was mit dem Problem zu tun?
> Was heißt hier "irgendwann"? Dass nach jedem "sdfgd..." wieder ein> "dgartzt..." kommt, zeigt doch, dass schon beim ersten> Schleifendurchlauf etwas gewaltig schief läuft.
irgendwann heißt so ungefähr exakt nach der Anzahl Durchläufen, die da
stehen: 165, 1291, 690, 1137 ...
Also recht breit gestreut. Und definitiv nicht beim ersten
Schleifendurchlauf.
Ich weiß, es ist schon spät, aber trotzdem Danke!
Boxi
Boxi Boxitec schrieb:> irgendwann heißt so ungefähr exakt nach der Anzahl Durchläufen, die da> stehen: 165, 1291, 690, 1137 ...> Also recht breit gestreut. Und definitiv nicht beim ersten> Schleifendurchlauf.
Ich verstehe. Das "in etwa" hier
> In einem Terminal sieht die Ausgabe in etwa so aus:
muss also sehr großzügig ausgelegt werden.
Wenn irgendwas mit printf, sprintf, etc. schief geht, ist es meistens
irgendwas mit den Parametern. Entweder läuft der Stack über, oder
es passt etwas bei der Parameterübergabe nicht (was auch über den Stack
abgewickelt wird).
Was passiert denn, wenn Du "static UI16 i = 0;" zu "static UI8 i = 0;"
änderst?
Alternativ mal statt "%d" mal "%x" probieren.
Du verwendest wohl den avr-gcc (?) Welche Version ?
Stefan Ernst schrieb:> Ich verstehe. Das "in etwa" hier>> In einem Terminal sieht die Ausgabe in etwa so aus:> muss also sehr großzügig ausgelegt werden.
Stefan,
ja, das "in etwa" sollte die recht unterschiedliche Anzahl von
Schleifendurchläufen andeuten, bis feststellbar (Reset) was schief
läuft.
Boxi
Matthias schrieb:> Du verwendest wohl den avr-gcc (?) Welche Version ?
Ach so ja, ich verwende avr-gcc in der Version von 20100110.
Ich habe ja vor meinem ersten Post gestern Nacht schon jede Menge
gegoogelt. Andere Leute hatten das Problem auch schon. Leider konnte ich
dort keine Lösung herauslesen:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=700064
Boxi
Boxi Boxitec schrieb:> UCSR1B |= (1<<TXEN0);
Ist nicht der Fehler, aber dennoch korrekturbedürftig.
Nimm doch mal das send_string aus der while raus und schau, ob's dabei
Reboots gibt. Dann kann man eingrenzen.
> dgartztkuzjuze etaear weeu tatawet rtaf> sdfgd 165 etgaga> dgartztkuzjuze etaear weeu tatawet rtaf
Die dritte Zeile zeigt, dass der AVR sich resettet. Kontrolliere mal die
RESET-Ursache in dem entsprechenden Kontollregister: Watchdog? Brownout?
Die M103C Fuse wäre ein Kandidat, weil bei gesetzter Fuse der Stack
nicht zum für Atmega128 übersetzten Programm passt und es bei der
Rückkehr von der ersten Funktion knallt. Die UART-Funktionen zählen
eventuell nicht als echter Funktionsaufruf, denn GCC kann die inline
realisiert haben (je nach Optimierungslevel)
Oliver schrieb:> Mit welcher Taktfrequenz läuft denn der Prozessor?>> Oliver
BINGO, Oliver!
Das war's, ich könnte mir in den A.... beißen. Ich habe den ATmega128
außerhalb der Spezifikationen mit 18,432MHz betrieben. Da im Datenblatt
in der Liste der Baudrateneinstellungen auch je eine Spalte mit fOSC =
18,432MHz und 20MHz dabei ist, habe ich total verdrängt, das der
ATmega128 nur bis 16MHz darf.
Manchmal sieht man einfach den Wald vor lauter Bäumen nicht... Obwohl
dieses eigenartige Verhalten ja förmlich danach geschrien hat, dass das
Teil nicht in seinen Spezifikationen läuft.
Der ATmega32, den ich vorher verwendet habe, lief mit auch 18,432MHZ,
obwohl er auch nur 16MHz dürfte. Ohne Probleme -> einfach nur
zweifelhaftes Glück gehabt. Da sieht man mal wieder, was passieren kann,
wenn man die Regeln nicht einhält.
Jetzt ist ein 16MHz-Quarz drauf, UBRR1 angepaßt und siehe da, es läuft.
Danke für all eure Gedanken. Für mich gilt: "Again what learned!" ;)
Grüße
Boxi
=======================================================================
Der Vollständigkeit halber noch ein paar Kommentare auf eure Antworten:
> Autor: Klaus Wachtler (mfgkw)> Und ist das wirklich das ganze Programm?
Ja, das war der relevante Teil, den ich aus meinem eigentlichen Programm
extrahiert habe, um den Fehler zu reproduzieren.
> Autor: MWS (Gast)> Boxi Boxitec schrieb:>> UCSR1B |= (1<<TXEN0);> Ist nicht der Fehler, aber dennoch korrekturbedürftig.>> Nimm doch mal das send_string aus der while raus und schau, ob's dabei> Reboots gibt. Dann kann man eingrenzen.
Wie ich schon vorher geschrieben hatte, gabs die Resets auch ohne das
uart_send_string()
> Autor: Krapao (Gast)> Die dritte Zeile zeigt, dass der AVR sich resettet. Kontrolliere mal die> RESET-Ursache in dem entsprechenden Kontollregister: Watchdog? Brownout?
Die Resetursache konnte ich jetzt leider nicht mehr kontrollieren, weil
ich in meinem Überschwang das 16MHz-Quarz eingelötet habe und den Fehler
ja jetzt nicht mehr bekomme.
Brown-Out und Watchdog würde ich jetzt mal ausschließen, weil nicht
aktiviert.
Aber ich gehe mal davon aus, dass es sowas wie "forbidden instruction"
(gibts das bei den AVRs?) war, weil er in einen Teil des
Programmspeichers geschickt wurde, der wohl mit 0xFFs gefüllt war.
Boxi Boxitec schrieb:> Ja, das war der relevante Teil, den ich aus meinem eigentlichen Programm> extrahiert habe, um den Fehler zu reproduzieren.
auch wenn es sich schon erledigt hat:
es hätte ja in dem weggelassenen Teil irgendwo eine ISR provoziert
werden können, für die keine Routine existiert.
Das hätte auch ein ähnliches Verhalten zeigen können, daher die Frage.
Klaus Wachtler schrieb:> Boxi Boxitec schrieb:>> Ja, das war der relevante Teil, den ich aus meinem eigentlichen Programm>> extrahiert habe, um den Fehler zu reproduzieren.>> auch wenn es sich schon erledigt hat:> es hätte ja in dem weggelassenen Teil irgendwo eine ISR provoziert> werden können, für die keine Routine existiert.> Das hätte auch ein ähnliches Verhalten zeigen können, daher die Frage.
Achso, jetzt bin ich dabei. Ja das war das komplette Programm, das für
den Controller übersetzt wurde. ;)
robo schrieb:> Mich wundert, dass i überhaupt hochzählt und nicht immer Null bleibt.
Wenn die Variable mit einem Wert deklariert wird, dann wird sie nur
einmal damit initialisiert, das ist nicht das Gleiche, wie wenn ihr
innerhalb des Codes etwas zugewiesen wird.