Hi,
mal wieder so ein PROGMEM Problem. Habe schon einige Beitraege und
Tutorials durchgelesen. Im Prinzip ja immer das selbe: Pointer aus Flash
lesen(pgm_read_word ), an x_P function uebergeben, die wiederum mit
pgm_read_byte liest.
Beim debugger wird mir aber gar nichts klar. Schau ich mir die Struktur
1
typedef struct {
2
PGM_P pcCmd;
3
const PF_GSM_IF pfCmd;
4
} PACKED ST_STR_RESLV;
wird fuer pcCmd statt 0x65(Byte-Adresse) wird 0x2465(invalid) angezeigt
1
.progmem.data 0x00000054 0x1e gsm_com.o
2
...
3
0x00000054 g_stCmdSmpl
4
0x00000065 g_strCSQ
5
0x0000005c g_stCmdBase
fuer pfCmd statt 0x0068 wird 0x2468(invalid) angezeigt.
0x65 / 2 = Wordadresse im Flash(jedoch 0x32)
0x68 * 2(warum?) = Adresse in Map fuer Function 0xD0
1
.text 0x000000b0 0x16a main.o
2
0x000000d0 SetNiveuVal
3
0x000001a8 Init
Es werden Strings aus dem Flash ueber put0text_P() normal geprintet.
Ebenso werden zeichen aus dem Flash gelesen und geprintet mittels
put0byte().Jedoch Strings welche erst referenziert werden muessen
crashen das system.
Vielleicht kann mir bitte jemand einen Hinweis geben.
Hier der Code:
daniel schrieb:> Vielleicht kann mir bitte jemand einen Hinweis geben.
Nicht 100% sicher
> #define PCHAR(c) ((const char PROGMEM)(c))
...
> const ST_BYTE_RESLV g_stCmdBase[] PROGMEM => {> // ...> {PCHAR('+'),GSM_CmdExt0},
Ich denke nicht, dass das das macht, was du erwartest.
Das hier
> #define PCHAR(c) ((const char PROGMEM)(c))
ist letztendlich einfach nur ein simpler cast. Er veranlasst aber nicht,
dass
a) c ins Flash geschoben wird
b) Der ganze Ausdruck als die Adresse von "c-im_Flash" evaluiert.
Sieh dir an, wie zb PSTR in pgmspace.h definiert ist.
Jaja. Wieder mal ganz sorgfältig überlegt und dann flach durch die kalte
Küche in die Ecke geschossen. ;-)
P.S.
Ist nicht böse gemeint, haben wir alle schon mal gemacht.
geht es ja um g_stCmdExt0 und nicht um g_stCmdBase.
Mann, dein ewiges Rumgecaste nervt.
Merk dir eines: Wenn du alles und jedes ständig rum casten musst, dann
ist etwas oberfaul. In einem korrekten Programm braucht man wenige
Casts.
Merk dir auch: Ein Cast ist eine Waffe, die du niemals leichtfertig
einsetzen willst. Mit einem Cast hebelst du das Typsystem in C (das
sowieso nicht das beste ist) komplett aus. Ein Cast ist das Äquivalent
zu einem bewaffneten Raubüberfall: Du tust jetzt was ich dir anschaffe,
oder ...
Kannst du das nicht mal ein wenig abspecken, da verliert man komplett
den Überblick, wer nun wo und worauf zugreift.
logo, crasht das.
EN_AT_CSQ ist 2, damit greifst du hier
1
....g_stCmdExt0[ubCmd-EN_AT_SEP_EXT+1]....
auf ein Element zu, welches laut
1
constST_STR_RESLVg_stCmdExt0[]PROGMEM=
2
{
3
{(PGM_P)(g_strCSQ),SetNiveuVal}
4
};
nicht existiert.
ubCmd - EN_AT_SEP_EXT + 1 ergibt 2 - 1 + 1 -> 2
g_stCmdExt0 hat aber nur 1 Element, daher ist 0 der einzig zulässige
Index.
Ich vermute mal, das hätte eigentlich
Die casts sind erst im nachhinein gekommen, weils nicht funktionierte.
Aber vielen Dank fuer den Hinweis, ich werde es auf ein minimum
reduzieren und nochmal posten.
2.
1
ubCmd - EN_AT_SEP_EXT + 1 ergibt 2 - 1 + 1 -> 2
Vielen Dank, logisch das es schief geht, da fehlen die Klammern?! (oder
-1). Wie immer: Imaginaere Klammern nuetzen nichts!
3.
1
da muss schon etwas mehr Aufwand getrieben werden, um etwas inline ins
2
Flash zu legen.
Vielen Dank, dass schau ich mir nochmal an. Jedes Byte zaehlt.
Nochmals vielen Dank, heute abend wirds getestet und ich werd mich
melden.
daniel
Hi,
@Karl heinz Buchegger
Vielen Dank! Das was du in den zwei Stunden geloest hast, ist mir in 3
Tagen nicht aufgefallen. Das war das Problem, deswegen ist mir das
gesamte System abgestuerzt.
Hier noch mal der korrigierte Code:
1
// protocol processing
2
typedef uint8_t (*PF_GSM_IF) (uint8_t*);
3
4
// string resolving tab
5
typedef struct {
6
PGM_P pcCmd; // constant pointer to string in flash
7
const PF_GSM_IF pfCmd; // constant pointer to function in flash
8
} PACKED ST_STR_RESLV;
9
10
// char resolving tab
11
typedef struct {
12
const prog_char cCmd; // constant character in flash
13
const PF_GSM_IF pfCmd; // constant character in flash