Forum: Compiler & IDEs eeprom_read_block Problem


von Frank L. (franklink)


Lesenswert?

Hallo zusammen,
ich habe ein kleines Verständnisproblem::

Ich möchte einfach nur einen Bereich aus einem Array mit 
eeprom_read_block auslesen. Aber irgendwie schickt die Funktion mein 
Programm ins nirvana.

Strukturdefinition:
1
#define NUMBER_OF_RGB_LED  2
2
#define NUMBER_OF_RGB_TABLE 8
3
4
typedef struct _colorstruc 
5
{
6
  unsigned char H;
7
  unsigned char S;
8
  unsigned char V;
9
  unsigned char Speed;
10
  unsigned char red_pwm;
11
  unsigned char green_pwm;
12
  unsigned char blue_pwm;
13
  unsigned char Pin_R;
14
  unsigned char Pin_G;
15
  unsigned char Pin_B;
16
} colorstruc;
17
18
typedef struct _colorproc
19
{
20
  colorstruc colorstrucs[NUMBER_OF_RGB_LED];
21
} colorproc;

EEPROM Arraydefinition:
1
EEMEM colorproc colortable[8] =
2
{
3
    { 
4
      { 
5
        // White 
6
        { 0x00, 0x00, 0xFF, 200, 0, 0, 0, 1, 2, 3 },
7
        { 0x00, 0x00, 0xFF, 200, 0, 0, 0, 4, 5, 6 } 
8
      }
9
        }, 
10
    { 
11
      { 
12
        // Bright red
13
      { 0x00, 0xFF, 0xFF, 0xC8, 0, 0, 0, 0, 1, 2 },
14
        { 0x00, 0xFF, 0xFF, 0xC8, 0, 0, 0, 3, 4, 5 } 
15
      }
16
        }, 
17
    { 
18
      { 
19
        // Bright yellow
20
      { 0x2A, 0xFF, 0xFF, 0xC8, 0, 0, 0, 0, 1, 2 },
21
        { 0x2A, 0xFF, 0xFF, 0xC8, 0, 0, 0, 3, 4, 5 } 
22
      }
23
        }, 
24
    { 
25
      { 
26
        // Bright green
27
      { 0x55, 0xFF, 0xFF, 0xC8, 0, 0, 0, 0, 1, 2 },
28
        { 0x55, 0xFF, 0xFF, 0xC8, 0, 0, 0, 3, 4, 5 } 
29
      }
30
        }, 
31
    { 
32
      { 
33
        // Bright cyan
34
      { 0x80, 0xFF, 0xFF, 0xC8, 0, 0, 0, 0, 1, 2 },
35
        { 0x80, 0xFF, 0xFF, 0xC8, 0, 0, 0, 3, 4, 5 } 
36
      }
37
        }, 
38
    { 
39
      { 
40
        // Bright blue
41
      { 0xAA, 0xFF, 0xFF, 0xC8, 0, 0, 0, 0, 1, 2 },
42
        { 0xAA, 0xFF, 0xFF, 0xC8, 0, 0, 0, 3, 4, 5 } 
43
      }
44
        }, 
45
    { 
46
      { 
47
        // fast cycle
48
      { 0x00, 0xFF, 0xFF, 0x0A, 0, 0, 0, 0, 1, 2 },
49
        { 0x00, 0xFF, 0xFF, 0x0A, 0, 0, 0, 3, 4, 5 } 
50
      }
51
        }, 
52
    { 
53
      { 
54
        // fast cycle low sat
55
      { 0x00, 0x7F, 0xFF, 0x32, 0, 0, 0, 0, 1, 2 },
56
        { 0x00, 0x7F, 0xFF, 0x32, 0, 0, 0, 3, 4, 5 } 
57
      }
58
        }
59
};

Ziel-Array:
1
colorproc colors[1] =
2
{
3
  { 
4
    { 
5
      { 0x00, 0xFF, 0xFF, 0xC8, 0, 0, 0, 1, 2, 3 },
6
      { 0x00, 0xFF, 0xFF, 0xC8, 0, 0, 0, 4, 5, 6 } 
7
    }
8
  }
9
};

und so lese ich:
1
eeprom_read_block( (void*)&colors[0], (const void*)&colortable[0], sizeof( colorproc ) );

Wäre für den entscheidenden Tip dankbar.

Gruß
Frank

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Das ist es denn für ein µC?

Neuere Versionen der avr-libc ignorieren einen Siliconbug einiger 
AVR-Derivate. Es wird eine ungültige Instruktion erzeugt, die im Manual 
verboten wurde.

Ob das das Poroblem ist, siehst du bei einer Sichtung des Disassemblies 
nebst Errata deines µC.

von Frank L. (franklink)


Lesenswert?

Hallo Johann,
nee, glaub ich nicht, ich verwende die gleiche Struktur in einer anderen 
Anwendung um Daten aus einem zwei dimensionalen EEMEM-Array zu lesen. 
Der Unterschied hier ist lediglich die Struktur in die ich die Daten 
einlesen möchte.

Ich vermute einfach nur ein falscher Aufruf... D.h. falsche 
Parametrisierung.

Gruß
Frank

von Stefan E. (sternst)


