Forum: Compiler & IDEs Mit Pointerarray auf ein Array im EEPROM zugreifen


von Christian P. (christian_paier)


Lesenswert?

Hallo,

ich habe erst vor ein paar Tagen begonnen mit GCC, basierend auf dem
GCC-Tutoril Mikrocontroller zu programmieren. Von daher sind mir Pointer
ohnehin noch nicht ganz geheuer.
Ich habe auch schon mal die Beiträge im GCC-Forum nach nützlichen 
Informationen durchsucht, bin davon aber auch nicht schlauer geworden.

folgendes bereitete mir Kopfschmerzen:

Ich möchte mehrere Arrays ins EEPROM schreiben und dann mittels einem
Pointerarray auf diese Daten zugreifen.

Ich habe mir das mal so gedacht:

#include <avr/io.h>
#include <stdint.h>
#include <avr/eeprom.h>

unsigned char I[] EEMEM = { 124,16,16,16,16,16,16,124 };
unsigned char Q[] EEMEM = { 60,66,129,129,129,133,66,61};
unsigned char Z[] EEMEM = { 255,2,4,8,60,32,64,255 };
unsigned char *PointerArray[] EEMEM = { I,Q,Z };

int main (void)
{

  DDRB=0xff;

  unsigned char id = 3;
  unsigned char *char_pointer;
  char_pointer=(uint8_t*)(eeprom_read_word(&PointerArray[char_id]));


  unsigned char char_byte = eeprom_read_byte(char_pointer);

  PORTB=char_byte;

   return 0;
}

Ich erhalte zwar keine Fehlermeldung aber dafür die Warnung:

"passing argument 1 of 'eeprom_read_word' from incompatible pointer 
type"

Habe auch schon alles versucht was mir so einfällt aber ohne Erfolg.
Hoffe ihr könnt mir helfen.

mfg Christian Paier

von Karl H. (kbuchegg)


Lesenswert?

Christian Paier wrote:

> "passing argument 1 of 'eeprom_read_word' from incompatible pointer
> type"
>
> Habe auch schon alles versucht was mir so einfällt aber ohne Erfolg.
> Hoffe ihr könnt mir helfen.

Sieh dir in solchen Fällen einfach mal den Funktionsprotoypen
an. Wahllos rumprobieren bringt dich selten weiter.
Also die Datei avr/eeprom.h aufmachen und dort den Protoypen
der Funktion eeprom_read_word raussuchen:

static inline uint16_t _attribute_ ((always_inline))
eeprom_read_word (const uint16_t *addr);

Man sieht, dass die Funktion gerne einen Pointer auf einen uint16_t
haben möchte. Das macht auch Sinn, da ein word im gcc nun mal
2 Bytes hat und der naheliegenste Datentyp dafür ein uint16_t
ist. Ergo möchte read_word die Adresse eines uint16_t haben.

Was übergibst du an die Funktion?
Du übergibst &PointerArray[id]). Auch das ist erst mal eine
Adresse (&), aber da PointerArray vom Datentyp
'Array of unsigned char *' ist, verbirgt sich im EEPROM an dieser
Stelle kein uint16_t sondern ein unsigned char*. Auch ein
unsigned char* besteht aus 16 Bit, so dass du im Prinzip kein
Problem hast. Du musst nur dem Compiler mitteilen:
'Ich weiss schon, dass an dieser Stelle im EEPROM kein uint16_t
liegt. Das macht aber nichts, den das was ich von dort auslesen
will, hat ebenfalls 16 Bit. Also tu doch bitte einfach so, als
ob die Adresse die ich dir gegeben habe, die Adresse eines
uint16_t wäre, damit der übergebene Datentyp für read_word
stimmt.'
Mit anderen Worten: Du musst das Typprüfsystem übergehen.
Und dazu benutzt du einen cast:
1
  char_pointer=(uint8_t*)(eeprom_read_word((uint16_t*)&PointerArray[char_id]));

BTW:
Ein Array mit 3 Elementen
unsigned char *PointerArray[] EEMEM = { I,Q,Z };

besteht aus den Elementen
  PointerArray[0], PointerArray[1], PointerArray[2]

ein Element PointerArray[3] gibt es nicht.

von Christian P. (christian_paier)


Lesenswert?

Oh ja sorry, dass mit dem 3.Element dass es nicht gibt habe ich falsch 
in den Beitrag geschriegen, sorry. ;-P

Jetzt verstehe ich auch die Problematik hinter dem Problem mit dem 
Compiler und dem erwartetem Dateityp. Habe die entsprechenden Änderungen 
um Programm vorgenommen. Alles funktioniert perfekt.

Danke kbuchegg.

mfg Christian Paier

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.