STM32 Pointer auf FLASH Adresse zuweisen

OP #7245398
Lesenswert?

Hallo,

zur Softwareentwicklung für einen STM32L4P5 nutze ich die STM32CubeIDE. 
Als c-Neuling scheitere ich an einer simplen Adresszuweisung. Ich habe 
ein Struktur-Array, das ich in den FLASH an eine bestimmte Adresse 
geschrieben habe. Ich möchte nun über ein Array auf diese Daten 
zugreifen.

struct calValue {
  unsigned freqMHz;
  float p22dBm;
  float p22V;
  float p20dBm;
};

/*Die Definition eines Pointers klappt noch ohne Compilerfehler*/
struct calValue *calPtr  =  ((struct calValue*)0x0804A000);

/*Diese Versuche zur Array-Definition schlagen kläglich fehl*/
__const struct calValue* cal[] = (struct calValue*) 0x0804A000;
__const struct calValue* cal[] __attribute__((_At(0x0804A000)));

Habe gelesen, dass man die LinkerScript Datei dafür ändern muss, was mir 
ja "sehr praktisch" erscheint. Muss ich wirklich die 
STM32L4P5CETX_FLASH.ld dafür ändern oder gibt es einen einfacheren Weg? 
Für ein Beispiel wäre ich sehr dankbar.

Dank im Voraus!
 Sigurd
Gast #7245419
Lesenswert?

1
const struct calValue cal[] __attribute__((_At(0x0804A000)))={{42U,22.0,22.2,20.0},{42U,22.0,22.2,20.0}};
2
const struct calValue* pcal=&cal[1];

wäre ein Versuch. Aber mein gcc meint Warnung "At" geht mir am .... 
vorbei. Also doch Linker Script anpassen.
Gast #7245426
Lesenswert?

Oh, ich lese gerade, die Daten stehen schon dort. Dann geht folgender 
Ansatz :
1
struct calValue {
2
  unsigned freqMHz;
3
  float p22dBm;
4
  float p22V;
5
  float p20dBm;
6
};
7

8
const struct calValue *calPtr  =  ((struct calValue*)0x0804A000UL);
9
.
10
.
11
.
12
value = calPtr[42].freqMHz;
#7245442
Lesenswert?

FOp schrieb:
> Oh, ich lese gerade, die Daten stehen schon dort. Dann geht folgender
> Ansatz :
>
1
> struct calValue {
2
>   unsigned freqMHz;
3
>   float p22dBm;
4
>   float p22V;
5
>   float p20dBm;
6
> };
7
> 
8
> const struct calValue *calPtr  =  ((struct calValue*)0x0804A000UL);
9
> .
10
> .
11
> .
12
> value = calPtr[42].freqMHz;
13
>

So ein Quatsch!
1
 const struct calValue {
2
   unsigned freqMHz;
3
   float p22dBm;
4
   float p22V;
5
   float p20dBm;
6
 };

Jetzt liegt die struct bereits im Flash, und der Linker kümmert sich um 
die Adresse.

Darauf kann man dann direkt zugreifen:
1
  calValue_ptr = &calValue;        // Pointer auf die struct selbst
2
  freqMHz_ptr = &calValue.freqMHz; // Pouinter auf das Element freqMHz in der struct
#7245445
Lesenswert?

Schöner wirds dann mit einem typedef:
1
 typedef struct calValue_t {
2
   unsigned freqMHz;
3
   float p22dBm;
4
   float p22V;
5
   float p20dBm;
6
 };
7

8
 const calValue_t calValue;
9

10
 calValue_t* calValue_ptr;
11
 unsigned frequMHz* freqMHZ_ptr;
12

13
  calValue_ptr = &calValue;        // Pointer auf die struct selbst
14
  freqMHz_ptr = &calValue.freqMHz; // Pouinter auf das Element freqMHz in der struct
#7245478
Lesenswert?

Harry L. schrieb:
> Schöner wirds dann mit einem typedef:

Er wird wohl mehr als ein Set an Werten haben.

Wie bereits geschrieben:
Kevin M. schrieb:
> Was versprichst du dir davon?
>
> Sigurd W. schrieb:
>> __const struct calValue* cal[] = (struct calValue*) 0x0804A000;
>> __const struct calValue* cal[] __attribute__((_At(0x0804A000)));
>
> du kannst doch mit der 1. Definition auf die Daten zugreifen:
>
>     value = calPtr->freqMHz;

Als Array kannst du das auch so machen:
1
/* Definition */
2
typedef struct {
3
  unsigned freqMHz;
4
  float p22dBm;
5
  float p22V;
6
  float p20dBm;
7
}calValue_t;
8

9
const calValue_t *calPtr  =  ((calValue_t*)0x0804A000);
10

11
/* Zugriff */
12

13
val1 = calPtr[0].freqMHz;
14
val2 = calPtr[0].p22dBm;
15

16
val3 = calPtr[1].freqMHz;
17
val4 = calPtr[1].p22dBm;

Ergebnis siehe Anhang (hier im RAM das spielt aber keine Rolle).
Angehängte Dateien:
Gast #7245485
Lesenswert?

Harry L. schrieb:
> So ein Quatsch!
> Jetzt liegt die struct bereits im Flash, und der Linker kümmert sich um
> die Adresse.

Laut erstem Beitrag liegt ein Array von diesen structs schon ohne den 
gesuchten Quellcode im Flash. Habe ich aber auch erstmal überlesen. Wie 
der dahin kommt : egal. Vielleicht hat er ja einen Generator, der eine 
.hex - Datei ausspuckt. Dein Code legt eine Struct selber an, und 
greift immer auf diese eine eigene zu.
OP #7245535
Lesenswert?

Vielen Dank für die schnellen Antworten.

Die Antwort von FOp und Kevin M. trifft es am Besten, da ich auf die 
einzelnen Elemente per Index zugreifen möchte und nicht einen Pointer 
inc- /dercremetieren will. Das ich auch den Pointer indizieren kann, hab 
ich nicht geahnt.

value = calPtr[42].freqMHz;

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren