mikrocontroller.net

Forum: Compiler & IDEs __attribute__( ( alias( "."))) funktioniert nicht


Autor: Martin Freund (martinf)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hey,

hab folgendes Problem:
Ich brauch ne polymorphe Funktion, die Stringparameter aus dem Daten- 
und Programmbereich unterscheiden kann.
void foo( const char* const _cstrText) { ... }
und
typedef char __attribute__( ( __progmem__))  prog_char;
void foo( const prog_char* const _cstrText) { ... }
funktioniert nicht, da beide Typgleich sind.



Also hab ich mir einen neuen Typ erstellt:
struct __attribute__( ( __progmem__)) __SProgChar {
  char __dummy;
};
typedef struct __SProgChar pchar_t;

Um nun einen String (hier: abc mit Inhalt "test") im Programmspeicher 
abzulegen, benutze ich
__asm(
  "\n\t .text"
  "\n\t .align 2"
  "\n\t .global abc" 
  "\n\t abc: .asciz \"test\""
);
extern const prog_char* abc[];
extern pchar_t identifier[sizeof( "test")] __attribute__( ( alias( "abc")));

Obwohl abc im asm-Teil global und im cpp-Teil extern deklariert ist, 
bekomme ich beim compilieren folgende Fehlermeldung in der letzten 
Zeile:
error: 'identifier' aliased to undefined symbol 'abc'

Ist das ein Bug oder überseh ich was?

mfg Martin

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Alias-Target muss in der selben Datei definiert sein. abc ist aber 
nur deklariert, nicht definiert. Und die Symbol-Definition im asm-Teil 
wird vom Compiler natürlich nicht als solches erkannt (erst später dann 
vom Assembler). Wozu brauchst du das Alias überhaupt? Deklariere doch 
abc gleich in dem von dir gewünschten Typ.

Außerdem fehlt im dem asm-Teil auch noch ein align hinter den Daten. 
Lass das Platzieren der Daten im Flash doch den Compiler erledigen. 
Definiere doch einfach in einer anderen Datei abc als normalen 
Flash-String.

Autor: Martin Freund (martinf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie gesagt, ich kann den String nicht per prog_char ablegen, da 
prog_char typgleich mit char ist und dann die Polymorphie nicht mehr 
funktioniert.

Ich hab mir ne andere Möglichkeit überlegt, mit der ich recht zufrieden 
bin:
#define CreatePGMStringDecl( identifier) \
  extern const prog_char identifier##_p[]; \
  extern const pchar_t identifier[]

#define CreatePGMStringDef( identifier, value) \
  const prog_char identifier##_p[] = value; \
  extern const pchar_t identifier[sizeof( identifier##_p)] __attribute__( ( alias( #identifier"_p")))

in der Headerdatei:
CreatePGMStringDecl( abc);

in der Quelldatei:
CreatePGMStringDef( abc, "test");

Somit hab ich jetzt zwei Arrays aber trotzdem nur einen Speicherort.
Was die Definition im asm-Teil angeht, die der Compiler nicht erkennt, 
hast du recht. Jetzt funktioniert das alias nämlich ohne Probleme.

Vielen Dank für den Tipp

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin Freund schrieb:
> Wie gesagt, ich kann den String nicht per prog_char ablegen, da
> prog_char typgleich mit char ist und dann die Polymorphie nicht mehr
> funktioniert.

Nicht? Du machst es doch mit deiner Lösung jetzt auch.

Mein Vorschlag war halt nur etwas simpler gestrickt.

FlashData.cpp:
char abc[] PROGMEM = "test";
Hier werden die Daten nur ins Flash gepackt, und sonst nichts weiter 
gemacht.


SomeOtherFile.cpp oder FlashData.h:
extern const pchar_t abc[];
Hier kannst du die Daten dann mit dem gewünschten Typ verwenden.

Autor: Martin Freund (martinf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Wie gesagt, ich kann den String nicht per prog_char ablegen, da
>> prog_char typgleich mit char ist und dann die Polymorphie nicht mehr
>> funktioniert.
>
> Nicht? Du machst es doch mit deiner Lösung jetzt auch.

Ich leg ihn jetzt zwar per prog_char ab, aber als abc_p. Auf den 
alternativen Typ greif ich ohne den Zusatz "_p" zu.

Wenn ichs so mach
> char abc[] PROGMEM = "test";
> extern const pchar_t abc[];
dann bekomm ich
error: conflicting declaration 'const pchar_t abc []'
error: 'abc' has a previous declaration as 'char abc [5]'

Genau deswegen brauch ich ein alias.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe ja auch nicht ohne Grund "andere Datei" geschrieben. Und ich 
dachte auch mein Beispiel würde das verdeutlichen.

Autor: Martin Freund (martinf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahhh, hab vor Eifer nicht dran gedacht dass die Trennung zwischen 
Deklaration/Definition jetzt verpflichtend ist.
Vielen Dank für deine Hilfe.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin Freund schrieb:
> Ahhh, hab vor Eifer nicht dran gedacht dass die Trennung zwischen
> Deklaration/Definition jetzt verpflichtend ist.

Wenn beides unterschiedliche Typen haben soll, dann schon. ;-)

Versteh mich nicht falsch, ich will dich zu nichts überreden. Wenn du 
eine für dich funktionierenden Lösung hast, dann ist es ja ok. Ich 
wollte nur darauf hinweisen, dass der Alias nicht zwingend notwendig 
ist.

Autor: Martin Freund (martinf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine Lösung ist definitv sauberer. Wenn ichs per asm mach, erscheinen 
die Strings nicht in der Exporttabelle von avr-nm. Und wenn ichs mit nem 
alias mach, bekomm ich doppelte Einträge. Ich hab auf jeden Fall was 
dazu gelernt ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.