Forum: Mikrocontroller und Digitale Elektronik Display Speicherproblem Überlauf ?


von Klaus (Gast)


Lesenswert?

Hallo Leute,

ich hänge an einem Speicherproblem und finde nicht den richtigen Anfang.

Es ist ein ATmega2560, der soll zwei Bilder auf einem TFT ausgeben.

Die Daten selber sind im Flash, sollten also zur Laufzeit keinen Platz 
belegen, richtig ?

Unten der Quelltext. Daten werden mit pgm_read gelesen und auf das 
Sisplay ausgegeben.

Mit 3 Bildern funktioniert die Sace super, aber sobald das vierte 
dazukommt, werden die Bilder wild durcheinander angezeit.

Nach der Anzeige läuft das Program normal weiter, als ob nix passiert 
wäre.

Ich habe gehofft das die Daten nur zur Laufzeit aus dem Flash geladen 
und nach der Anzeige wieder gelöscht werden, also keinen RAM belegen.





Daten:

const uint16_t data_original_bmp1[] PROGMEM=
{
    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
.......
}


Auslesen und weitergeben:

            a=0;
            while (a<9600)
                {
                    pushcolour(pgm_read_word(&data_original_bmp2[a]));
                    a++;
                }



Ausgabe zum Display:

//set colour for drawing
void pushcolour(uint16_t colour)
{
    writedata8(colour>>8);
    writedata8(colour);
}

Speicherbelegung:

Program Memory Usage   :  155066 bytes   59,2 % Full
Data Memory Usage  :  2770 bytes   4,3 % Full
EEPROM Memory Usage   :  2475 bytes   60,4 % Full

von Rudolph R. (rudolph)


Lesenswert?

Probiere mal, ob das mit pgm_read_word_far() klappt.

von Klaus (Gast)


Angehängte Dateien:

Lesenswert?

Rudolph R. schrieb:
> Probiere mal, ob das mit pgm_read_word_far() klappt.

Danke Rudolph.

Nein, leider keine Verbesserung. Es sieht anders aus, also es werden 
andere Bildteile genommen.

von Jim M. (turboj)


Lesenswert?

Klaus schrieb:
> Program Memory Usage   :  155066 bytes   59,2 % Full

Das sind mehr als 65536*2 Byte, also reichen 16 Bit nicht aus.
-> pgm_read_word_far() zwingend erforderlich.

Zeige uns mal den Code mit pgm_read_word_far(), pass auf dass da nicht 
irgendwo noch 16 Bit Pointer (oder int) drin sind.

von Falk B. (falk)


Lesenswert?

@ Klaus (Gast)

>Es ist ein ATmega2560, der soll zwei Bilder auf einem TFT ausgeben.

>Die Daten selber sind im Flash, sollten also zur Laufzeit keinen Platz
>belegen, richtig ?

Doch, den Flash ;-)

>Mit 3 Bildern funktioniert die Sace super, aber sobald das vierte
>dazukommt, werden die Bilder wild durcheinander angezeit.

Du willst doch nur 2 anzeigen. Warum auf einmal 4?

Wie groß sind deine Bilder?

Wenn diese zusammen mehr als 64kB belegen muss man mit den _far 
Funtkionen arbeiten. Dazu muss man aber auch FAR-Pointer als Argument 
übergeben.

https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Flash_mit_PROGMEM_und_pgm_read

Bisschen runter scrollen, "Variablenzugriff >64kB"

von Klaus (Gast)


Lesenswert?

Falk B. schrieb:
> Doch, den Flash ;-)

Ja ;-)

Danke für die Hilfe, hat funktioniert !!

Das mit der far Funktion kannte ich nicht. Im nachgang macht es ja sinn, 
wäre ich aber nie drauf gekommen.

Danke !!!!!!

In main.h:

//====================================================================
// Macro to access strings defined in PROGMEM above 64kB
//--------------------------------------------------------------------
#define FAR(var)                     \
({ uint_farptr_t tmp;                \
  _asm_ __volatile__(         \
  "ldi    %A0, lo8(%1)"  "\n\t" \
  "ldi    %B0, hi8(%1)"  "\n\t" \
  "ldi    %C0, hh8(%1)"  "\n\t" \
  : "=d" (tmp)                  \
  : "p"  (&(var)));             \
  tmp;                              \
})//-------------------------------------------------------------------

//===================================================================
// Define a section above 64kiB (FAR_SECTION)
// and add the required linker argument below
// -Wl,--section-start=.far_section=0x10000
//--------------------------------------------------------------------
#define FAR_SECTION   __attribute__((__section__(".far_section")))
//--------------------------------------------------------------------


Und der neue Aufruf:

pushcolour(pgm_read_word_far(FAR(logo_1)+a));

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.