Forum: Compiler & IDEs mehrdimensionales Array aus Flash an Funktion übergeben


von Neo (Gast)


Lesenswert?

Hallo,
Ich bräuchte mal ein wenig Hilfe und zwar würde ich gerne ein 
mehrdimensionales Array das ich per PROGMEM im Flash abgelegt habe an 
eine Funktion übergeben:

Mein Array wird wie flogt im Flash abgelegt:
1
const uint8_t image_1[128][6] PROGMEM = {
2
  {0x00, 0x00, 0x3F, 0x00, 0x00, 0x00},
3
  ...
4
}
soweit auch erstmal kein problem.

Wenn ich das jetzt richtig verstanden ist image_1 jetzt ein Array aus 
Zeigern die auf den Flash zeigen? Auf deren Inhalt ich per
1
pgm_read_byte(&image_1[0][0])
zugreifen kann. Das funktioniert soweit auch...

Aber wie bekomme ich jetzt mein image_1 an eine Funktion übergeben? So 
das ich aus der Funktion per pgm_read_byte auf den Inhalt von image_1 
zugreifen kann?
Ich komm einfach nicht drauf...

von g457 (Gast)


Lesenswert?

> Aber wie bekomme ich jetzt mein image_1 an eine Funktion übergeben?

einefunktion(image_1);

Das war jetzt leicht ;-)

von Floh (Gast)


Lesenswert?

Neo schrieb:
> Aber wie bekomme ich jetzt mein image_1 an eine Funktion übergeben?

Im Normalfall übergibt man der Funktion den Zeiger auf den ersten Wert 
(hier image_1) und die Dimensionen des Arrays, falls im Unterprogramm 
benötigt.

von Neo (Gast)


Lesenswert?

So wollte ich's auch machen... klappt nur leider nicht:

Bekomme da erstmal eine Warnung bei der Übergabe:
warning: passing arg 1 of `G_DRAW_IMAGE' makes integer from pointer 
without a cast

und dann in der Funktion folgenden Error:
error: subscripted value is neither array nor pointer

So schaut meine Funktion aus an die ich das gange gerne übergeben würde:
1
void G_DRAW_IMAGE(uint16_t image, uint8_t x, uint8_t y, uint8_t color) {
2
    for (uint8_t byte_x=0; byte_x<image_w; byte_x++) {
3
      for (uint8_t byte_y=0; byte_y<(neobator_h-(image_h&0x07)); byte_y=byte_y+8) {
4
        DOG128_SET_BYTE(pgm_read_byte(&image[byte_x][byte_y/8]), byte_x+x, byte_y+y, color);
5
      }
6
    }   
7
  }

von g457 (Gast)


Lesenswert?

image ist kein uint16_t sonder ein uint8_t*;

von Neo (Gast)


Lesenswert?

Floh schrieb:
> Im Normalfall übergibt man der Funktion den Zeiger auf den ersten Wert
> (hier image_1) und die Dimensionen des Arrays, falls im Unterprogramm
> benötigt.

Also würde ich meiner Funktion einfach image_1[0][0] übergeben und dann, 
innerhalb der Dimensionen, image_1[x][y] hochzählen?
werd ich gleich mal probieren :)

von Floh (Gast)


Lesenswert?

Neo schrieb:
> Also würde ich meiner Funktion einfach image_1[0][0] übergeben und dann,
> innerhalb der Dimensionen, image_1[x][y] hochzählen?

Ne. image[0][0] ist ein uint8_t.
Du brauchst die Adresse des Arrays, also entweder &image_1[0][0] oder 
image_1 .

von Neo (Gast)


Lesenswert?

g457 schrieb:
> image ist kein uint16_t sonder ein uint8_t*;

gleiches Problem auch wenn ich's so mach:
1
void G_DRAW_IMAGE(uint8_t* image, uint8_t x, uint8_t y, uint8_t color)

außerdem dachte ich das Zeiger auf im Flash abgelegte Variabeln immer 
uint16_t sind?

von Neo (Gast)


Lesenswert?

oh fein so klapts:
1
G_DRAW_IMAGE(&image_1[0][0] ,0,0,1);
2
3
4
5
void G_DRAW_IMAGE(uint16_t image, uint8_t x, uint8_t y, uint8_t color) {
6
    
7
    for (uint8_t byte_x=0; byte_x<neobator_w; byte_x++) {
8
      for (uint8_t byte_y=0; byte_y<(neobator_h-(neobator_h&0x07)); byte_y=byte_y+8) {
9
        DOG128_SET_BYTE(pgm_read_byte(image), byte_x+x, byte_y+y, color);
10
        image++;
11
      }
12
    }
13
    
14
  }
allerdings doch uint16_t sonst bekomm ich nur 1/4 des bildes und der 
Rest ist naja... nenen wir es mal "rauschen"...

bekomme allerdings immernoch folgende Warnung:
main.c:153: warning: passing arg 1 of `G_DRAW_IMAGE' makes integer from 
pointer without a cast

wie bekomm ich die jetzt noch weg?

von g457 (Gast)


Lesenswert?

1
$ cat main.c 
2
#include <avr/pgmspace.h>
3
#include <inttypes.h>
4
5
const uint8_t image_1[2][6] PROGMEM = {
6
  {0x00, 0x00, 0x3F, 0x00, 0x00, 0x00},
7
  {0x00, 0x00, 0x3F, 0x00, 0x00, 0x00}
8
};
9
10
uint8_t funktion(const uint8_t* const pData, uint8_t x, uint8_t y, uint8_t resX)
11
{
12
        return pgm_read_byte(&(pData[y *resX +x]));
13
}
14
15
int main()
16
{
17
        return funktion(&(image_1[0][0]), 1, 2, 6);
18
}
19
$ avr-gcc -mmcu=atmega8 -Wall -o main main.c
20
$ file main
21
main: ELF 32-bit LSB executable, Atmel AVR 8-bit, version 1 (SYSV), statically linked, not stripped

HTHundichhoffichhabmirnichtindenadressenverhauen

von g457 (Gast)


Lesenswert?

> main.c:153: warning: passing arg 1 of `G_DRAW_IMAGE' makes integer from
> pointer without a cast

wie schon geschrubt (und oben inzwischen auch im Beispielcode 
vorgeschrubt): der formale Parameter 'image' ist ein POINTER, kein 
uint16_t (bzw. hat es der Einfachheit halber zu sein).

von Neo (Gast)


Lesenswert?

Jupp, klappt jetzt. dickes Danke euch beiden :)

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.