Forum: Mikrocontroller und Digitale Elektronik STM32 Pointer auf FLASH Adresse zuweisen


von Sigurd W. (sig_w)


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

von Kevin M. (arduinolover)


Lesenswert?

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;

von Harry L. (mysth)


Lesenswert?

Sigurd W. schrieb:
> struct calValue {
>   unsigned freqMHz;
>   float p22dBm;
>   float p22V;
>   float p20dBm;
> };
1
const struct calValue {
2
   unsigned freqMHz;
3
   float p22dBm;
4
   float p22V;
5
   float p20dBm;
6
};
7
8
freqMHz_ptr = &calValue.freqMHz;
9
p22V_ptr = &calValue.p22dbm;
10
// usw.

: Bearbeitet durch User
von FOp (Gast)


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.

von FOp (Gast)


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;

von FOp (Gast)


Lesenswert?

noch besser :
1
const struct calValue * const calPtr  =  ((struct calValue*)0x0804A000UL);

weil die Adresse, wo der Gulasch steht ist ja auch konstant.

von Harry L. (mysth)


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

von Harry L. (mysth)


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

: Bearbeitet durch User
von Kevin M. (arduinolover)


Angehängte Dateien:

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).

von FOp (Gast)


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.

von Harry L. (mysth)


Lesenswert?

FOp schrieb:
> Dein Code legt eine Struct selber an, und
> greift immer auf diese eine eigene zu.

Du sprichst in Rätseln!

von J. S. (jojos)


Lesenswert?

Sowas ohne sections im Linkerfile zu machen ist aber schmutzig, das 
kommt irgendwann als Boomerang zurück. Der hat mich auch gerade wieder 
getroffen, mal eben zum Test einen Puffer ins RAM packen, ist ja genug 
da...

von Sigurd W. (sig_w)


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;

von Émile (Gast)


Lesenswert?

FOp schrieb:
1
 const struct calValue * const calPtr  =  ((struct  calValue*)0x0804A000UL);

Wobei helfen da die Klammern?

Schreibst Du auch
1
a = (b);

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.