//Len ist wichtig um Data später rechtsbündig darzustellen
16
char*p=m->name;//char* name: Zeiger auf array im Flash
17
while(c=pgm_read_byte(p++))//nächtes Byte lesen und Zeiger um 1 erhöhen Z.26 5. Warnung
18
{
19
len--;
20
lcd_putc(c);
21
}
22
lcd_putc(':');
23
lcd_putc(' ');
24
//Der rest ist zurzeit auskommentiert und daher unwichtig, da schon das nicht funktioniert.
25
//[...]
26
}
Problem ist aber, wenn ich den einen Menüeintrag auf dem Lcd ausgeben
will, erscheint nur Murks. Die "1 " erscheint noch, dann kommen aber ein
wildes Sammelsurium.
Ich vermute das der µC irgendwo liest wo er nicht lesen soll. Kurzzeitig
wird der volle Block auf dem ganzen Display angezeigt. Er liest also
erstmal länger 0xFF im leeren Flash.
Ich habe mal die HexDatei nach 0x00 durchsucht, aber nichts gefunden. Er
könnte höchstens im Bootloader zum stoppen kommen. Sonst fällt mir keine
Stelle ein, wo noch 0x00 sein könnte.
Der Compiler zeigt ein paar Warnungen an. Ich wüsste aber nicht was ich
da casten sollte:
1
7 [Warning] initialization discards qualifiers from pointer target type
2
7 [Warning] initialization discards qualifiers from pointer target type
3
7 [Warning] initialization discards qualifiers from pointer target type
4
8 [Warning] initialization discards qualifiers from pointer target type
5
26 [Warning] suggest parentheses around assignment used as truth value
@ Samuel K. (sam1994)
>void do_menu(Menu m)>{> lcd_clear();> lcd_setcursor(0,1);> write_entry(1, m.entry[0]);
Hier gibt es AFAIK schon Probleme, weil eben dein Menu im PROGMEM liegt,
Zugriff geht nur über pgm_read_byte etc.
> char* p = m->name; //char* name: Zeiger auf array im >Flash
char* ist ein Zeiger auf den RAM. Für Flash gibt es extra PGM_P, siehe
doku der libc. Aber auch hier gibt es wahrscheinlich ein
Dereferenzierungsproblem.
Ne Lösung hab ich aber nicht :-0
MFG
Falk
Falk Brunner schrieb:>>void do_menu(Menu m)>>{>> lcd_clear();>> lcd_setcursor(0,1);>> write_entry(1, m.entry[0]);>> Hier gibt es AFAIK schon Probleme, weil eben dein Menu im PROGMEM liegt,> Zugriff geht nur über pgm_read_byte etc.
Danke, das hab ich glatt vergessen zu lesen. Mal schauen ob das hilft.
>> char* p = m->name; //char* name: Zeiger auf array im >Flash>> char* ist ein Zeiger auf den RAM. Für Flash gibt es extra PGM_P, siehe> doku der libc. Aber auch hier gibt es wahrscheinlich ein> Dereferenzierungsproblem.
Das wusste ich nicht genau und hab dann einfach einen char* Zeiger
genommen. Solange ich den über pgm_read_byte aufrufe dürfte das doch
trotzdem passen, oder nicht?
Ein paar 0x00 sind übrigens doch in der Hex-Datei. Ich dachte der
Hexreader unterstützt .hex Dateien. Das er die nicht unterstützt merkte
ich daran, dass die Code angeblich 4,6KB groß sei.
Falk Brunner schrieb:> char* ist ein Zeiger auf den RAM. Für Flash gibt es extra PGM_P,
Zeiger ist Zeiger. PGM_P ist in erster Linie was fürs Auge.
So auf die Schnelle:
//Len ist wichtig um Data später rechtsbündig darzustellen
16
char*p=pgm_read_word(m->name);//char* name: Zeiger auf array im Flash
17
while(c=pgm_read_byte(p++))//nächtes Byte lesen und Zeiger um 1 erhöhen
18
{
19
len--;
20
lcd_putc(c);
21
}
22
lcd_putc(':');
23
lcd_putc(' ');
24
}
@Stefan
Deine Vorschläge machen es auch besser, allerdings erscheint das Test:
in der 2. Zeile. Also sind >40 falsche Zeichen dazwischen.
Entry ist übrigens schon ein Pointer, siehe Definition. Da muss das "&"
dann weg.
Irgendwie glaub ich grad, dass Assembler hier unkomplizierter wäre, da
man nicht auf so ein Pointer pgm Zeug aufpassen muss.
Stefan Ernst schrieb:> PS:> Und was die Warnungen angeht: da fehlen diverse "const" in den> Struct-Definitionen.
Hmm, ich hab alle PROGMEM mit einem const ausgestattet. Google meint
auch was mit const, aber ich wüsste nicht wohin damit.
Nochmal langsam:
write_entry(1, *);
Hier muss man einen Zeiger MenuEntry* übergeben.
m.entry[0] ist der Zeiger auf den Flash
man liest also pgm_read_byte(m.entry[0])
dann bekommt man das 1. Byte vom MenuEntry
davon den Zeiger ergibt die Startadresse:
Ich hatte eine falsche Vorstellung der Flashsyntax.
Wenn man eine Konstante als PROGMEM deklariert ist sie immer ein Zeiger.
Den man auch erst auslesen muss. Erst danach hat sie den "deklarierten"
Wert.
PS: Der Rest des Programms funktioniert jetzt auch. Danke nochmals.
Was noch offen bleibt wäre wie ich die Warnungen entferne. Wäre nett
wenn mir jemand kurz sagt wo noch ein const hinmuss.
Und warum man Menu als Zeiger übergeben muss.
Was mich noch wundert ist, dass obwohl
1
33 [Warning] passing argument 1 of 'do_menu' discards qualifiers from pointer target type
diese Warnung ausgespuckt wird, es trotzdem funktioniert.
In do_menu gebe ich &optionen an.
Samuel K. schrieb:> Wenn man eine Konstante als PROGMEM deklariert ist sie immer ein Zeiger.
Nein, es ist genau das, als was man es deklariert hat. Aber die
Funktionen zum Auslesen dieses "etwas" aus dem Flash brauchen natürlich
die Adresse von diesem "etwas", daher immer das & bei den
Funktionsargumenten.
Samuel K. schrieb:> Wäre nett> wenn mir jemand kurz sagt wo noch ein const hinmuss.
Na überall dort, wo du dann auch "const-Sachen" einträgst. Beispiel:
wenn die Menü-Einträge alle im Flash liegen, dann sollte entry in
Menu doch wohl ein Array aus "const MenuEntry*" sein.
Samuel K. schrieb:> Initialisiere ich die Union falsch?
Bei MenuEntry.len schreibst du bei der Initialisierung doch auch direkt
eine 4 rein. Warum glaubst du, bei der Union die Zahlen vorher irgendwie
im Flash ablegen zu müssen?
Samuel K. schrieb:> Die anderen Warnungen kommmen übirgens immer noch, obwohl ich vor jedem> Menu und Entry ein const stehen habe.
1) Und warum sehe ich in dem geposteten Code davon nichts?
2) Du hast ja auch noch mehr Konstanten im Flash, z.B. die Strings.
Stefan Ernst schrieb:> Samuel K. schrieb:>> Initialisiere ich die Union falsch?>> Bei MenuEntry.len schreibst du bei der Initialisierung doch auch direkt> eine 4 rein. Warum glaubst du, bei der Union die Zahlen vorher irgendwie> im Flash ablegen zu müssen?
Stimmt daran hab ich irgendwie nicht gedacht.
> Samuel K. schrieb:>> Die anderen Warnungen kommmen übirgens immer noch, obwohl ich vor jedem>> Menu und Entry ein const stehen habe.>> 1) Und warum sehe ich in dem geposteten Code davon nichts?
Die Warnungen kommen bei den MenuEntry und Menu Definitionen. Die sind
aber schon const. Kann es sein, dass man bei manchen Angaben für die
Struktur ein (const) davor schreiben muss?
> 2) Du hast ja auch noch mehr Konstanten im Flash, z.B. die Strings.
Bei den Strings steht doch immer ein const davor. Verstehe ich dich da
irgendwie falsch?
Sam schrieb:> Kann es sein, dass man bei manchen Angaben für die> Struktur ein (const) davor schreiben muss?
Natürlich. Ich dachte eigentlich, das längst geschrieben zu haben:
Stefan Ernst schrieb:> Beispiel:> wenn die Menü-Einträge alle im Flash liegen, dann sollte entry in> Menu doch wohl ein Array aus "const MenuEntry*" sein.
Falk Brunner schrieb:> Das const hat auf die Sache mit dem Flash keinerlei Einfluss beim AVR> GCC.
Hat ja auch keiner behauptet. Es geht um das Entfernen von Warnungen.