Forum: Compiler & IDEs Probleme mit Array im Flash


von Benedikt (Gast)


Lesenswert?

Irgendwie funktioniert bei mir das Array im Flash nicht so richtig.

Mit dem Array im RAM funktioniert es:
const signed char UFO_CORD[9][3]={...};
const unsigned int UFO_LINE[13][2]={...};

...

void RotatingObject(int W1,int W2,int W3,int x_Pos,int y_Pos,const
signed char COORD[][3], const unsigned int LINES[][2], int cnt,int
size)
{
    x1 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i][0])][0]);
    y1 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i][0])][1]);

    z1 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i][0])][2]);

    x2 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i][1])][0]);
    y2 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i][1])][1]);

    z2 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i][1])][2]);

Und mit dem Array im Flasg geht es leider nicht:

const prog_int8_t UFO_CORD[9][3]={...};
const prog_uint16_t UFO_LINE[13][2]={...};

void RotatingObject(int W1,int W2,int W3,int x_Pos,int y_Pos,const
prog_char COORD[][3], const prog_char LINES[][2], int cnt,int size)
{
    x1 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i][0])][0]);
    y1 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i][0])][1]);

    z1 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i][0])][2]);

    x2 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i][1])][0]);
    y2 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i][1])][1]);

    z2 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i][1])][2]);

von Benedikt (Gast)


Lesenswert?

Das mit dem pgm_read beim funktionierenden Code ist falsch, es heißt
natürlich heißt es:

    x1 = COORD[LINES[i][0]][0];
    y1 = COORD[LINES[i][0]][1];
    z1 = COORD[LINES[i][0]][2];

    x2 = COORD[LINES[i][1]][0];
    y2 = COORD[LINES[i][1]][1];
    z2 = COORD[LINES[i][1]][2];

von Rufus T. Firefly (Gast)


Lesenswert?

Bist Du Dir sicher, daß

  const prog_int8_t UFO_CORD[9][3]={...};

wirklich das ganze Array im Flash ablegt und nicht etwa nur ein Array
mit 9 Pointern auf 9 konstante Arrays, die wiederum im RAM liegen, so
wie es andere "Konstanten" beim gccavr auch tun?

Ich weiß nicht, was gccavr mit so einer Deklaration genau anstellt;
vielleicht liegt da ja ein Hase o.ä. im Pfeffer.

Bedenke, daß zweidimensionale Arrays in C ein bisschen einfacher
strukturiert sind als in anderen Sprachen, im Grunde genommen gibt es
keine.
Vielleicht geht's, wenn Du -etwas uneleganter- das ganze mit 'nem
eindimensionalen Array machst:

  const prog_int8_t UFO_CORD[9 * 3]={...};

dann sähe Deinen Zeilen statt so

  x1 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i][0])][0]);
  y2 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i][1])][1]);

