Forum: Mikrocontroller und Digitale Elektronik AVR eigene #defines für Interruptvektoren


von Georg P. (perthil)


Lesenswert?

Ich versuche gerade meine eigenen Definitionen für Interruptvektoren zu 
generieren. Das ganze soll für eine USART so ablaufen: Ich definiere nur 
welche USART benutzt wird und alles andere soll via ## Operatoren 
generiert werden. Hier der Code:
1
#include <avr/interrupt.h>
2
3
/*
4
#define _VECTOR(N) __vector_ ## N
5
#define __INTR_ATTRS used, externally_visible
6
#define ISR(vector, ...)            \
7
    void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
8
    void vector (void)
9
*/
10
11
#define USART0_RXC_vect      _VECTOR(19)
12
13
#define cfgDBG_USART        USART0
14
15
#define STRING2(x)          #x
16
#define STRING(x)           STRING2(x)
17
18
#define CONCAT(y,z)         y##z
19
#define CONCAT2(y,z)        CONCAT(y,z)
20
21
#define dbgRXC_VECT         CONCAT2(cfgDBG_USART, _RXC_vect)
22
23
#pragma message ("dbgRXC_VECT = " STRING(dbgRXC_VECT))
24
25
26
ISR(dbgRXC_VECT){
27
  return;
28
}

Wenn ich das kompiliere kommt der folgende Fehler:

source/test.c:13:29: Fehler: das Einfügen von »)« und »_RXC_vect« ergibt 
kein gültiges Präprozessor-Token

Wenn ich aber interrupt.h nicht einbinde und statt dessen die 
auskommentierten Zeilen verwende funktioniert es. Die auskommentierten 
Zeilen sind die für den Interrupt notwendigen Definitionen aus 
interrupt.h und sfr_defs.h. USART0_RXC_vect habe ich aus der über io.h 
eingebundenen Hardwarebeschreibungsdatei.

Ich benutze MPLABX Version 6.10 und avr-gcc in Version 5.4.0.

Ich habe auch versucht das Konzept für andere Sachen als den 
Interruptvektor zu verwenden. Sobald ich aber irgendwas aus der avr 
Library einbinde passiert genau dasselbe. Irgendwas in dieser Library 
verhindert also, dass das richtig übersetzt wird.

Hat jemand vielleicht eine Idee was das sein könnte und wie man das 
umgehen kann?

: Verschoben durch Moderator
von Oliver S. (oliverso)


Lesenswert?

Läuft denn der Preprozessor alleine durch? Dann kannst du dir doch 
anschauen, was der da zusammenbastelt.

Ansonsten wird wohl niemand für dich sich durch die Sourcen der avrlibc 
wühlen, um dein ganz spezielles Problem zu lösen. Das musst du schon 
selber machen.

Oliver

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wie sieht die GCC-Kommandozeile aus?

Bezieht sich die in der Fehlermeldung angegebene Zeilennummer 13
wirklich auf den geposteten Code? In dieser Zeile steht ein
unverdächtiges
1
#define cfgDBG_USART        USART0

von Oliver S. (oliverso)


Lesenswert?

Georg P. schrieb:
> Wenn ich das kompiliere kommt der folgende Fehler:
1
11:40:33 **** Build of configuration Release for project AVRTest ****
2
make all 
3
Building file: ../main.c
4
Invoking: AVR Compiler
5
avr-gcc -Wall -Os -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -flto -std=gnu99 -funsigned-char -funsigned-bitfields -Wl,-u,vfprintf -lprintf_min -mmcu=atmega328p -DF_CPU=1000000UL -MMD -MP -MF"main.d" -MT"main.o" -c -o "main.o" "../main.c"
6
../main.c:31:9: note: '#pragma message: dbgRXC_VECT = __vector_19'
7
   31 | #pragma message ("dbgRXC_VECT = " STRING(dbgRXC_VECT))
8
      |         ^~~~~~~
9
Finished building: ../main.c
10
 
11
Building target: AVRTest.elf
12
Invoking: AVR C Linker
13
avr-gcc -Wl,-Map,AVRTest.map -mmcu=atmega328p -o "AVRTest.elf"  ./main.o   
14
Finished building target: AVRTest.elf
15
 
16
Invoking: AVR Create Extended Listing
17
avr-objdump -h -S AVRTest.elf  >"AVRTest.lss"
18
Finished building: AVRTest.lss
19
 
20
Create Flash image (ihex format)
21
avr-objcopy -R .eeprom -R .fuse -R .lock -R .signature -O ihex AVRTest.elf  "AVRTest.hex"
22
Finished building: AVRTest.hex
23
 
24
Create eeprom image (ihex format)
25
avr-objcopy -j .eeprom --no-change-warnings --change-section-lma .eeprom=0 -O ihex AVRTest.elf  "AVRTest.eep"
26
Finished building: AVRTest.eep
27
 
28
Invoking: Print Size
29
avr-size --format=berkeley -t AVRTest.elf
30
   text     data      bss      dec      hex  filename
31
    140        0        0      140       8c  AVRTest.elf
32
    140        0        0      140       8c  (TOTALS)
33
Finished building: sizedummy
34
 
35
36
11:40:40 Build Finished. 0 errors, 0 warnings. (took 7s.396ms)

gcc 12.0

Oliver

von Steve van de Grens (roehrmond)


Lesenswert?

Ich habe das anders gelöst:
1
#ifdef USE_SERIAL0
2
...
3
#endif
4
5
#ifdef USE_SERIAL1
6
...
7
#endif

Zwischen diese Makros packe ich den spezifischen Code. Mein Editor zeigt 
mit hellgrauer Schrift, welche Blöcke inaktiv sind.

Mehrfach verschachtelte Makros vermeide ich, denn sie führen manchmal zu 
Fehlermeldungen, die ich nicht durchblicke.

: Bearbeitet durch User
Beitrag #7571916 wurde vom Autor gelöscht.
von Georg P. (perthil)


Lesenswert?

Oliver S. schrieb:
> Läuft denn der Preprozessor alleine durch? Dann kannst du dir doch
> anschauen, was der da zusammenbastelt.
>
> Ansonsten wird wohl niemand für dich sich durch die Sourcen der avrlibc
> wühlen, um dein ganz spezielles Problem zu lösen. Das musst du schon
> selber machen.
>
> Oliver

Es ist ja ein Präprozessorfehler, da vermute ich dass er gar keine 
Ausgabe generiert. Deshalb habe ich da gar nicht gesucht. Aber ich werde 
es Mal probieren.

So speziell ist das Problem meiner Ansicht nach gar nicht, ## wird auch 
in der avr-libc benutzt.

Ich dachte halt dass es dieses Problem eventuell schon Mal gab und ich 
könne die Fehlersuche etwas beschleunigen.

Georg

von Georg P. (perthil)


Lesenswert?

Yalu X. schrieb:
> Wie sieht die GCC-Kommandozeile aus?
>
> Bezieht sich die in der Fehlermeldung angegebene Zeilennummer 13
> wirklich auf den geposteten Code? In dieser Zeile steht ein
> unverdächtiges
>
>
1
> #define cfgDBG_USART        USART0
2
>

Die Kommandozeile samt den Fehlermeldungen ist:
1
CLEAN SUCCESSFUL (total time: 59ms)
2
"/usr/bin/avr-gcc"   -mmcu=avr128da32 -I "/opt/microchip/mplabx/v6.10/packs/Microchip/AVR-Dx_DFP/2.3.272/include" -B "/opt/microchip/mplabx/v6.10/packs/Microchip/AVR-Dx_DFP/2.3.272/gcc/dev/avr128da32"  -x c -c -D__AVR128DA32__  -I"/usr/lib/avr/include" -I"include" -I"config" -I"../Library/include" -funsigned-char -funsigned-bitfields -O0 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -save-temps -MD -MP -MF "build/default/production/source/test.o.d" -MT "build/default/production/source/test.o.d" -MT build/default/production/source/test.o  -o build/default/production/source/test.o source/test.c  -DXPRJ_default=default    -fstack-usage
3
source/test.c:13:29: Fehler: das Einfügen von »)« und »_RXC_vect« ergibt kein gültiges Präprozessor-Token
4
 #define cfgDBG_USART        USART0
5
                             ^
6
source/test.c:18:29: Anmerkung: in Definition des Makros »CONCAT«
7
 #define CONCAT(y,z)         y##z
8
                             ^
9
source/test.c:21:29: Anmerkung: bei Substitution des Makros »CONCAT2«
10
 #define dbgRXC_VECT         CONCAT2(cfgDBG_USART, _RXC_vect)
11
                             ^
12
source/test.c:21:37: Anmerkung: bei Substitution des Makros »cfgDBG_USART«
13
 #define dbgRXC_VECT         CONCAT2(cfgDBG_USART, _RXC_vect)
14
                                     ^
15
source/test.c:23:42: Anmerkung: bei Substitution des Makros »dbgRXC_VECT«
16
 #pragma message ("dbgRXC_VECT = " STRING(dbgRXC_VECT))
17
                                          ^
18
source/test.c:13:29: Fehler: das Einfügen von »)« und »_RXC_vect« ergibt kein gültiges Präprozessor-Token
19
 #define cfgDBG_USART        USART0
20
                             ^
21
source/test.c:18:29: Anmerkung: in Definition des Makros »CONCAT«
22
 #define CONCAT(y,z)         y##z
23
                             ^
24
source/test.c:21:29: Anmerkung: bei Substitution des Makros »CONCAT2«
25
 #define dbgRXC_VECT         CONCAT2(cfgDBG_USART, _RXC_vect)
26
                             ^
27
source/test.c:21:37: Anmerkung: bei Substitution des Makros »cfgDBG_USART«
28
 #define dbgRXC_VECT         CONCAT2(cfgDBG_USART, _RXC_vect)
29
                                     ^
30
source/test.c:26:5: Anmerkung: bei Substitution des Makros »dbgRXC_VECT«
31
 ISR(dbgRXC_VECT){
32
     ^
33
make: *** [nbproject/Makefile-default.mk:286: build/default/production/source/test.o] Error 1
34
35
BUILD FAILED (exit value 2, total time: 67ms)

Georg

von Georg P. (perthil)


Lesenswert?

Steve van de Grens schrieb:
> Ich habe das anders gelöst:
>
1
> #ifdef USE_SERIAL0
2
> ...
3
> #endif
4
> 
5
> #ifdef USE_SERIAL1
6
> ...
7
> #endif
8
>
>
> Zwischen diese Makros packe ich den spezifischen Code. Mein Editor zeigt
> mit hellgrauer Schrift, welche Blöcke inaktiv sind.
>
> Mehrfach verschachtelte Makros vermeide ich, denn sie führen manchmal zu
> Fehlermeldungen, die ich nicht durchblicke.

Ja, so hatte ich das vorher auch. Aber vor Jahren hatte ich auch schon 
Mal das mit dem ## benutzt. Es erscheint mir irgendwie logischer. Damals 
ging es; also würde ich es gerne wieder so machen.

Georg

von Oliver S. (oliverso)


Lesenswert?

Georg P. schrieb:
> Ich dachte halt dass es dieses Problem eventuell schon Mal gab und ich
> könne die Fehlersuche etwas beschleunigen.

Da der avr-gcc 12 auf meinem Rechner das fehlerfrei compiliert (siehe 
oben), ists wohl entweder ein Problem deines Uraltcompilers, oder deine 
Installation ist kaputt.

Für welchen AVR compilierst du denn?

Oliver

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Georg P. schrieb:

> Wenn ich das kompiliere kommt der folgende Fehler:
>
> source/test.c:13:29: Fehler: das Einfügen von »)« und »_RXC_vect« ergibt
> kein gültiges Präprozessor-Token

Für welche AVR-Familie soll Dein Code genutzt werden? Ich vermute, dass 
in dem Header mit den Registerdefinitionen Deiner MCU USART0 und USART1 
bereits als Pointer auf eine Struktur definiert sind, z.B. so:
#define USART0              (*(USART_t *) 0x0800)
#define USART1              (*(USART_t *) 0x0820)

Mein Vorschlag: Bau das Symbol aus drei Elementen zusammen.
Das erste ist das konstante Schlüsselwort "USART"
das  zweite ist ein Makro, das die Ziffer 0 oder 1 enthält
das dritte ist das konstante Schlüsselwort "_RXC_vect"

So zum Beispiel:

#define cfgDBG_USART_NO     0
...
#define dbgRXC_VECT         CONCAT3(USART, cfgDBG_USART_NO, _RXC_vect)

Grüßle,
Volker

: Bearbeitet durch User
von Georg P. (perthil)


Lesenswert?

Oliver S. schrieb:
> Georg P. schrieb:
>> Ich dachte halt dass es dieses Problem eventuell schon Mal gab und ich
>> könne die Fehlersuche etwas beschleunigen.
>
> Da der avr-gcc 12 auf meinem Rechner das fehlerfrei compiliert (siehe
> oben), ists wohl entweder ein Problem deines Uraltcompilers, oder deine
> Installation ist kaputt.
>
> Für welchen AVR compilierst du denn?
>
> Oliver

Ich habe den genommen der im Ubuntu Repository ist. Dort ist leider nur 
diese Version. Ich habe auch Mal nach einer neueren gesucht, aber damals 
nichts gefunden. Ich werde also nochmal suchen.

Prozessor ist ein AVR128DA32.

Ich habe jetzt Mal in dem Präprozessorlisting geschaut, und da wird 
USART0 durch eine Adresse ersetzt. Siehe die Antwort von Volker. Das 
probiere ich jetzt Mal.

Danke, Georg

von Steve van de Grens (roehrmond)


Lesenswert?

Georg P. schrieb:
> Ich habe auch Mal nach einer neueren gesucht, aber damals
> nichts gefunden.

https://blog.zakkemble.net/avr-gcc-builds/

von Georg P. (perthil)


Lesenswert?

Volker B. schrieb:

> Für welche AVR-Familie soll Dein Code genutzt werden? Ich vermute, dass
> in dem Header mit den Registerdefinitionen Deiner MCU USART0 und USART1
> bereits als Pointer auf eine Struktur definiert sind, z.B. so:
> #define USART0              (*(USART_t *) 0x0800)
> #define USART1              (*(USART_t *) 0x0820)
>
> Mein Vorschlag: Bau das Symbol aus drei Elementen zusammen.
> Das erste ist das konstante Schlüsselwort "USART"
> das  zweite ist ein Makro, das die Ziffer 0 oder 1 enthält
> das dritte ist das konstante Schlüsselwort "_RXC_vect"
>
> So zum Beispiel:
>
> #define cfgDBG_USART_NO     0
> ...
> #define dbgRXC_VECT         CONCAT3(USART, cfgDBG_USART_NO, _RXC_vect)
>
> Grüßle,
> Volker

Ich habe jetzt auch gefunden dass USART0 durch die Speicheradresse 
ersetzt wird. Ich denke das war es dann. Ich bin gerade dabei das 
abzuändern.

Danke, Georg

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.