www.mikrocontroller.net

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


Autor: Christian Paier (christian_paier)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
  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.

Autor: Christian Paier (christian_paier)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.