Riesiges Array im Flash

OP #982287
Hi,

für ein Verschlüsselungsverfahren muss ich riesige Matrizen speichern.
Wenn ich versuche sie per:
1
const uint8_t matrix[] PROGMEM={0x11,0x22,...,0x11};
in den Flash legenzu lassen, bekomme ich immer den Fehler:
"Größe der Variablen "matrix" ist zu hoch."
Ich benutze einen atmega128 und die matrix ist 81Kbyte( ja 81*1024 
bytes)
gross, sollte also in den Flash passen.

G++gle und Forumssuche hat leider nicht erbracht.
Was läuft da schief?

Danke
Stefan
Gast #982420
Der avr-gcc adressiert Arrays über 16-bit-Pointer, damit ist die Größe 
auf 32kB begrenzt. Warum es nicht 64kB sind, wurde hier mal diskutiert, 
wenn du das genauer wissen willst, musst du mal danach suchen. 81kB 
funktiert auf keinen Fall.

Oliver
OP #982431
Ah, das erklärt es natürlich.
Aber wenn ich die Matrix in ein 2-dimensionales Array mit 81 Zeilen und 
1024 Spalten zerlege, dann sollte das funktionieren, oder? Jeder Pointer 
für sich muss dann ja weniger als 32kbyte "überstreichen" können.

Danke für die schnelle Antwort
Stefan
#982461
@ Stefan H. (Firma privat) (schnufff)

>Aber wenn ich die Matrix in ein 2-dimensionales Array mit 81 Zeilen und
>1024 Spalten zerlege, dann sollte das funktionieren, oder?

NEIN! Weil das auch als zusammenhängendes Objekt verwaltet wird. Du 
braucht getrennte Arrays kleiner gleich 32kB.

MfG
Falk
OP #984357
Ok, die einzelnen Arrays müssen kleiner 32Kbyte sein.
Wenn ich die Zeilen der Matrix als 1024 Arrays speichere:
1
const uint8_t Matrix0[] PROGMEM={0x01,...};
2
...
3
const uint8_t Matrix1023[] PROGMEM={0x01,...};

wobei jede Zeile 81 Bytes enthält und dann die Zeilen in einem
Array von Pointern auf Arrays verwalte:
1
const uint16_t* Matrix[] PROGMEM={Matrix0,..Matrix1023[]};

Komme ich dann mit:
1
myByte=pgm_read_byte_far((pgm_read_byte_far(&Matrix[Zeile])[Spalte]);
an das Element in Zeile,Spalte?

Nur zur Info: Ich habe mehrere Matrizen die in Summe knapp 200Kbyte 
gross sind und 3 davon sind grösser als 64K.Alle Matrizen sind statisch 
und werden nur gelesen. Ich weiss das ich besser auf einen kleinen ARM7 
umsteigen kann, aber das ist nunmal nicht die Zielplattform.

danke
Stefan
OP #984384
Danke Jörg, aber die Matrizen werden auf einem PC mit einem 
CoputeralgebraProgramm vorberechnet und dann etwas formatiert und in 
meiner config.c eingebunden. Sie sind also zur kompletten Laufzeit des 
Programms fest.

Ich hatte mittlerweile versucht das Beispiel aus dem libc manual 
nachzubauen:
1
char string_1[] PROGMEM = "String 1";
2
char string_2[] PROGMEM = "String 2";
3
char string_3[] PROGMEM = "String 3";
4
char string_4[] PROGMEM = "String 4";
5
char string_5[] PROGMEM = "String 5";
Then use the new symbols in your table, like so:
1
PGM_P string_table[] PROGMEM = 
2
{
3
    string_1,
4
    string_2,
5
    string_3,
6
    string_4,
7
    string_5
8
};
Auslesen wollte ich dann per:
1
myChar=pgm_read_byte_far((PGM_P)pgm_read_word(&(string_table[i]))[j]);

Allerdings meckert er jetzt" pointer targets in init differ in 
signedness".
Selbst wenn der pointer "signed int" ist, muss er doch immer noch 
+32Kbyte adressieren können.Also sollte das für eine Zeile der MAtrix 
reichen, oder hab ich was flasch verstanden?

Gruss
Stefan
Moderator Persönliche Seite #984433
Stefan H. wrote:

> Danke Jörg, aber die Matrizen werden auf einem PC mit einem
> CoputeralgebraProgramm vorberechnet und dann etwas formatiert und in
> meiner config.c eingebunden. Sie sind also zur kompletten Laufzeit des
> Programms fest.

Ja, eben, daher kannst du sie ja genauso gut durch eine Folge von
.byte-Anweisungen in einer Assemblerdatei anlegen lassen.
OP #997794
So, ich hab jetzt alle Array in Stücke kleiner 32K aufgeteilt und will 
mit pgm_read_byte/word_far drauf zugreifen.
Definiert sind die Array wie gehabt per
1
const uint8_t Matrix0[] PROGMEM={0x01,...};

aber keine der heir gefunden Möglichkeiten auf die hexwerte in 
Matrix[i]zuzugreifen scheint richtig zu funktionierten:
1
myByte=pgm_read_byte_far(FAR(Matrix[i]);
2
myByte=pgm_read_byte_far(FAR(Matrix+i));
3
myByte=pgm_read_byte_far(FAR(Matrix)+i));
liefern entweder nur 00 oder FF.

Bin ich denn so blöd?
Ich will einfach nur konsistent auf den kompletten flash eines Mega256 
zugreifen können und mir auf ewig konstante bytes/words auslesen können.

Gruss
Stefan
Moderator Persönliche Seite #998645
Stefan H. wrote:

> Ich hab grad 2 probleme. wie binde ich die *.asm datei ein und wie
> greife ich dann über C auf die bytes/words zu?

Die Assemblerdatei benennst du mit einer auf .S (großes S) versehenen
Endung und gibst sie einfach dem Compiler mit.  Der kann damit dann
was anfangen.

In der Assemblerdatei musst du die extern bekannt zu machenden Symbole
mit .global deklarieren:
1
.section .progmem.data,"a",@progbits
2
.global bigarray
3
bigarray:
4
    .byte 42, 23, 1, 5, 18

In der C-Datei deklarierst du dies einfach als externes Array:
1
extern uint8_t bigarray[];

*Aber*:

Du kannst nicht mit normalen Array- oder Zeigerzugriffen darauf
zugreifen, denn dann stolperst du ja sofort wieder darüber, dass
ein Zeiger im AVR-GCC nur 16 bits groß ist und dass der Arrayindex
per definitionem vom Typ signed int ist.  Du musst stattdessen per
Typecast vom Arraynamen einen uint32_t-Wert bilden und den an Stelle
eines Zeigers benutzen.  Die ganze Adressrechnung, die dir sonst
der Compiler abnimmt, musst du also zu Fuß erledigen.  Die sich
ergebende uint32_t-Zahl kannst du dann als Adresse an ein
pgm_read_byte_far() übergeben.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.