Forum: Compiler & IDEs Array in GCC


von Axos (Gast)


Lesenswert?

Hi!

Ich habe ein Problem mit einem array, dass ich folgendermasen
erstelle:

volatile char data[] = {  0x0C, 0x94, 0x2A, 0x00, 0x0C, 0x94... };

In das Array sollen später über 8000 bytes. Jetzt ist nur mein Problem,
dass wenn ich mehr als 1024 Bytes reinschreib mein Programm lauter
fehler ausweist.

Ist nun 1024 wirklich die Grenze für ein (char) Array ? Gibts da ne
einstellung beim GCC die die Array Grenze erweitert? Oder gibts da ne
andere lösung (aussen externe bauteile, und das interne eeprom is ja zu
klein) ?

MfG Axos

von Jörg Wunsch (Gast)


Lesenswert?

Nein, die Grenze für den Array-Index liegt bei INT_MAX, also 32767
Elementen.

Bist Du Dir eigentlich sicher, dass Du das Ding wirklich volatile
deklarieren willst?  Nicht dass es auf Dein Problem einen Einfluss
hätte, aber es wird Dir uneffektiven Code generieren.

von Axos (Gast)


Lesenswert?

@Jörg Wunsch: Hast recht das volatile ist quatsch. Habs gleich mal
rausgemacht.

hab den fehler schon vertanden...1K SRAM ;(( mehr geht nicht
rein...kann ich die sachen auch nur teilweise in den RAM laden und dann
später das nächte Stück ?
Es gibt soch eine Routine mit der ich auf dem Flash zugreifen kann...
dann würd ich einfach den ganzen array code an das ende der datei
setzen und dann mit dem befehl auslesen.

von Rufus T. Firefly (Gast)


Lesenswert?

Soll das Array etwa mit konstanten Werten gefüllt werden?
Dann ließe es sich am besten gleich ganz im Flash-ROM unterbringen,
allerdings muss bei Arrayzugriffen dann darauf Rücksicht genommen
werden.
Mit dem Prefix prog_char kann eine Konstante im ROM abgelegt werden,
mit pgm_read_byte() kann ein einzelnes Byte aus dem Flash-ROM gelesen
werden.
Näheres findet sich sicherlich in der Dokumentation.
Eine Diskussion hierzu auch hier:
http://www.mikrocontroller.net/forum/read-2-141782.html#new

von Axos (Gast)


Lesenswert?

Danke ! Funktioniert super !
kannst du mir nochsagen wie ich die grösse des arrays ermittle?
sizeof() geht jetzt wohl icht mehr.

MfG Axos

von Rufus T. Firefly (Gast)


Lesenswert?

Wieso sollte das nicht gehen? sizeof() wird nicht während der Laufzeit
ausgewertet - oder schreibt die avr-gcc Dokumentation da anderes? IMHO
wird vom Compiler sizeof(wasauchimmer) zur Übersetzungszeit durch eine
Konstante ersetzt.

von Jörg Wunsch (Gast)


Lesenswert?

Genau so ist es.  Gängige Methode, einen Feldindex bis zum Ende zu
zählen ist:

for (size_t i = 0; i < sizeof array / sizeof array[0]; i++)

von tenner (Gast)


Lesenswert?

ich kenne zwar den avr-gcc nicht, beim msp430-gcc kann ein array als
const angelegt werden. dies wird dann automatisch im flash abgelegt.
der lese-zugriff erfolgt dann ganz normal über den index bzw. mittels
pointer ohne umständliches pgm_read_byte() oder so.

gruß tenner

von ---- (Gast)


Lesenswert?

@tenner: Ja, aber Jörg und die anderen AVRGCC-Macher sehen das nicht so,
da der AVR getrennten Adressbus für Programm und Daten hat und man damit
theoretisch sauber das nicht vermischen darf und der Benutzer bei jedem
Zugriff darauf auf die umständliche Konstruktion ausweichen muß,
anstatt nur 'const' zu schreiben. Theoretisch mag das zwar sauber
sein, aber ob's praktisch wirklich hilft...

@Jörg, ich möchte damit nicht erneut die alte Diskussion auslösen,
sondern nur nochmal erwähnen, daß es keinen techn. notwendigen Grund
der Umsetzung gibt, wie sie der AVRGCC verwendet.
Verzeihe meine Polemik - hoffentlich ist meine Erklärung oben
einigermassen richtig.

----, (QuadDash).

von Jörg Wunsch (Gast)


Lesenswert?

Du vergisst dabei eben nur, dass der MSP430 nicht Harvard ist,
sondern flat (32-bit) address space.  Damit hat er es in dieser
Hinsicht deutlich einfacher, dort kann man const einfach im ROM
ablegen, ohne dabei die Standardkonformität (bzgl. z.B. der <string.h>
Funktionen) kaputtzumachen.

von Tobias Tetzlaff (Gast)


Lesenswert?

Hallo,

und hier auch nochmal, vielleicht hilft es weiter,
allerdings schiebe ich die HEX Werte per SPI raus :

---------------------------------------------------------------------

#include <avr/pgmspace.h>

volatile unsigned int pos;
volatile unsigned int pos_a;

volatile prog_char
display_1[]={0xAA,0x2A,0x0A,0x02,0x00,0x00,0x00,0x00,0x00,0x00,//10
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  //20
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  //30
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  //40
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  //50
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x0A,0x2A,  //60
                0x00,                        //361
                };

void Anzeige(void)
{
if( pos < 361 )
  {
  SPDR = PRG_RDB(display_1 + pos_a);    // Daten aus Flash per SPI 
senden
    while (!(SPSR & (1<<SPIF)));      // Warten bis Übertragung beendet


Oder auch dieses : ------------------------------------------------

#include <avr/io.h>
#include <avr/iom8.h>
#include <avr/pgmspace.h>

// Eine Möglichkeit Daten in den Programmspeicher zu legen
prog_char Tabelle_1[]={0x30,0x31,0x32,0x33,0x34,0x35};
prog_char Tabelle_2[]={0x41,0x42,0x43,0x44,0x45};

// Noch eine Möglichkeit
const char Text_1[]PROGMEM="TextText 11111";
const char Text_2[]PROGMEM="TestText 22222";

void main(void);

//-------------------------------------

void main(void)
{
  char  i;

  for(i=0; i<5; i++)
  {
    // Lesen (Daten der Tabelle_1 plus Offset (i) )
    // und PortB Zuweisen
    PORTB = PRG_RDB(Tabelle_1 + i);
    // Tabelle_2 nach PortC
    PORTC = PRG_RDB(Tabelle_2 + i);
  }
  for(i=0; i<5; i++)
  {
    // Auf PortD werden 5 Zeichen vom Text_1 ausgegeben
    PORTD = PRG_RDB(Text_1 + i);
  }
}
------------------------------------------------------------------

Gruß Toby

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.