Hallo,
ich versuche das speicherintensive Menü vom SRAM in den Flash zu
bekommen. Jedoch scheitere ich an den vorhandenen structures, die sich
scheinbar nicht in den Flash verschieben lassen wollen. Zumindest
menu_entry_t, dass nach der Initialisierung konstant bleibt, könnte man
ja in den Flash verschieben.
Hat jemand Tips wie ich das bewerkstelligen kann?
Danke für den Vorschlag, hab diese Variante auch schon ausprobiert,
jedoch kommen dabei einige Fehlermeldungen:
menu.c:92: error: syntax error before "__attribute__"
menu.c:94: error: field name not in record or union initializer
menu.c:94: error: (near initialization for `Zeit')
menu.c:94: warning: missing braces around initializer
menu.c:94: warning: (near initialization for `Zeit.entry')
menu.c:94: warning: initialization makes integer from pointer without a
cast
menu.c:94: error: initializer element is not computable at load time
menu.c:94: error: (near initialization for `Zeit.entry[0].flags')
menu.c:95: warning: excess elements in struct initializer
menu.c:95: warning: (near initialization for `Zeit')
menu.c:95: error: unknown field `name' specified in initializer
menu.c:95: warning: excess elements in struct initializer
menu.c:95: warning: (near initialization for `Zeit')
menu.c:96: error: unknown field `value' specified in initializer
menu.c:96: warning: excess elements in struct initializer
menu.c:96: warning: (near initialization for `Zeit')
menu.c:98: error: syntax error before '{' token
Ich komme nur durch Aufteilung der verschachtelten Struktur um das
Problem herum:
1
#include<avr/io.h>
2
#include<avr/pgmspace.h>
3
4
typedefunsignedcharuint8_t;
5
6
#define MENU_ENTRY_NAMELEN 42
7
#define NULL ((void *)0)
8
#define vEditTime ((void *)1234)
9
#define vEditDate ((void *)5678)
10
11
typedefstructmenu_entry_s{
12
uint8_tflags;
13
void(*select)(uint8_t*value,char*name);
14
charname[MENU_ENTRY_NAMELEN];
15
void*value;
16
}PROGMEMmenu_entry_t;
17
18
typedefstructmenu_s{
19
uint8_ttop_entry;
20
uint8_tcurrent_entry;
21
uint8_tnum_entries;
22
structmenu_s*previous;
23
menu_entry_t*entry;// <===
24
}menu_t;
25
26
menu_entry_tprogmem_entry[]={// <===
27
{.flags=0,
28
.select=vEditTime,
29
.name="Uhrzeit",
30
.value=0,
31
},
32
{.flags=0,
33
.select=vEditDate,
34
.name="Datum",
35
.value=0,
36
},
37
};
38
39
menu_tZeit={
40
.top_entry=0,
41
.current_entry=0,
42
.entry=progmem_entry,// <===
43
.num_entries=2,
44
.previous=NULL,
45
};
46
47
intmain(void)
48
{
49
return0;
50
}
Ich erkläre mir das so, dass im Ausgangsfall die im SRAM abgelegte
Struktur gleichzeitig einen Teil haben soll, der im FLASH liegt - das
ist ein Widerspruch in sich.
Was geht und hier gemacht wurde: die Struktur 1 liegt im FLASH und der
Zeiger auf diese Struktur wird in die Struktur 2 im Flash eingebunden.
Man "opfert" einen Zeiger (2 Bytes) pro Struktur 2
Allerdings kommt dann noch die berechtigte Warnung:
../Main.c:12: warning: only initialized variables can be placed into
program memory area
Also noch initialisieren:
Danke für die Hilfe. Ich hab nun die obige Variante von Stefan mit der
Trennung der beiden structs vorgenommen. Irgendwas mach ich aber noch
immer beim Auslesen falsch, da ich weder 3 noch 4 angezeigt bekomme.
1
#include<avr/io.h>
2
#include<avr/pgmspace.h>
3
4
typedefunsignedcharuint8_t;
5
6
#define MENU_ENTRY_NAMELEN 42
7
#define NULL ((void *)0)
8
#define vEditTime ((void *)1234)
9
#define vEditDate ((void *)5678)
10
11
typedefstructmenu_entry_s{
12
uint8_tflags;
13
void(*select)(uint8_t*value,char*name);
14
charname[MENU_ENTRY_NAMELEN];
15
void*value;
16
}PROGMEMmenu_entry_t;
17
18
typedefstructmenu_s{
19
uint8_ttop_entry;
20
uint8_tcurrent_entry;
21
uint8_tnum_entries;
22
structmenu_s*previous;
23
menu_entry_t*entry;
24
}menu_t;
25
26
27
menu_entry_tzeitsub[]={
28
{.flags=3,//<== Dieser Wert soll ausgelesen werden
>Irgendwas mach ich aber noch>immer beim Auslesen falsch, da ich weder 3 noch 4 angezeigt bekomme.
Das PROGMEM gehört in die Variablendeklaration, nicht in die
Typdefinition.
Also: