PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Häufiger Einsatz von SerPrint(); führt zu großen Problemen



ElTransistor
17.11.2007, 17:12
hi,

ich hab nun ein neues projekt angefangen, und wie hätte es auch anders sein können, habe ich schon wieder ein unlösbares problem welches wohl auch dieses gefährdet und mir den spass endgültig verdirbt :(

es geht um folgende: ich mache gerade ein kleines programm welches mit dem hyperterminal arbeitet und ihm bei unterschiedlichen zuständen unterschiedliche sachen per SerPrint(); schickt. soweit so gut. das hat auch wunderbar funktioniert, bis zu einer bestimmten anzahl an gespeicherten strings. sobald ich sie überschreite, fängt der asuro an, sämtliche strings in einen topf zu schmeissen, und über serprint einfach irgendeinen müll auszugeben.

da ich davon ausgegangen bin dass er ungefähr 8K ROM hat, wovon ich evtl 6-7K für meine sachen verwenden kann, müssten es schon einige tausend zeichen sein die er ohne probleme speichern sollte.
mein problem fängt aber schon bei ~600 zeichen an, was doch eigentlich schon sehr weit unterhalb der grenze liegen sollte..

ich habe hier einen kleinen test-code erstellt um mein problem zu verdeutlichen: (einige stellen des codes sind auskommentiert, erklärung weiter unten)


#include "asuro.h"

int main(void) {

Init();

SerPrint("00ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("01ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("02ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("03ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("04ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("05ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("06ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("07ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("08ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("09ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("10ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("11ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("12ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("13ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("14ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("15ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("16ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("17ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("18ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("19ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("20ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("21ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
/*SerPrint("22ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("23ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("24ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("25ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("26ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("27ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("28ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("29ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
*/


while(1);
return 0;
}

wenn ich das an das terminal sende, kommt folgendes raus:




05ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ
06ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ
07ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ
08ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ
09ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ
10ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ
11ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ
12ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ
13ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ
14ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ
15ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ
16ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ
17ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHI18ABCDEFGHIJK LMNOPQRSTUVWXYZABCDEFGHIJKLMNO
PQRSTUVWXYZ
19ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ
20ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ
21ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ


man beachte dass es in der 5. zeile erst anfängt und dass die 18. zeile komplett zerhackt ist. (der fehler ist reproduzierbar und liegt nicht an der ir-verbindung).
wenn ich die auskommentierten stellen des codes noch hinzufüge, wird es noch viel hefitger, dann kommen noch mehr verwirrte zeichen an. jetzt würde ich gerne wissen, woran das liegt. wieso geht es nicht, und warum fängt das problem schon bei so relativ wenigen zeichen an? was mache ich falsch? was kann ich anders machen?

danke schonmal..

liggi
17.11.2007, 17:37
Der Asuro hat nur 1k Rom. Er 8k hat flash-speicher, wo bei schon 1k vom Bootloader besetzt sind. (s. https://www.roboternetz.de/wissen/index.php/Asuro) Das dürfte die Lösung sein.

mfg liggi

ElTransistor
17.11.2007, 17:44
ok hab das durcheinander gebracht. aber das macht ja nichts, die teile werden in den rom geladen, ausgeführt, und wieder gelöscht. (zumindest sollten sie das) und beim nächsten funktionsaufruf wieder ins rom geladen.


oder nich? (bzw da es wohl nich so is, wie bring ich ihn dazu?) ;)

damaltor
17.11.2007, 18:36
das problem ist, dass die strings so wie du sie verwendest, zuerst in eine zwischenvariable im RAM geladen werden... und da der deutlich kleiner ist als die menge der zeichen die du senden willst (1024 bytes) läuft er ganz stumpf über. ;)

das hier könnte dir helfen, macht zwar die arbeit etwas umständlicher, sorgt aber dafür dass die strings im flash gespeichert werden und auch direkt von dort gelesen werden:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_(Flash)
achte auf die includes!!! etwas weiter unten ist ein absatz über strings, trotzdem solltest du zuerst die grundlagen oben lesen.

ElTransistor
17.11.2007, 23:49
ok danke schonmal..ich verstehe zwar noch nich was da geschrieben steht, aber ich werde es mir nochmal durchlesen..

ElTransistor
18.11.2007, 03:34
guten morgen O:)

ich hab mich nochmal hingesetzt und denke dass ich das vom mikrocontroller.net verstanden habe, war doch nich so viel. aber lösen tut es mein problem nich.

soweit ich verstanden habe muss ich den code in folgendes ändern:

#include "asuro.h"
#include "avr/io.h"
#include "avr/pgmspace.h"
#include "string.h"

int main(void) {

Init();

const char a[] PROGMEM ="00ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char b[] PROGMEM ="01ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char c[] PROGMEM ="02ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char d[] PROGMEM ="03ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char e[] PROGMEM ="04ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char f[] PROGMEM ="05ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char g[] PROGMEM ="06ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char h[] PROGMEM ="07ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char i[] PROGMEM ="08ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char j[] PROGMEM ="09ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char k[] PROGMEM ="10ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char l[] PROGMEM ="11ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char m[] PROGMEM ="12ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char n[] PROGMEM ="13ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char o[] PROGMEM ="14ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char p[] PROGMEM ="15ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char q[] PROGMEM ="16ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char r[] PROGMEM ="17ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char s[] PROGMEM ="18ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char t[] PROGMEM ="19ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char u[] PROGMEM ="20ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
const char v[] PROGMEM ="21ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n";
/*SerPrint("22ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("23ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("24ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("25ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("26ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("27ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("28ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
SerPrint("29ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV WXYZ\r\n");
*/


SerPrint(a);
SerPrint(b);
SerPrint(c);
SerPrint(d);
SerPrint(e);
SerPrint(f);
SerPrint(g);
SerPrint(h);
SerPrint(i);
SerPrint(j);
SerPrint(k);
SerPrint(l);
SerPrint(m);
SerPrint(n);
SerPrint(o);
SerPrint(p);
SerPrint(q);
SerPrint(r);
SerPrint(s);
SerPrint(t);
SerPrint(u);
SerPrint(v);


while(1);
return 0;
}

wenn ich das tue startet asuro aber mit allen led's auf rot und stürzt ab :-({|=

also entweder hab ich das falsch gemacht, oder es wird irgendwas erzeugt was ihn noch mehr belastet...

damaltor
18.11.2007, 04:27
nicht SerPrint(xx); sondern SerPrint(PSTR(xx));

ist recht verschachtelt, ich weiss... alternativ kannst du auch folgendes mal testen:
SerPrint(PSTR("Text zum ausgeben\n\r"));

ElTransistor
18.11.2007, 04:56
nicht SerPrint(xx); sondern SerPrint(PSTR(xx));


will er nicht kompillieren!


alternativ kannst du auch folgendes mal testen:
SerPrint(PSTR("Text zum ausgeben\n\r"));

geht, aber dann sendet er auch nur 1 zeichen und verstummt.

im mikrocontroller.net steht ja "Zeichenketten können innerhalb des Quellcodes als "Flash-Konstanten" ausgewiesen werden. Dazu dient das Makro PSTR aus pgmspace.h. Dies erspart die getrennte Deklaration mit PROGMEM-Attribut."

das bedeutet doch dass das nur ein ersatz für progmem ist?

izaseba
18.11.2007, 10:27
Hallo,
leider ist es nicht so einfach Sachen aus dem Flash zu lesen, das bedarf einer Sonderfunktion, ich poste einfach mal ein Ausschnitt:


void push_flash(const char *string){
char zeichen;
while((zeichen = pgm_read_byte(string))) {
while(!(UCSRA&(1<<UDRE)));
UDR = zeichen;
string++;
}
}

So, an diese Funktion kann man dann Flashstrings überbeben z.B so


push_flash(PSTR("Hallo, ich bin im Flash!\r\n"));


Ich hoffe geholfen zu haben

Gruß Sebastian

damaltor
18.11.2007, 14:53
stimmt. hätte mal genauer lesen können... 0_o genau so ist es bei mir auch...

ElTransistor
18.11.2007, 20:26
hi sebastian, du hast mir sozusagen zu 50% geholfen ;)

denn wenn ich "zeichen" dann ausgebe kommt im HT folgendes an:


 Flash!øþ O†Å

izaseba
19.11.2007, 00:26
Hallo ElTransistor,

Hmm,
ich sehe gerade, daß es Probleme geben könnte, weil ich die Senderoutine einfach aus irgendeinem meiner 'nicht Asuro' Programme rauskopiert habe, und da gibt es leider kleine diferenzen.

Versuch es mal damit:


void push_flash(const char *string){
char zeichen;
while((zeichen = pgm_read_byte(string))) {
Uart_Putc(zeichen);
string++;
}
}

Ich hoffe damit erreichst Du Dein Vorhaben.

Gruß Sebastian

ElTransistor
19.11.2007, 20:56
hi..

ich hab das gestern nacht nochmal versucht, und zuerst hat es wunderbar geklappt! aber als ich dann die funktion in mein programm übernommen habe hat er wieder nur zeichen ausgespuck..und dann hab ichs nochmal von dir kopiert und nun geht es auch mit deinem beispiel nicht ](*,)


#include "asuro.h"
#include "avr/io.h"
#include "avr/pgmspace.h"
#include "string.h"

void push_flash(const char *string){
char zeichen;
while((zeichen = pgm_read_byte(string))) {
UartPutc(zeichen);
string++;
}
}

int main(void) {
Init();
push_flash("lskjdhflkajshdlfkjhslkdjfhlkjhlkj");
return 0;
}



liefert
ß“ìÀ$Ñ!–þ„‘ˆ#Ñ÷ß‘Ï•«Ð€æàï߀à•’’¶’$“Ÿ“¯“ ¿“„µ‹]„½€‘

ich weiß nur nich warum das einmal ging und dann wieder nicht..

izaseba
19.11.2007, 21:07
Hallo ElTransistor,

2 Probleme:

1. ich habe geschrieben


push_flash(PSTR("Hallo, ich bin im Flash!\r\n"));


Du aber


push_flash("lskjdhflkajshdlfkjhslkdjfhlkjhlkj");


Na Fehler gefunden ?

2.
Ich vermisse eine Endlosschleife in deinem Programm, das ist nicht gut.

Gruß Sebastian

ElTransistor
19.11.2007, 21:51
AH du hast recht! ja das ist der nachteil wenn man nachts noch prgrammieren will :-({|=

ich glaube das war es, man ich hasse es immer diese kleinigkeiten zu übersehen:(

thx!

damaltor
21.11.2007, 13:54
sowas ist in assmbler ja recht elegant zu lösen... aber da sieht man ganz gut die grenzen dec compilers :P

MartinFunk
21.11.2007, 16:40
Hi,
Steht nicht am ende eines Strings eine Dezimal "0"?

MfG Maritn

izaseba
21.11.2007, 18:40
Hallo Damaltor ,


sowas ist in assmbler ja recht elegant zu lösen... aber da sieht man ganz gut die grenzen dec compilers

Versteh ich nicht so recht, was Du meinst, warum erreicht der Kompiler hier seine Grenzen ? :-k

Meinst Du, weil man nicht so einfach aus dem Flash lesen kann?
Wenn ja liegt das nicht am Kompiler, sondern an der AVR Architektur würde ich mal sagen.
Trotzdem haben die avr-gcc Macher die Problematik gut gelöst, man muß es nur wissen !

@Martin Funk ,
Du hast recht, ich weiß aber nicht recht, worauf Du hinauswillst.

Gruß Sebastian

stochri
21.11.2007, 19:37
sag mal, izaseba, warum nennst Du Deine Routine eigentlich "push_flash". Um etwas zu holen, nimmt man doch normalerweis "pop" statt push

izaseba
21.11.2007, 19:52
Hi stochri,
nun ja, kommt drauf an, von welcher Seite man das ganze sieht ;-)

Hier sehe ich das von der UART Seite...

man könnte auch getfromflashandputinuart sagen, oder weiß was ich.
die Routne pushed ja was in UART (poped aber aus den flash #-o )

Ehrlichgesagt habe ich mir keine Gedanken darüber gemacht \:D/
Schlag was sinvolles vor, dann benenne ich sie um O:)

Gruß Sebastian

damaltor
21.11.2007, 20:24
Hi,
Steht nicht am ende eines Strings eine Dezimal "0"?

MfG Maritn

ja, diese wird jedoch vom compiler erzeugt wenn das array lang genug istt oder keine feste länge hat.

stochri
21.11.2007, 23:14
Schlag was sinvolles vor, dann benenne ich sie um Angel

Es ist mir nur so in's Auge gefallen, es stört nicht weiter, Du kannst es ruhig so lassen.

Bester Gruß,
stochri