Guten Abend,
Ich habe ein kleines Problem mit meiner Software. Ich hatte letztes
Jahr(So um Oktober) mal ein Thema hier wo es um mein Aquarium
Steuergerät ging wo mir der Platz aus ging.
Da ich mich ja dafür entschlossen habe den gesamten Programmcode neu zu
schrieben anstatt im bestehen Projekt zu überarbeiten, habe ich dieses
Stück für Stück getan.
Es wurde mir ja mehrmals geraten das ich die String nicht mehr im RAM
ablegen soll sondern mit den "_P" Funktion und PSTR sowie PROGMEM in den
Flash auslagere.
Das habe ich auch immer bis jetzt getan(Außer Serielle Nachrichten die
nur zur Temporären Überprüfung waren wurden ohne _P und PSTR verwendet).
Nur jetzt habe ich ein Problem und zwar bin ich gerade an dem
Menüfunktion Netzwerk angelangt, und dort verwende ich ein Switch Case.
In diesem Switch Case lade ich einen String "preIpStr" mit strcpy_P vor.
Dort steht dann zB. drin "IP" oder "GW". Das Problem liegt am zweiten
strcpy_P in case Fall 2 wenn ich das drin stehen habe und die
IP-Adressen im Menü ändern möchte wird mein TFT Display(ili9341) mit
allen möglich Zeichen ausgefüllt und der Controller hängt sich komplett
auf.
Nach 4 Sekunden setzt dann der Watchdog Timer den Controller zurück.
Wenn ich aus dem strcpy_P die normale Version mache strcpy funktioniert
der Programmcode Problemlos.
Kann mir nicht erklären woran das liegt, char Array ist groß genug
teiweise auch mal auf 100 Bytes erhöht ändert aber nix. Wenn ich das
strcpy_P aus dem Case Fall 1 entnehme(Also strcpy_P(preIpStr,
PSTR("IP"));) und im Case Fall 2 es stehen lasse(strcpy_P(preIpStr,
PSTR("GW"));) dann funktioniert der Code wieder.
Gibt es eine Limitierung bei PSTR/pgmspace? Der RAM ist noch nicht
Ansatz weiße voll.
Flash aktuell: 41,8kB 32 %
RAM aktuell : 2,59kB 15 %
Ich habe die Funktion mal angehängt. Sie ist zum Teil kommentiert.
Kann mir da jemand weiter helfen?
Mfg
Felix N. schrieb:> Es wurde mir ja mehrmals geraten das ich die String nicht mehr im RAM> ablegen soll sondern mit den "_P" Funktion und PSTR sowie PROGMEM in den> Flash auslagere.
richtig so, nur die strings standen auch schon vorher im flash und sind
nur extra zum init ins ram kopiert worden.
Felix N. schrieb:> Das Problem liegt am zweiten> strcpy_P
glaube ich nicht, weil da sieht alles ok aus. ich denke an
bereichsüberschreitung/-schreibung ...
mache debug ausgaben von dem code davor!
bzw. verwende as7 und den simulator um dir codebereiche anzuschauen!
mt
Apollo M. schrieb:> richtig so, nur die strings standen auch schon vorher im flash und sind> nur extra zum init ins ram kopiert worden.
Ach ja, so war das.
Apollo M. schrieb:> glaube ich nicht, weil da sieht alles ok aus. ich denke an> bereichsüberschreitung/-schreibung ...
Ah ok.
Apollo M. schrieb:> mache debug ausgaben von dem code davor!> bzw. verwende as7 und den simulator um dir codebereiche anzuschauen!
Also mit dem Simulator habe ich das wohl schon mal versucht jedoch komme
ich da noch nicht wie man den richtig anwendet. Muss da nochmal schauen
zu mal die Funktion ja nur ausgeführt wird denn ein Knopf gedrückt wird
und ein bestimmter Wert auf 1 gesetzt wird sonst wird die Funktion ja
garnicht ausgeführt.
Von was soll ich den genau debug ausgaben machen? Von den Strings?
Pit S. schrieb:> Wo wird denn 'ipByteSelector' initialisiert?
ipByteSelector ist eine globale uint8_t Variable und wird mit dem Wert 0
initialisiert.
Pit S. schrieb:> Du greifst da mit ...-1> drauf zu.
Huch, wo greife ich den da mit -1 drauf zu? //Edit: Meinst du bei
eIP[ipByteSelector - 1]?
Mfg
Apollo M. schrieb:> glaube ich nicht, weil da sieht alles ok aus. ich denke an> bereichsüberschreitung/-schreibung ...
Hallo nochmal,
Ich habe nochmal ein bisschen geschaut also Debug Nachrichten auszugeben
macht kein Sinn da solange das zweite strcpy_P drin steht da keine Debug
Nachrichten mehr an den UART gesendet werden sobald die Funktion
aufgerufen wird auch wenn die Sendung der Nachrichten vor dem strcpy_P
erfolgt.
Komisch ist ja das der Programmcode Problemlos funktioniert wenn ich den
String in den RAM lade und nicht über PSTR ablege.
Auch Ausblenden einzelner Codeteile vor und nach dem strcpy_P nach nix
gebracht der Code funktioniert nur wenn das strcpy_P durch strcpy
ersetzt wird oder das strcpy_P komplett raus genommen wird.
Nochmal zu dem ipByteSelector das ist ja wie schon erwähnt eine globale
Variable die mit 0 initialisiert wird. Bevor jedoch die changeIP()
Funktion aufgefunden wird(Diese Funktion ist ja nur dafür da die Werte
zu ändern) wird eine andere Funktion aufgerufen welche den
ipByteSelector zuweist. Beim ersten Knopfdruck wird der Selector auf 1
gesetzt und wählt damit das erste Byte der IP-Adresse aus bei nächsten
drücken wird der um 1 erhöht und wählt dann das zweite Byte aus geht alt
bis 4 dann wird er zurückgesetzt.
Nur kann ich mir das mit dem strcpy_P nicht erklären. Es macht für mich
irgendwie kein sinn.
mfg
Guten Abend nochmal an alle,
Es hat zwar in der zwischen Zeit keiner geantwortet jedoch habe ich
selber noch fleißig weiter gesucht und konnte das Problem teilweise
lösen kann es mir aber immer noch nicht erklären warum das so ist.
Also was ich mittlerweile feststellen konnte das das Problem wohl nicht
an dem zweiten strcpy_P liegt sondern wahrscheinlich an dem:
1
sprintf_P(strIP, PSTR("%03d"), eIP[ipByteSelector - 1]); //Format String to drawing
Wenn ich die sprintf_P Zeile auskommentiere funktioniert der Code wieder
Problemlos aber gleichzeitig wenn ich die sprintf_P Zeile drin lasse und
oben eine der strcpy_P auskommentiere funktioniert der Code auch. Wie
kann das???
Also eIP und ipByteSelector sind gültig und auch initialisiert. Daher
keine Probleme ipByteSelector hat zum Zeit Punkt den Wert 1 und in
eIP[0] steht dann der entsprechen Wert.
Ich habe jedoch noch das 03 in dem %d drin damit wenn man eine Zahl
unter 100 eingibt das dort nicht 99 steht sondern 099 weil sich sonst
die ganze Display Zeile verschiebt und das alles dann nicht mehr richtig
funktioniert.
Jedoch wenn ich das %03d zu einem einfach %d ersetzt funktioniert der
Code Problemlos.
Ich kann mir das nicht erklären wieso das so ist. Habt ihr vielleicht
eine Idee? Zumal ich die Zeile mit dem sprintf_P schon öfters in
Kombination mit %03d bzw. %02d verwendet habe und es gab in der Hinsicht
noch nie Probleme.
Komisch das ganze ...
Mfg
Felix N. schrieb:> Jedoch wenn ich das %03d zu einem einfach %d ersetzt funktioniert der> Code Problemlos.
Dann ist der Puffer strIP zu klein oder ungültig.
Felix N. schrieb:> sprintf_P(strIP, PSTR("%03d"), eIP[ipByteSelector - 1]);
"Zeiger/Index - 1" sollte man generell vermeiden. Bei jedem Profi läuten
da sofort die Alarmglocken.
gibt es auch ein snprintf_P? Die n Versionen würde ich sowieso
bevorzugen.
> eIP[ipByteSelector - 1]
Da könnte man auch ein ASSERT() Makro für einen Debugbuild verwenden.
Das %03 nicht funktioniert und %3 doch hört sich ja schon nach einem
Grössenproblem an.
Oder du hast dir vorher einen Stackfehler eingefangen, das macht sich
auch gerne erst später bemerkbar.
Hallo an alle,
Totomitharry schrieb:> Minimiere doch mal den kompletten Code mit bestehendem Problem als> snippet.
Ja das Problem ist ja das dieses Problem sich durch andere
Programmzeilen beeinflussen lässt. Daher wird es schwierig.
Denn was ich nun herausgefunden habe ist das dort zwischen den strcpy_P
und dem sprintf_P noch eine sprintf_P Zeile drin steht:
Auch da ist wieder das Problem das wenn ich das %03d zu einem %3d oder
%d der Code wieder funktioniert.
Peter D. schrieb:> Dann ist der Puffer strIP zu klein oder ungültig.
Hatte ich auch schon dran gedacht jedoch habe ich bereits oben in der
Funktion direkt nach den anlegen der Lokalen Variablen versucht die
Puffers mit memset() mit 0 zu initialisieren. Jedoch ohne Erfolg.
Auch habe ich die Puffergröße von 10 test weiße mal auf 100 Bytes
vergrößert aber das Problem tritt dann immer noch auf.
Peter D. schrieb:> "Zeiger/Index - 1" sollte man generell vermeiden.
Ich kann mir vielleicht vorstellen warum wenn der Index 0 beträgt und
ich minus 1 rechne und die Variable vom Typ unsigned ist kann sie ja
nicht Negativ werden und es kommt zum Fehler oder?
Nur wie soll ich das ganze den anderes machen? Der Index ist nun mal
beim Aufruf schon 1 und ich muss es im Index des Arrays 0 speichern
alternativ könnte ich den Index 0 vom Array unbelegt lassen dann kann
ich ohne das minus 1 auskommen. Ist das die einzige Möglichkeit?
Johannes S. schrieb:> gibt es auch ein snprintf_P? Die n Versionen würde ich sowieso> bevorzugen.
Ich habe mal kurz geschaut also die Funktion gibt es. Wenn ich die
snprintf Funktion richtig verstehe übergibt man als zweites Argument die
Größe des Puffers damit die Funktion nicht mehr in den Puffer schreiben
kann als der groß ist und somit "Overflows" verhindert werden? Oder
warum ist Sie besser?
Johannes S. schrieb:> Das %03 nicht funktioniert und %3 doch hört sich ja schon nach einem> Grössenproblem an.
Grössenproblem? Ich meine ich brauche ja die führenden Nullen davor
damit der Text korrekt auf dem Display anzeigt wird. Arbeite jedoch auch
nicht zum ersten mal mit %03d bis jetzt hat das immer Problemlos
funktioniert.
Scheint irgendwie ein Problem mit den führenden Nullen zu seinen den %3d
lässt ja 2 Platz nach linkes ohne es mit nullen aufzufüllen.
Was ich aber einfach nicht verstehe warum funktioniert der Programmcode
wenn ich ich die normale sprintf Funktion verwende also den String in
den RAM lade?
Johannes S. schrieb:> Oder du hast dir vorher einen Stackfehler eingefangen, das macht sich> auch gerne erst später bemerkbar.
Ok oder auch nicht. Wie kann ich das jetzt ausfinden?
Felix N. schrieb:> Ich kann mir vielleicht vorstellen warum wenn der Index 0 beträgt und> ich minus 1 rechne und die Variable vom Typ unsigned ist kann sie ja> nicht Negativ werden und es kommt zum Fehler oder?
da macht dir der Compiler eine implizite Konvertierung und evtl. eine
Warnung. Aber das kann man doch einfach blocken wenn am Anfang der
Funktion eine Prüfung auf <= 0 mit Ausgabe von Fehlermeldung und return
gemacht wird.
Johannes S. schrieb:> da macht dir der Compiler eine implizite Konvertierung und evtl. eine> Warnung. Aber das kann man doch einfach blocken wenn am Anfang der> Funktion eine Prüfung auf <= 0 mit Ausgabe von Fehlermeldung und return> gemacht wird.
Hallo,
Achso du meinst das der Compiler dann aus dem uint8_t einfach ein int8_t
macht? Meinst du dann sowas?:
1
if(ipByteSelector <= 0) {
2
return;
3
}
4
5
//Sonst sprintf etc...
Werde ich mir mal im Hinterkopf behalten. Jedoch wenn ich aus der
sprintf Funktion die Variable eIP[ipByte... -2] raus nehme und dort fest
einfach zB. 50 reinschreibe. Tritt der Fehler ja immer noch auf.
Mfg
Felix N. schrieb:> Achso du meinst das der Compiler dann aus dem uint8_t einfach ein int8_t> macht?
Nein, der macht daraus ein unsigned int. Was an dem Problem nichts
ändert...
Oliver
Felix N. schrieb:> Hatte ich auch schon dran gedacht jedoch habe ich bereits oben in der> Funktion direkt nach den anlegen der Lokalen Variablen versucht die> Puffers mit memset() mit 0 zu initialisieren. Jedoch ohne Erfolg.
memset kann Deinen Puffer nicht vergrößern, ist hier also sinnlos.
Welche Größe hast Du denn memset übergeben?
Felix N. schrieb:> Der Index ist nun mal> beim Aufruf schon 1
Warum denn, hast Du irgendwo ein Increment an der falschen Stelle?
Wenn es für die Nutzeranzeige ist, dann rechne intern ab 0 und addiere 1
nur für die Anzeige.
Peter D. schrieb:> memset kann Deinen Puffer nicht vergrößern, ist hier also sinnlos.
Hi, ja ich weiß das memset die Größe nicht verändern kann aber damit
kann ich das Array initialisieren. Damit es nicht NULL ist. Im Moment
hat der Puffer strIP eine Größe von 100 Bytes.
Peter D. schrieb:> Welche Größe hast Du denn memset übergeben?
So habe ich es gemacht:
1
char strIP[10];
2
3
memset(strIP, 0x00, sizeof(strIP));
Peter D. schrieb:> Warum denn, hast Du irgendwo ein Increment an der falschen Stelle?> Wenn es für die Nutzeranzeige ist, dann rechne intern ab 0 und addiere 1> nur für die Anzeige.
Ja sorry, ich habe mir den Teil mit dem ipByteSelector angesehen ich
kann auch mit 0 anfangen warum ich da jetzt 1 genommen habe weiß ich
nicht mehr jedoch ist das nur ein Index im Code er wird also nie auf der
Anzeige erscheinen. Er ist nur dafür die Bytes in der IP-Adresse
auszuwählen da eine IPv4 Adresse 4 Bytes hat habe ich wahrscheinlich 1 =
1 Bytes, 2 = 2 Bytes etc... genommen. Das werde ich dann auf 0 abändern
also 0 = 1 Bytes etc...
Jedoch muss ich an einer Stelle immer noch -1 rechnen. Denn ich habe ja
immer noch die Abfrage drin wo geprüft wird ob der ipByteSelector größer
als 1 ist und wenn ja wird das vorherige Byte auf dem Display weiß
dargestellt und das neue Byte welches jetzt ausgewählt ist zum
bearbeiten in Rot. Da muss ich ja dann -1 rechnen um den vorherigen Wert
zu bekommen. Oder wie soll ich das da machen?
Es wird dort ja erst geprüft ob der Selector größer als 1 ist(Später
dann größer als 0 wenn ich es geändert habe). Wenn es so ist wird mit
fillrect der Bereich wo die Zahl steht(zB. 192) mit einem schwarzen
Kästchen überlagern damit die Zahlen sich nicht überlappen. Dann wird
mit snprintf_P der vorherige Wert entsprechend Formatiert mit führenden
Nullen. Und ili9341_combo ist eine Funktion die alles vereinigt also
Koordinaten setzten, Text/Hintergrundfarbe wählen, Schriftgröße etc...
und dann wird der vorherige Wert in Weiß wieder angezeigt.
Der Teil muss doch eigentlich Safe sein oder nicht? Weil ich prüfe doch
vorher ob ich den Selector - 1 nehmen darf durch die if Abfrage.
Aber es scheint irgend ein Problem mit den führenden Nullen zu seinen,
denn ich habe noch was raus gefunden den in einer anderen Funktion die
das Menü "malt" habe ich folgende Programmzeile drin:
Sie stellt die Server IP Adresse im Menü da. strBuffer ist ein Puffer
mit einer Größe von 400 Bytes und in der main.h angelegt ist der String
Puffer für alles(Debug, Menüs malen etc...)
Wenn ich dort das erste %d durch ein %03d ersetzte passiert noch nix
ersetze ich das zweite %d auch durch ein %03d so das ich dort
"%03d.%03d.%d.%d" stehen habe. Und das Menü aufrufe hängt sich der
Prozessor wieder auf sobald der das Menü darstellen will. Mache ich aber
wieder nur %3d bei allen 4 funktioniert es wieder Problemlos nur halt
ohne führenden Nullen dafür dann mit entsprechend vielen Leerzeichen
dazwischen.
Mfg
Hallo Philipp,
Philipp K. schrieb:> %d03.%d03
Du hast %d03 geschrieben. Versuchs mal mit %03d also 03 vor dem d. Bei
mir funktioniert das ganze schon. Aber halt nur mit der sprintf Funktion
ohne das _P am Ende.
Kann es ein das du die Arduino IDE nutzt? Ich weiß jetzt nicht sicher ob
es die "_P" Funktion in der Arduino gibt.
Mfg
Ups, ja mein Fail.
Reproduziere das doch mal selbst in einem gekürzten Code.
Ersetzte mal das sprintf durch eine Zuweisung des eigentlichen
Ergebnisses.. um Pufferüberläufe zu testen.
Edit: wieviel stellen sind in den String Arrays reserviert? Kann man mit
den schnippeln nur schätzen. Muss einer mehr für den Abschluss sein.
Eine IP bräuchte 17 arrayelemente
Philipp K. schrieb:> Ups, ja mein Fail.
Hallo,
Ich scheine wohl erstmal den Fehler gefunden zu haben. Ich habe gerade
einfach mal die changeIP() Funktion komplett ausgeblendet so das diese
nicht mehr aufgerufen wird.
Es gibt aber noch eine andere Funktion die nennt sich editIPs() diese
wird als erstes aufgerufen wenn man die IP-Adressen bearbeiten möchte
und markiert dann entsprechend den Namen der IP-Adresse in Rot so das
man weiß welche man ausgewählt hat.
Nachdem nur noch die editIPs() Funktion drin war und der Fehler immer
noch aufgetreten ist, also das sich der Controller aufhängt habe ich
diese Funktion auch mal ausgeblendet so das sie nicht mehr aufgerufen
wird. Danach hängt sich der Controller nicht mehr auf.
Also habe ich mir den Code nochmal genauer angeschaut. Dort habe ich
auch zwei lokale char Arrays einmal ipStr und preIpStr beide mit einer
Größe von 10 Bytes. Die Variable ipStr ist für die ausgewählte
IP-Adresse und preIpStr für die vorherige Adresse.
Da aber nicht immer eine vorherige Adresse vorhanden ist musste ich das
zweite Array dennoch belegen und zwar habe ich das so gemacht:
1
strcpy_P(preIpStr, NULL);
Habe jetzt test weiße das ganze durch folgendes ersetzt:
1
strcpy_P(preIpStr, PSTR(""));
Habe nämlich die Vermutung das das "NULL" daran schuld gewesen sein
könnte. Denn jetzt funktioniert der gesamte Code Problemlos. Warum aber
der Code teilweise funktioniert wenn man in einer anderen Funktion was
geändert hat. Keine Ahnung.
Werde es jetzt mal testen und weiter programmieren ob dieser Fehler
wirklich weg bleibt.
Ich habe mal meine ethernetMenu.c Datei angehängt.
Mfg
Was wird
strcpy_P(preIpStr, NULL);
Auf einem AVR wohl machen?
Es kopiert den Anfang des Flash bis zur ersten gefundenen '\0'. Und das
kann ein paar Bytes dauern, wenn die zig Int-Vectoren mit "JMP Badint"
vorgelegt sind.
Besser eine (falls verfügbar) "n"-Variante der Str-Routine benutzen.
Carl D. schrieb:> Es kopiert den Anfang des Flash bis zur ersten gefundenen '\0'.
Hallo Carl,
Das heißt wenn ich strcpy_P mit NULL als zweites Argument übergebe
kopiert er alles in den Puffer rein bis er ein \0 gefunden hat? Bedeutet
also zb. Wenn es von Flash Adresse 0x00 bis zum zB. 0xFF alles kopiert
weil 0xFF ein \0 beinhaltet?
Und da der Puffer nicht groß genug ist stürzt er dann ab? Richtig so?
Carl D. schrieb:> Besser eine (falls verfügbar) "n"-Variante der Str-Routine benutzen.
Ja es gibt eine strncpy_P Variante die will Quelle, Ziel und Größe als
Argumente haben. Quelle und Ziele ist ja klar und als Größe kann ich
dann einfach mit sizeof und dann die Größe des Puffers übergeben?
Also kann ich besser die "n" Funktion verwenden weil wenn er mehr Daten
kopiert/schiebt etc... die Funktion einfach aufhört wenn das Limit was
als dritte Argument übergeben wird überschritten wird? Oder steht dann
nur das bis zum Limit in Puffer?
Mfg
Felix N. schrieb:> Carl D. schrieb:>> Es kopiert den Anfang des Flash bis zur ersten gefundenen '\0'.>> Hallo Carl,>> Das heißt wenn ich strcpy_P mit NULL als zweites Argument übergebe> kopiert er alles in den Puffer rein bis er ein \0 gefunden hat? Bedeutet> also zb. Wenn es von Flash Adresse 0x00 bis zum zB. 0xFF alles kopiert> weil 0xFF ein \0 beinhaltet?>> Und da der Puffer nicht groß genug ist stürzt er dann ab? Richtig so?
Genau!
NULL aka 0 ist eine gültige Flash-Adresse. NULL als "nix" anzusehen ist
eine Vereinbarung (die auf mancher HW/manchen OS durchgesetzt wird, aber
auf AVR eben nicht). Denn Flash(0) beinhaltet (das erste Byte) eines
Sprungs zu "Start"-Routine. Was Konventions ist, daß GCC/AVRLibc die
Int-Vektoren zumindest mit einen Sprung zu BadInt() füllen. Das können
0-Bytes vorkommen, oder meist eben auch nicht. Danach kommen dann (falls
C++) Adressen der Initialisierungsroutinen für globale Objekte. Dann
eventuell benutzte PROGMEN Strings. Letztere würden die Kopierwut von
strcpy_P() bremsen, aber da ist es sicher schon zu spät.
> Carl D. schrieb:>> Besser eine (falls verfügbar) "n"-Variante der Str-Routine benutzen.>> Ja es gibt eine strncpy_P Variante die will Quelle, Ziel und Größe als> Argumente haben. Quelle und Ziele ist ja klar und als Größe kann ich> dann einfach mit sizeof und dann die Größe des Puffers übergeben?>> Also kann ich besser die "n" Funktion verwenden weil wenn er mehr Daten> kopiert/schiebt etc... die Funktion einfach aufhört wenn das Limit was> als dritte Argument übergeben wird überschritten wird? Oder steht dann> nur das bis zum Limit in Puffer?>> Mfg
Die Funktion kennt vom Ziel nur die Adresse, die Länge muß zusätzlich
mitgegeben werden, andernfalls kommt die Länge aus der Quelle, und zwar
nach der C-String-Konvention "endet mit '\0'".
Felix N. schrieb:> strcpy_P(preIpStr, NULL);
Das ist natürlich ganz großer Mist.
NULL nimmt man, um einen Pointer als ungültig zu kennzeichnen, d.h. mit
einem solchen Pointer dürfen auf keinen Fall irgendwelche Aktionen
erfolgen.
Erlaubt ist nur, einen solchen Pointer auf NULL zu testen oder ihm eine
gültige Adresse zuzuweisen.
Z.B. malloc liefert NULL, wenn kein Speicher belegt werden konnte.
Carl D. schrieb:>> NULL aka 0 ist eine gültige Flash-Adresse. NULL als "nix" anzusehen ist> eine Vereinbarung (die auf mancher HW/manchen OS durchgesetzt wird, aber> auf AVR eben nicht).
Ist aber völlig egal, die Verwendung von NULL als *src ist schlicht
falsch, und führt zum Fehler.
Oliver
Carl D. schrieb:> NULL aka 0 ist eine gültige Flash-Adresse.
Nur stehen dort keine Strings, sondern Befehle.
D.h. man könnte höchstens dahin springen, um einen SW-Reset zu bewirken.
Carl D. schrieb:> Genau!Oliver S. schrieb:> ist schlicht> falsch, und führt zum Fehler.
Hallo nochmal,
Ach ja selbst eingebaute Fehler sind ja eh die besten :)
Peter D. schrieb:> Nur stehen dort keine Strings, sondern Befehle.
Eine Frage bleibt mir da noch. Wenn strcpy im Flash an der Adresse 0
angefangen hat und bis zu einem \0 gesucht hat aber am Anfang nur
Befehle stehen wieso kann es dann sein das wenn ich teilweise String
Funktion ohne _P verwende ohne andere String Funktion ausblende das der
Programmcode trotzdem funktioniert?
Peter D. schrieb:> NULL nimmt man, um einen Pointer als ungültig zu kennzeichnen
Ach so ok. Ich dachte das wenn ich als weites Argument NULL übergebe das
er in den String dann einfach auf 0 setzt. Da lag ich wohl daneben.
Immerhin etwas neues dazu gelernt :)
Also ich habe meine Funktion nun fast vervollständigt es fehlt jetzt nur
noch der Teil mit dem Server Port dann ist sie fertig. Bis jetzt trat
der Fehler nicht mehr auf. Ich denke mal das es dann wirklich nur an dem
NULL lag.
Möchte mich auf jeden Fall bei allen die mir hierbei geholfen haben
Bedanken!
Vielen Dank an euch!
Mfg
Felix N. schrieb:> wieso kann es dann sein das wenn ich teilweise String> Funktion ohne _P verwende ohne andere String Funktion ausblende das der> Programmcode trotzdem funktioniert?
Weil an RAM-Adresse 0 das Register r0 gemappt ist, und das wird vom gcc
dauerhaft auf den Wert 0 gesetzt.
Oliver
Für alle die das vielleicht falsch verstanden haben könnten:
Ich hab beschrieben, was konkret auf der HW passiert und nicht zum
Ausdruck bringen wollen, daß was der TO "codiert" hat richtig wäre.
Offensichtlich ist es falsch, denn es führt zum Chaos. Den Weg dorthin
wollte ich ihm erklären.
Felix N. schrieb:> Peter D. schrieb:>> NULL nimmt man, um einen Pointer als ungültig zu kennzeichnen>> Ach so ok. Ich dachte das wenn ich als weites Argument NULL übergebe das> er in den String dann einfach auf 0 setzt. Da lag ich wohl daneben.> Immerhin etwas neues dazu gelernt :)Felix N. schrieb:> Habe jetzt test weiße das ganze durch folgendes ersetzt:> strcpy_P(preIpStr, PSTR(""));
Was Du eigentlich willst ist: