Forum: Mikrocontroller und Digitale Elektronik #pragma wird ignoriert


von Der G. (jonnyk)


Lesenswert?

Hallo Leute hoffe mir kann jemand Helfen

Habe folgenden code von einem anderen (also nicht AVRGCC) compiler:
1
#define LED_ADDRESSE          0x1181  // externes Register für Led 9
2
3
4
#pragma location=LED_ADDRESSE
5
__no_init uint8 ui8_Led_AD;                  // LED 9
wie kann ich das in AVRGCC übersetzen?

Ich kriege immer 1 warnung dass #pragma ignoriert wird

und einen Fehler

Expected '=',',',';' ... before 'uint8'

Hoffe jemand weiß bescheid.

von Sven P. (Gast)


Lesenswert?

Pragma sind Kompilerdirektiven, die dürfen von jedem Kompiler nach 
belieben bewertet oder ignoriert werden (bis auf die paar 
Fließkomma-Pragmas in C99).

Bei dir bemängelt der Kompiler, dass "__no_init" nicht definiert wurde. 
Was das "location"-Pragma bewirken soll, weiß ich nicht, aber wie man 
eine Variable an eine bestimmte Stelle im RAM/SFR verankert, ist den 
libc-Headern in aller Ausführlichkeit zu entnehmen.

von Der G. (jonnyk)


Lesenswert?

in welchen Headern???
wo finde ich sie?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Was du willst, ist übrigens die section .noinit.

Die Zuordnung zu den Speicherstellen macht der Linker, nicht der
Compiler, daher muss man auch diesem mitteilen, wenn man bestimmte
Dinge an bestimmten Stellen im Speicher haben will.  Der Compiler
hat darauf keinen Einfluss.

Wenn man aber ein externes Register anspricht, ist es allemal das
Einfachste, dass man das über einen entsprechenden Zeiger macht:
1
#define LED_ADRESSE 0x1181
2
#define Led_AD (*(volatile uint8_t *)0x1181)

Das spart den ganzen Zirkus mit dem Linker und ist noch dazu sogar
zwischen den Compilern praktisch portabel.

von Sven P. (Gast)


Lesenswert?

Jörg Wunsch wrote:
> Was du willst, ist übrigens die section .noinit.
Womit er immer noch keinen Schritt weiter ist. So geht das mit AVR-GCC:
1
uint8 ui8_Led_AD __attribute__ ((section (".noinit")));

Wobei ich mir mit "uint8" auch nicht sicher bin, zum Standard gehört das 
jedenfalls nicht, da heißt das "uint8_t", also mit _t hinten dran.

> Die Zuordnung zu den Speicherstellen macht der Linker, nicht der
> Compiler, daher muss man auch diesem mitteilen, wenn man bestimmte
> Dinge an bestimmten Stellen im Speicher haben will.  Der Compiler
> hat darauf keinen Einfluss.
Der Linker bindet den Kram zusammen und verteilt automatisch Code auf 
Code-(Text-)Segmente und Daten auf Datensegmente, jo. An welchen 
(numerischen) Adressen der Programmierer in seinem Code aber rumwerkelt, 
ist dem Linker ziemlich wurscht, weil der nur Speicherstellen nur dann 
zuordnen kann, wenn er sie auch kennt, sie also Namen haben.

> Wenn man aber ein externes Register anspricht, ist es allemal das
> Einfachste, dass man das über einen entsprechenden Zeiger macht:
>
1
> #define LED_ADRESSE 0x1181
2
> #define Led_AD (*(volatile uint8_t *)0x1181)
3
>

Macht die libc auch so:
1
/* Aus avr/sfr_defs.h */
2
3
/* Je nach Controller: */
4
#define __SFR_OFFSET 0x20
5
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
6
#define PORTB  _SFR_IO8(0x18)

> Das spart den ganzen Zirkus mit dem Linker und ist noch dazu sogar
> zwischen den Compilern praktisch portabel.
Wie gesagt, wenn du numerische Adressen angibst, geht das den Linker 
garnichts an.

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.