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 | void submit_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 | void submit_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..
Was heißt den "geht nicht"... so wie ich das sehen nutzt du in den Funktionen eine ganze Menge globaler Variablen-->vieles das schief gehen kann ;)
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
Du könntest die Konstanten Strings auch in den Flash oder EEPROM auslagern dann gibt es auch keine Probleme mit dem SRAM.
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
Stefan L. schrieb: > oder betrifft die langsame Geschwindigkeit > nur den Schreibvorgang beim EEPROM Das Datenblatt kann dir sicher mehr verraten ;) Lesen dauert nicht sooo Lange, ich würde mich jedoch erstmal um das auslagern in den Flash bemühen, da stehen die Texte nämlich schon drinn und werden nur nochmal ins SRAM kopiert... --> http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Vereinfachung_f.C3.BCr_Zeichenketten_.28Strings.29_im_Flash
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
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.