Forum: Mikrocontroller und Digitale Elektronik GCC section für string


von Michael S. (michatroniker)


Lesenswert?

Hallo zusammen!

Ich hab ne Frage zu GCC:
ich möchte einen String im EEProm ablegen. Das geht ja über
1
__attribute__((section (".eepromSection")))
(mit einer entsprechenden section im linker file. leider funktioniert 
das nur bei Variablen:
1
char __attribute__((section (".eepromSection"))) abc[] = "meinStringImEEPROM";
Es funktioniert aber nicht, wenn ich einfach einen konstanten String aus 
dem EEPROM einer Funktion übergeben will:
1
void function(char * arg);
2
3
function(__attribute__((section (".eepromSection"))) "meinString");
--> das gibt nen Compiler error.
weiß jemand, wie die Syntax hierfür ist? Ich will ja nicht vor jedem 
Funktionsaufruf erst eine char* Variable erzeugen. Der String soll aber 
trotzdem in den EEPROM, um Flash speicher zu sparen.

dankeschön für euere Hilfe!
Michael

von Harry L. (mysth)


Lesenswert?

Du willst also 512Byte EEPROM mit Strings zumüllen um bei dem um ein 
Vielfaches größerem Flashspeicher ein paar Bytes zu sparen?

Klingt nach ner totalen Schnaps-Idee!

Das solltest du dringend nochmal überdenken!

von A.. P. (arnonym)


Lesenswert?

Harry L. schrieb:
> Du willst also 512Byte EEPROM mit Strings zumüllen um bei dem um ein
> Vielfaches größerem Flashspeicher ein paar Bytes zu sparen?
>
> Klingt nach ner totalen Schnaps-Idee!
>
> Das solltest du dringend nochmal überdenken!

"Entschuldigung, wo geht es hier denn nach… ?"

"Was, wo wollen Sie hin? Ne ne, ich erklär' Ihnen mal, wo sie hin 
wollen…"

: Bearbeitet durch User
von Brummbär (Gast)


Lesenswert?

Michael S. schrieb:
> weiß jemand, wie die Syntax hierfür ist? Ich will ja nicht vor jedem
> Funktionsaufruf erst eine char* Variable erzeugen. Der String soll aber
> trotzdem in den EEPROM, um Flash speicher zu sparen.

Der EEProm lässt sich nicht direkt mittels Pointer ansprechen.
Daher funktioniert der Aufruf auch nicht.

Entweder schreibst Du Deine Funktion so, dass sie direkt auf das EEProm 
zugreifen kann oder Du kopierst den String vorher in den RAM.

von Michael S. (michatroniker)


Lesenswert?

Brummbär schrieb:
> Der EEProm lässt sich nicht direkt mittels Pointer ansprechen.
> Daher funktioniert der Aufruf auch nicht.
>
> Entweder schreibst Du Deine Funktion so, dass sie direkt auf das EEProm
> zugreifen kann oder Du kopierst den String vorher in den RAM.

Danke dir! Allerdings funktioniert das beim STM32L0 soweit ich weiß 
schon:
1
char __attribute__((section (".eepromSection"))) __attribute__ ((aligned (4))) text[] = "meinString";
2
void function(char * arg);
3
4
int main(...){
5
    function(text);
6
}
dieser code funktioniert fehlerfrei, obwohl die variable text auf einen 
EEPROM Adressbereich zeigt. Ich hab nur keine Lust, für jeden String 
erst eine globale Variable zu definieren, würde das gern in der gleichen 
Zeile im Funktionsaufruf machen.

von (prx) A. K. (prx)


Lesenswert?

Brummbär schrieb:
> Der EEProm lässt sich nicht direkt mittels Pointer ansprechen.

Eine mutige Aussage, wenn man bedenkt, dass der Controller überhaupt 
nicht genannt wurde.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Mit einem Makro, einem Lambda und einer lokalen statischen Variablen 
geht es:
1
#include <cstdio>
2
3
#define EEPROM_STR(literal) ([] () -> const char (&) [sizeof(literal)] { static constexpr char str [] __attribute__((section(".eepromSection"))) = literal; return str; } ())
4
5
void test (const char* str) {
6
  puts (str);
7
}
8
9
int main () {
10
  test (EEPROM_STR("Hello, world!"));
11
}

Schön ist aber anders :-) Mit C++20 wird es vermutlich auch möglich ein 
User Defined Literal zu nutzen, in der Form test("Hello, world!"_eeprom) 
o.ä.

: Bearbeitet durch User
von Michael S. (michatroniker)


Lesenswert?

Niklas G. schrieb:
> Mit einem Makro, einem Lambda und einer lokalen statischen Variablen
> geht es:
>
>
1
#include <cstdio>
2
> 
3
> #define EEPROM_STR(literal) ([] () -> const char (&) [sizeof(literal)] { 
4
> static constexpr char str [] __attribute__((section(".eepromSection"))) 
5
> = literal; return str; } ())
6
> 
7
> void test (const char* str) {
8
>   puts (str);
9
> }
10
> 
11
> int main () {
12
>   test (EEPROM_STR("Hello, world!"));
13
> }
danke, klingt gut - ich versteh zwar nicht alles, aber leider gibts auch 
nen compiler error:

error: expected expression before '[' token

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Michael S. schrieb:
> error: expected expression before '[' token

Hm, wie genau sieht der Compiler-Aufruf aus, welche Compiler-Version 
hast du? Das ganze funktioniert erst ab C++11.

von Michael S. (michatroniker)


Lesenswert?

ich verwende C11 ohne C++...

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Achso. Aufgrund der weitgehenden Abwärtskompatibilität ist es aber 
meistens ohne großen Aufwand möglich, Projekte (teilweise) auf C++ 
umzustellen, damit man solche Funktionalität nutzen kann.

von Michael S. (michatroniker)


Lesenswert?

okay. Das sprengt dann aber wohl den Rahmen, für eine kleine solche 
Funktion auf C++ umzustellen. Ist nämlich ein recht großes Projekt, dann 
muss ich vllt eben doch globale variablen anlegen.
Danke dir jedenfalls für die Hilfe!

Michael

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.