Forum: Mikrocontroller und Digitale Elektronik Problem mit pgm_read_word_far


von Der T. (Gast)


Lesenswert?

Hi,

ich versteh's nicht.. ;-(

Ich habe im Programmspeicher folgende Daten:
1
const unsigned int daten[] PROGMEM = { 0xf0aa,  0x0f55, .... }

Wenn ich nun mit
1
val = pgm_read_word_far(FAR(daten) + offset);

darauf zugreifen will, bekomme ich nur die einzelnen Bytes (!!), auf die 
'offset' zeigt. D.h. der Reihe nach: 0x00aa, 0x00f0, 0x0055, 0x000f, 
ect.

Das pgm_read_word_far kann ich aktuell gegen ein pgm_read_byte_far 
tauschen, ohne dass es irgendwelche Auswirkungen hat. Keine 
Compiler-Warnung (GCC) ect.. ;-)

Das FAR() habe ich hier aus dem Forum und ist wie folgt definiert:
1
#define FAR(var)                      \
2
({ uint_farptr_t tmp;                 \
3
__asm__ __volatile__(                 \
4
  "ldi    %A0, lo8(%1)"  "\n\t" \
5
  "ldi    %B0, hi8(%1)"  "\n\t" \
6
  "ldi    %C0, hh8(%1)"  "\n\t" \
7
  : "=d" (tmp)                  \
8
  : "p"  (&(var)));             \
9
tmp;                                  \
10
})

Wo liegt der Hund begraben..? :-)
Für Tipps wäre ich sehr dankbar!

von Davis (Gast)


Lesenswert?

Wie ist "val" definiert/deklariert?

von Der T. (Gast)


Lesenswert?

Sorry, natürlich unsigned int.. ;-)
(Das hat aber nichts mit den Ergebnis zu tun, das mir sonst "nur" die 
oberen 8Bit je Wort verloren gehen würden.)

von Der T. (Gast)


Lesenswert?

Keiner eine Idee, woran das liegt? :-/

(Ich lese nun als Workaround 2x 8Bit und baue mir daraus mein Integer.)

von Stefan E. (sternst)


Lesenswert?

Zeig mal allen relevanten Code, nicht nur Einzeiler. Dazu gehört z.B. 
auch der Code, mit dessen Hilfe du überhaupt feststellst, was gelesen 
wurde.

Davon abgesehen: Dass 'offset' tatsächlich nur ein Byte-Offset darstellt 
und nicht etwa ein Index für das Array, ist hoffentlich klar, oder?

von Der T. (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Zeig mal allen relevanten Code, nicht nur Einzeiler. Dazu gehört z.B.
> auch der Code, mit dessen Hilfe du überhaupt feststellst, was gelesen
> wurde.

Ich habe zu Eingrenzung ein extra Projekt erstellt und gebe ein Wort via 
16 LEDs (PORTA und PORTB) aus. Ansonsten gibt es wirklich nur die paar 
Zeilen..

> Davon abgesehen: Dass 'offset' tatsächlich nur ein Byte-Offset darstellt
> und nicht etwa ein Index für das Array, ist hoffentlich klar, oder?

Das ist wohl mein erstes Problem. Ich dachte, dass dies ein Index 
ist..?!?

Jedoch unabhängig davon: Sollte die Funktion nicht trotzdem (wenn auch 
verschoben) echte 16Bit-Werte liefern? z.B. bei offset=1 => 0x55f0

Ich verstehe jedoch nicht, warum mir pgm_read_word_far immer die oberen 
8Bit auf 0 setzt..?!? :-/

von Stefan E. (sternst)


Lesenswert?

Der Techniker schrieb:
>> Davon abgesehen: Dass 'offset' tatsächlich nur ein Byte-Offset darstellt
>> und nicht etwa ein Index für das Array, ist hoffentlich klar, oder?
>
> Das ist wohl mein erstes Problem. Ich dachte, dass dies ein Index
> ist..?!?

Nein, denn "FAR(daten) + offset" ist keine Pointer-Arithmetik, sondern 
einfach nur eine Addition zweier Integer.

Der Techniker schrieb:
> Jedoch unabhängig davon: Sollte die Funktion nicht trotzdem (wenn auch
> verschoben) echte 16Bit-Werte liefern? z.B. bei offset=1 => 0x55f0

Ja.

Der Techniker schrieb:
> Ich verstehe jedoch nicht, warum mir pgm_read_word_far immer die oberen
> 8Bit auf 0 setzt..?!? :-/

Tut es mit ziemlicher Sicherheit nicht. Es ist wahrscheinlicher, dass 
irgendwo anders ein Fehler ist, der dich das nur glauben lässt. Aber 
schon klar, im Rest des Codes kann natürlich unter keinen Umständen 
irgendein Fehler sein, richtig?

Der Techniker schrieb:
> Ich habe zu Eingrenzung ein extra Projekt erstellt und gebe ein Wort via
> 16 LEDs (PORTA und PORTB) aus. Ansonsten gibt es wirklich nur die paar
> Zeilen..

Umso unverständlicher, warum man dir den Code aus der Nase pulen muss, 
und du ihn nicht einfach komplett postest.

von Der T. (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Umso unverständlicher, warum man dir den Code aus der Nase pulen muss,
> und du ihn nicht einfach komplett postest.

Frisch aus der Nase:

main.c
1
#include <avr/io.h>
2
#include <avr/pgmspace.h>
3
4
#define FAR(var)                      \
5
({ uint_farptr_t tmp;                 \
6
__asm__ __volatile__(                 \
7
  "ldi    %A0, lo8(%1)"  "\n\t" \
8
  "ldi    %B0, hi8(%1)"  "\n\t" \
9
  "ldi    %C0, hh8(%1)"  "\n\t" \
10
  : "=d" (tmp)                  \
11
  : "p"  (&(var)));             \
12
tmp;                                  \
13
})
14
15
const unsigned int daten[] PROGMEM = { 0xf0aa,  0x0f55 };
16
17
int main (void)
18
{
19
 unsigned int var = 0;
20
 unsigned char offset = 0;
21
22
 DDRA = 0xff;
23
 DDRB = 0xff;
24
 
25
 val = pgm_read_word_far(FAR(daten) + offset);
26
 
27
 PORTA = (val >>8);
28
 PORTB = val;
29
 
30
 while(1);
31
}

Zur Fehlereingrenzung sieht das "Programm" genau so aus.
Nicht mehr und nicht weniger..

von Stefan E. (sternst)


Lesenswert?

Welcher Controller?

Und bitte mal zusätzlich das lss-File posten.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.