eher so aus:

  x1 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i * 0]) * 0);
  y2 = pgm_read_byte(&COORD[pgm_read_word(&LINES[i * 1]) * 1);

was sich auch als

  x1 = pgm_read_byte(COORD + pgm_read_word(LINES + (i * 0)) * 0);
  y2 = pgm_read_byte(COORD + pgm_read_word(LINES + (i * 1)) * 1);

schreiben ließe.

Viel Erfolg!

von Stefan Seegel (Gast)


Lesenswert?

Tach,

ich behaupte mal einfach dass Deine Arrays nicht im Flash stehen...
Dazu müssen die Arrays mit "PROGMEM" gekennzeichnet sein, z.B.

#include <avr/pgmspace.h>

const char myarray[2][2] PROGMEM = {{1, 2}, {5, 6}};

Stefan

von Benedikt (Gast)


Angehängte Dateien:

Lesenswert?

Mit PROGMEM geht es nicht, 2D Arrays funktionierten bei mir schonmal mit
einem Flash Array.
Das Array liegt auf jedenfall im Flash:
.section  .progmem.data,"a",@progbits

Ich verstehe es echt nicht, warum es nicht funktioniert. Daher hier mal
das komplette Programm. Ich habe testweise nurmal ein Array ins Flash
gelegt, um Probleme mit dem Integer Array ausschließen zu können, aber
auch leider das geht nicht.

von Benedikt (Gast)


Lesenswert?

Ich hoffe mal, ich habe den Fehler:
pgm_read_byte läd einen Wert direkt aus dem Flash, ohne dass dieser als
signed oder unsigned definiert ist, daher gehe ich davon aus, dass er
das Byte als unsigned verarbeitet, und es daher ohne Beachtung des
Vorzeichens in die int Variable schreibt.

Allerdings habe ich jetzt ein anderes Problem:
Der verdammte Compiler macht nichts mehr. Zum ersten mal fiel mir auf,
dass keine Warnings mehr kommen, dann bemerkte ich, dass der Compiler
keine neue hex Datei erstellt. Lösche ich diese, dann ist diese für
immer weg. Und das ist bei all meinen Programmen auf einmal so !!!
Erstelle ich ein neues Programm, versucht der Compiler die nicht
erstellten Dateien zu verlinken, was in einem Fehler endet:
No rule to make target `main.o', needed by `main.elf'.  Stop.

von OldBug (Gast)


Lesenswert?

Hast Du schon avr-libc FAQ #14 gelesen?

von OldBug (Gast)


Lesenswert?

...und hast Du bei den Dateinamen die Groß-/Kleinschreibung beachtet?

von Benedikt (Gast)


Lesenswert?

Der Fehler war genau so wie ich vermutet hatte, nur ich habe es nicht
gemerkt, da der Compiler den Code nicht mehr compiled hat.
Mit einem Backup von gestern abend habe ich ihn dann irgendwie wieder
zum Laufen bekommen.

Und mit signed chars für x1, y1 usw. lief der Code sofort. Der Compiler
missachtet also bei pgm_read_byte ob das Array signed oder unsigned ist,
und kopiert das Byte direkt ohne Beachtung des Vorzeichens in den
Integer, dessen Highbyte mit 0 gefüllt wird...

von Benedikt (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe schon wieder dass Problem, dass der Compiler main.c nicht mehr
compiled.
Ich habe mal alles angehängt. Könnte mal jemand das bei sich
ausprobieren, ob es an meinem WinAVR liegt, oder ob ich nur zu dumm für
die Makefile bin ?

von OldBug (Gast)


Lesenswert?

Ich habe Dich bereits auf den Fehler hingewiesen ;)

Main.c != main.c

Auszug aus Deinem Makefile:

# Target file name (without extension).
TARGET = main


# List C source files here.
SRC = $(TARGET).c uart.c

Daraus wird dann:

"SRC = main.c uart.c"

main.c existiert allerdings nicht, es gibt nur Main.c!

von Benedikt (Gast)


Lesenswert?

Seltsam, ich habe Main.c gelöscht, und neu als main.c gespeichert, jetzt
ist sie wieder groß geschrieben...
Ich habe auch nie eine Main.c erstellt, sondern immer nur die main.c
aus anderen Projekten kopiert !

von Rufus T. Firefly (Gast)


Lesenswert?

Diese Diskussion wurde IMHO bereits geführt - der eigentliche Fehler
liegt im Make, das -entgegen den Dateisystemkonventionen des
zugrundeliegenden Betriebssystemes- bei Dateinamen auf Groß- und
Kleinschreibung achtet.

Wer auch immer für die Portierung des Make auf die Win32-Plattform
verantwortlich ist, sollte eben jenen Fehler beheben.

von Werner B. (Gast)


Lesenswert?

Ich tippe mal auf Bill G.'s "eXtended Problems" Betriebssystem!

Bei mir wird immer irgendwann einfach aus Makefile -> makefile (das
stört zwar make.exe nicht, ist aber nervend "da ich das gerne so
hätte", den ICH bin der Boss des Rechners, nicht Bill G.)  ;-)

von Rufus T. Firefly (Gast)


Lesenswert?

"Bei mir wird immer irgendwann einfach aus Makefile -> makefile"

Das kann auch eine Anzeigeoption des Explorers sein, der viele
ärgerliche Fehler mit sich herumschleppt.

Dennoch ist es ein Fehler im Make, wenn das unter Windows die
Dateien

   bla.c
   BLA.C
   Bla.c

etc. als was unterschiedliches ansieht.

Das ganze wurde -ohne Ergebnis- im Thread
http://www.mikrocontroller.net/forum/read-2-155523.html diskutiert.

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.