Hallo,
Leider bin ich heute auf ein für mich nicht so ganz erklärbares und
deshalb auch nicht behebbares Problem gestossen.
Ich programmiere gerade ein etwas umfangreicheres Programm in C auf
einem Atmega16. Es hat derzeit ca. 1000 Bytes.
Heute habe ich lediglich zwei Funktionen hinzugefügt welche ein paar
Variablen per utoa über die hardwareuart ausgeben. Seit ich diese
Funktionen eingefügt habe, funktioniert aber die softuart-schnittstelle
welche gps-daten empfängt nicht mehr richtig.
Ich konnte aber inzwischen durch probieren ausschließen dass es mit den
Funktionen selbst zu tun hat, es liegt an der Codelänge. Sobald ich eine
bestimmte Anzahl an Codezeilen in einer der Funktionen (vermutlich auch
in anderen.. das habe ich jetzt aber nicht getestet) hinzufüge, tritt
das Problem auf. (es kommt kein korrekter Text mehr an..)
Ich bin Anfänger und kann leider noch nicht auf viele Erfahrungswerte
zurückgreifen, ich meine mich aber zu erinnern dass es bei den
Sprungmarken etc. gewisse Grenzen gab.. wie aber kann ich das
kontrollieren ob das bei mir das Problem ist? Dieses Problem ist derzeit
das einzige mir bekannte was zu meinem Phänomen irgendwie passt..
Vielleicht kann mir jemand einen Tipp geben, auf was ich hier achten
muss oder was sonst noch die Ursache für ein solches komisches Verhalten
ist?
Vielen Dank im vorraus,
avlbger
Brauchst dich nicht drum kümmern (falls nicht der Compiler buggy ist).
Solche primitiven Fehler macht aber kein Compiler. Ausserdem geht rjmp
bis 2kB.
Das Problem liegt mit ziemlicher Sicherheit an deinem Programm.
Hmm ok.. danke.. hab ja erstmal auch mein Programm vermutet da ich
derzeit sicher noch Fehleranfälliger bin als alles andere drum herum :)
Das Ganze ist aber sehr strange.. es geht um folgende 2 Funktionen:
1
voidsubmit_runtime_vars()
2
{
3
huart_puts("\r\n#VAR@");
4
utoa(pwm_g_startval,tbuff,10);
5
huart_puts(tbuff);
6
huart_putc(',');
7
utoa(manual_override,tbuff,10);
8
huart_puts(tbuff);
9
huart_puts("\r\n");
10
}
11
12
voidsubmit_countjob_status()
13
{
14
huart_puts("\r\n#CNT@");
15
utoa(cj1_d1,tbuff,10);
16
huart_puts(tbuff);
17
huart_putc(',');
18
utoa(cj1_d2,tbuff,10);
19
huart_puts(tbuff);
20
huart_putc(',');
21
utoa(cj1_d3,tbuff,10);
22
huart_puts(tbuff);
23
huart_putc(',');
24
utoa(cj2_d1,tbuff,10);
25
huart_puts(tbuff);
26
huart_putc(',');
27
utoa(cj2_d2,tbuff,10);
28
huart_puts(tbuff);
29
huart_putc(',');
30
utoa(cj2_d3,tbuff,10);
31
huart_puts(tbuff);
32
huart_putc(',');
33
utoa(cj_active,10);
34
huart_puts(tbuff);
35
huart_puts("\r\n");
36
}
Die beiden Funktionen funktionieren auch wie gewünscht, nur funktioniert
die SoftUART eben nicht mehr richtig wenn beide so wie hier gezeigt
eingebaut sind. Kommentiere ich die Befehle in den Funktionen aus,
gehts, kommentiere ich nur die Befehle einer Funktion aus und zwar egal
welcher, gehts auch. Kommtentiere ich ein paar Zeilen, ebenfalls egal
welche, aus, funktionierts ebenfalls.. es funktioniert NUR NICHT wenn
ich die beiden Funktionen komplett drin habe..
Das gibt doch keinen Sinn, oder?? Und in den Funktionen passiert ja auch
ncihts was die SoftUART beeinflussen sollte.. ich checks nicht :(
Ahja.. hab mich vorhin vertan.. mein Programm ist nicht 1000 sondern
10000 Bytes lang..
Stefan L. schrieb:> Das gibt doch keinen Sinn, oder?? Und in den Funktionen passiert ja auch> ncihts was die SoftUART beeinflussen sollte.. ich checks nicht :(
Werden diese Funktionen wohlmöglich in einem Interrupt aufgerufen??
SoftUART => zeitkritische Interrupts.
Viel Aktivität in anderen Interrupts => Zeitfehler in SoftUART.
Guten Morgen zusammen :)
Die einzige globale Variable die in den Funktionen überschrieben wird,
ist tbuff und die wird definiv nicht zeitgleich woanders verwendet und
schon gar nicht von der Softuart.
Die Funktionen werden auch in einem Interrupt ausgeführt -> weiß dass
das Zeitkritisch ist und so evtl. stören könnte.. ABER :) Es ist ja so
dass diese Funktionen überhaupt gar nicht ausgeführt werden! Die werden
nur aufgerufen wenn ich über die HardwareUART ein bestimmtes Kommando
sende, was ich aber momentan nicht mache... Alleine die Tatsache dass
die Funktionen "da" sind, stört offenbar die SoftUART und das ist was
ich nicht verstehe und weshalb ich zum Schluss gekommen bin dass es
irgendwie mit der Codelänge zu tun haben muss.
Compiler ist avr-gcc, der sollte mich da warnen falls irgendwelche
Sprungmarken zu "weit" entfernt sind?
Neuer Tag neues Glück.. ich werd jetzt mal weiterprobieren und komme der
Sache hoffentlich noch auf die Schliche.. echt sehr eigenartig :)
Stefan L. schrieb:> Compiler ist avr-gcc, der sollte mich da warnen falls irgendwelche> Sprungmarken zu "weit" entfernt sind?
In C kümmerst du dich nicht um Sprungmarken. Und der Compiler kann das
ausreichend gut. Du hast ein anderes Problem.
> Alleine die Tatsache dass> die Funktionen "da" sind, stört offenbar die SoftUART und das ist was> ich nicht verstehe und weshalb ich zum Schluss gekommen bin dass es> irgendwie mit der Codelänge zu tun haben muss.
Nein.
Es ist ganz einfach: du hast einen amoklaufenden Pointer.
Kurz: irgendein Array wird über das Arrayende hinaus beschrieben.
Strings werden gern für solche Fehler verwendet...
Es könnte auch ganz einfach der Stack überlaufen (das ist auch wieder
ein amoklaufender (Stack-)Pointer)...
Hmm.. OK, bin dahingehend eh schon am probieren. Die SoftUART empfängt
ja Zeichen vom GPS und schreibt die in einen Puffer welcher dann am
Schluss ein GPS-Datensatz enthalten sollte und der wird dann über die
HardwareUART ausgegeben. Möglicherweise läuft da beim befüllen des
Puffers was schief, (sehr gut möglich da ich leider noch nicht alles was
ich mir da aus anderen Codeschnipseln zusammengebastelt habe 100%
verstehe)
Aber was mir einfach überhaupt nicht einleuchten will ist, WARUM zum
Henker hat das bisher tadellos funktioniert und nur weil ich ein paar
Zeilen Code an komplett anderer Stelle, die derzeit ncoh nicht mal
aufgerufen werden, hinzugefügt habe, läuft das Ganze Amok :D
Das zweite, der möglicherweise überlaufende Stackpointer, wie kann ich
denn das überprüfen ob es daran liegt?
Vielen Dank :)
Stefan L. schrieb:> Aber was mir einfach überhaupt nicht einleuchten will ist, WARUM zum> Henker hat das bisher tadellos funktioniert und nur weil ich ein paar> Zeilen Code an komplett anderer Stelle, die derzeit ncoh nicht mal> aufgerufen werden, hinzugefügt habe, läuft das Ganze Amok :D
Z.B. darum, weil du wegen dieser Code-Zeilen (auch ohne dass sie
aufgerufen werden) mehr RAM verbrauchst (wegen der Strings). Lass die
Strings einfach mal weg (huart_puts(0);), und schaue, was dann passiert.
Stefan L. schrieb:> Die einzige globale Variable die in den Funktionen überschrieben wird,> ist tbuff und die wird definiv nicht zeitgleich woanders verwendet und> schon gar nicht von der Softuart.
Wenn das so ist dann mach sie Funktionslokal oder Funktionsstatisch!
Ein Blick auf den Speichervervrauch wäre auch nicht verkehrt.
Zum Bleistift könnte es daran liegen, dass dein tBuff zu "klein" ist.
In der Doku zu der Funktion utoa findet man:
"The size of buffer must be at least (8 * sizeof(int) + 1) bytes when
converting values in base 2. That makes the size 17 bytes on 16-bit
machines, and 33 bytes on 32-bit machines."
Viele Grüße
Hallo Leute!
Vielen Dank für eure Hilfe, ich habs nun :)
Tatsächlich hatte ich den SRAM wohl ausgereizt :)
Die Strings warens... Bin nun meinen ganzen Code durchgegangen und habe
ein wenig optimiert so dass der Compiler noch besser optimieren konnte.
Zb: solche Zeilen:
1
huart_puts("XYZ\r\n");
durch
1
huart_puts("XYZ");
2
huart_puts("\r\n");
ersetzt. Auch den Puffer für die GPS Datensätze habe ich etwas reduziert
und somit einige Bytes gespart. Nun funzt alles wieder wie gewünscht :)
Zum Glück ist das Programm nun so gut wie fertig und ich hoffe ich muss
nichts großes mehr hinzufügen sonst hab ich ein SRAM Problem.. mein Code
hat aber sicher noch mehr Optimierungspotential.
Vielen Dank nochmal für eure Tipps die mir auf die richtige Spur
geholfen haben!
avlbger
Ja, hab ich mir auch schon überlegt, aber ich wollte alles erstmal so
einfach wie möglich machen.. was in dem Fall wohl kurz nach hinten
losgegangen ist ;)
Wie ich was im Flash speichere und zur Laufzeit auslese muss ich mir
erstnoch aneignen, das würde ja auch von der Geschwindigkeit her gehen,
EEPROM ist ja relativ langsam und dann könnte ich mir wieder Probleme
aufreissen wenn ich evtl. sogar noch in einer INterrupt-Routine einen
String ausgeben will der im EEPROM gespeichert ist.(oder betrifft die
langsame Geschwindigkeit nur den Schreibvorgang beim EEPROM?)
Das EEPROM verwende ich bisher dafür dass ich diverse Einstellungen die
nach Stromausfall oder Reset wieder verfügbar sein sollen, speichere und
diese bei Programmstart dann auslese.
Viele Grüße,
avlbger
Für heut mach ich erstmal Schluss :) Danke für den Link, ja das Tutorial
ist echt hilfreich.. wäre nie so weit gekommen ohne das Ding.
Aber alles ist halt noch nicht hängengeblieben :) aber ich Arbeite dran
:)
Schönen Sonntag noch,
avlbger