Lesenswert?

Schau nochmal genau hin, ob es nicht noch einen weiteren Unterschied 
gibt, nämlich die Optimierungsstufe. Die fehlerhafte Instruktion wird 
nur erzeugt, wenn die Optimierung abgeschaltet ist.

von Frank L. (franklink)


Lesenswert?

Vergessen:

Prozessor: ATMega8
Board: MyAvrUsb
Umgebung: AVR Studio 4.13.557

Gruß
Frank

von Werner B. (werner-b)


Lesenswert?

1. Und das Wichtigste, die Compilerversion?

2. Workaround für das Compilerproblem = leere ISR für den EEProm 
Interrupt definieren.

3. EEMEM Daten werden vom Compiler "im Prizip" genauso behandelt wie 
Daten im Progmem. Es gelten also im wesentlichen auch die gleiche 
Beschränkungen.
Du kannt insbesondere den Abschnitt 
AVR-GCC-Tutorial: Array aus Zeichenketten im Flash-Speicher aus dem 
Tutorial auf dein Problem mit dem EEProm übertragen.
Ich fürchte so wird das nicht funktionieren. :-(

Werner

von Frank L. (franklink)


Lesenswert?

Hallo Werner,
ich denke, das Problem liegt an sizeof( colorproc ). Ich hatte mir den 
Wert mal per UART ausgeben lassen und erhalte hier den Wert 0x20 an 
Stelle von 0x14.

In der Simulation läuft die Anwendung einwandfrei. Also liegt die 
Vermutung nahe, dass ich mir irgendwo Speicher überschreibe.

Ich werde heute Abend nochmals in Ruhe und mit dem notwendigen Abstand 
forschen.

Danke schon mal für die Ratschläge.

Gruß
Frank

von Werner B. (werner-b)


Lesenswert?

> ...erhalte hier den Wert 0x20 an Stelle von 0x14.

Könnte das nicht nur ein Darstellungsproblem sein?  Denn 0x14 = 20Dez ?

von Frank L. (franklink)


Lesenswert?

Hallo Werner,
eigentlich nicht, ich verwende eine Funktion für den Uart die mir einen 
Hex-Wert liefert. Da ich diese Funktion an anderer Stelle auch verwende 
und sie dort korrekte Werte liefert...

Aber wie so oft, der Teufel liegt im Detail, werde ich also heute Abend 
nochmals prüfen.

Ich werde heute Abend mal das ganze Teil posten. Mal sehen ob sich 
jemand erbarmt und mal rein schaut. Sitze schon zu lang an dem Problem 
und sehe wahrscheinlich mal wieder den Wald vor lauter Bäumen nicht 
mehr.

Gruß
Frank

P.S. eigentlich sollte das doch so richtig sein, oder?

von Stefan E. (sternst)


Lesenswert?

Frank Link wrote:

> ich denke, das Problem liegt an sizeof( colorproc ). Ich hatte mir den
> Wert mal per UART ausgeben lassen und erhalte hier den Wert 0x20 an
> Stelle von 0x14.

Sehr unwahrscheinlich. Die bereits angesprochene mögliche Hex<->Dez 
Verwechselung ist hier deutlich wahrscheinlicher.

Und mal so nebenbei: Bist du meinem Hinweis bezüglich der 
Optimierungsstufe mal nachgegangen?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Werner B. wrote:
> 1. Und das Wichtigste, die Compilerversion?

Falls es der EERE-Bug ist, ist die Version der avr-libc interessanter. 
Neuere Versionen machen da nen ziemlich umständlichen indirekten call 
und wenn nicht alles komplett wegoptimiert wird, crasht es.

Zudem würd ich meine Hand nicht ins Feuer dafür legen, daß das Problem 
je nach C-Kontext nicht auch bei höheren Optimierungsstufen zum Tragen 
kommt.

Ergo: Nur ein Disassembly liefert Sicherheit.

Der Bug ist für ATmega8 aktiv.


Probleme kann es auch geben, wenn ein Modul mit -fpack-struct übersetzt 
ist und eines ohne.

Und in den Initializern kann ich eine {}-Ebene nicht zuordnen, scheint 
eine zu viel zu sein?

von Frank L. (franklink)


Lesenswert?

Hallo Stefan,
nein, dem Optimierungproblem bin ich noch nicht nachgegangen, da ich 
erst heute Abend wieder daran arbeite.

Ist kein Problem, dass ich im Bürö habe.

Die Anwendung ist eine kleine Spielerei von mir für ein Moodlight.

Wie geschrieben, ich stelle heute Abend mal den Sourcecode und alle 
anderen Infos ein.

Gruß
Frank

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Frank Link wrote:
> Hallo Stefan,
> nein, dem Optimierungproblem bin ich noch nicht nachgegangen, da ich
> erst heute Abend wieder daran arbeite.

hmmm, soweit ich sehe, benutzt die neueste Version der avr-libc (1.6.4) 
explitit ein IN, so daß der Silicon-Bug nicht getriggert werden dürfte.

Da weiß Jörg bestimmt mehr drüber zu sagen, für welchen lib-Versionen 
überhaupt problematischer Code erzeugt werden könnte.

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.