Forum: Compiler & IDEs gcc 5 mit --gc-sections killt interrupt vectoren


von Hans W. (Firma: Wilhelm.Consulting) (hans-)


Lesenswert?

Hallo Leute!

Habe mich gerade mit dem gcc 5.3 geärgert... irgendwie optimiert er mit 
meine interrupt vectoren raus wenn man mit --gc-sections (+ 
-ffunction-sections/-fdata-sections) arbeitet.

Anscheinend liegt das am neuen linker (zumindest interpretiere ich den 
letzten post in 
http://stackoverflow.com/questions/23668247/gcc-warning-used-attribute-ignored 
so)...


Die Lösung war für mich folgende (diff gegen svn):
1
--- interrupt.h_orig    2016-01-25 21:55:47.427354891 +0100
2
+++ interrupt.h 2016-01-25 22:04:47.377367723 +0100
3
@@ -125,10 +125,14 @@
4
 #  define ISR(vector, [attributes])
5
 #else  /* real code */
6
 
7
-#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
8
-#  define __INTR_ATTRS used, externally_visible
9
-#else /* GCC < 4.1 */
10
-#  define __INTR_ATTRS used
11
+#if (__GNUC__ > 4)
12
+#    define __INTR_ATTRS used, externally_visible, section (".vectors")
13
+#else
14
+#  if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
15
+#    define __INTR_ATTRS used, externally_visible
16
+#  else /* GCC < 4.1 */
17
+#    define __INTR_ATTRS used
18
+#  endif
19
 #endif
20
 
21
 #ifdef __cplusplus


irgend jemand eine schöner Lösung parat?

Das linker-script hat übrigens den notwendigen KEEP drinnen...

73

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

ALso jetzt GCC oder LD der Bösewicht?

Mit GCC 5.2.1, Binutils 2.25.51 und folgendem Programm kann ich das 
nicht bestätigen:
1
#include <avr/interrupt.h>
2
3
ISR (INT0_vect) {}
4
5
int main;

Präprocessed:
1
void __vector_1 (void) __attribute__ ((signal,used, externally_visible)) ; void __vector_1 (void) 
2
               {}
3
int main;

wobei compiliert mit
1
avr-gcc -mmcu=attiny44 -Os foo.c -o foo.elf -save-temps -Wl,-Map,foo.map -Wl,--gc-sections -ffunction-sections

Im Disassembly von foo.elf steht dann auch brav __vector_1 drinne.

Ich zieh dir jetzt mal nicht jeden Wurm einzeln aus der Nase; ich geh 
mal davon aus dass du weisst, was andere brauchen um dein Problem 
nachzuvollziehen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

...und die ISRs gehören NICHT nach .vectors!

In .vectors stehen die IRQ-Vektoren, die einen (R)JMP zu jeweiligen ISR 
(bzw. __bad_interrupt als Default) enthalten.

Was treibst du da???

von Hans W. (Firma: Wilhelm.Consulting) (hans-)


Lesenswert?

ok... .vectors ist falsch... typischer fall von RTFM...

Das Grundproblem bleibt.

Ohne Patch:
1
00000000 l    d  .text  00000000 .text
2
00800060 l    d  .data  00000000 .data
3
00000000 l    df *ABS*  00000000 _clear_bss.o
4
0000000a l       .text  00000000 .do_clear_bss_start
5
00000008 l       .text  00000000 .do_clear_bss_loop
6
00000000 l    df *ABS*  00000000 
7
00000010 l       *ABS*  00000000 __data_load_start
8
00000000 g       .text  00000000 __trampolines_start
9
00000010 g       .text  00000000 _etext
10
00000010 g       *ABS*  00000000 __data_load_end
11
00000000 g       .text  00000000 __trampolines_end
12
00000000 g       .text  00000000 __dtors_end
13
00800060 g       .data  00000000 __bss_end
14
00000000 g       .text  00000010 .hidden __do_clear_bss
15
00810000 g       .data  00000000 __eeprom_end
16
00000000 g       .text  00000000 __ctors_start
17
00800060 g       .data  00000000 __bss_start
18
00000000 g       .text  00000000 __dtors_start
19
00000000 g       .text  00000000 __ctors_end
20
00800060 g       .data  00000000 _edata
21
00800060 g       .data  00000000 _end

Mit patch:
1
00000000 l    d  .text  00000000 .text
2
00800060 l    d  .data  00000000 .data
3
00000000 l    d  .comment       00000000 .comment
4
00000000 l    df *ABS*  00000000 main.c
5
0000003e l       *ABS*  00000000 __SP_H__
6
0000003d l       *ABS*  00000000 __SP_L__
7
0000003f l       *ABS*  00000000 __SREG__
8
00000000 l       *ABS*  00000000 __tmp_reg__
9
00000001 l       *ABS*  00000000 __zero_reg__
10
00000000 l    df *ABS*  00000000 _clear_bss.o
11
0000003a l       .text  00000000 .do_clear_bss_start
12
00000038 l       .text  00000000 .do_clear_bss_loop
13
00000000 l    df *ABS*  00000000 
14
00000040 l       *ABS*  00000000 __data_load_start
15
00000030 g       .text  00000000 __trampolines_start
16
00000040 g       .text  00000000 _etext
17
00000040 g       *ABS*  00000000 __data_load_end
18
00000030 g       .text  00000000 __trampolines_end
19
00000030 g       .text  00000000 __dtors_end
20
00800060 g       .data  00000000 __bss_end
21
00000000 g     F .text  00000030 __vector_17
22
00000030 g       .text  00000010 .hidden __do_clear_bss
23
00810000 g       .data  00000000 __eeprom_end
24
00000030 g       .text  00000000 __ctors_start
25
00800060 g       .data  00000000 __bss_start
26
00000030 g       .text  00000000 __dtors_start
27
00000030 g       .text  00000000 __ctors_end
28
00800060 g       .data  00000000 _edata
29
00800060 g       .data  00000000 _end

ohne --gc-sectiions:
1
00000000 l    d  .text  00000000 .text
2
00800060 l    d  .data  00000000 .data
3
00800060 l    d  .bss   00000000 .bss
4
00000000 l    d  .comment       00000000 .comment
5
00000000 l    df *ABS*  00000000 _clear_bss.o
6
0000000a l       .text  00000000 .do_clear_bss_start
7
00000008 l       .text  00000000 .do_clear_bss_loop
8
00000000 l    df *ABS*  00000000 main.c
9
0000003e l       *ABS*  00000000 __SP_H__
10
0000003d l       *ABS*  00000000 __SP_L__
11
0000003f l       *ABS*  00000000 __SREG__
12
00000000 l       *ABS*  00000000 __tmp_reg__
13
00000001 l       *ABS*  00000000 __zero_reg__
14
00000000 l    df *ABS*  00000000 _divmodhi4.o
15
000000ac l       .text  00000000 __divmodhi4_neg1
16
000000b4 l       .text  00000000 __divmodhi4_neg2
17
000000ba l       .text  00000000 __divmodhi4_exit
18
00000000 l    df *ABS*  00000000 _udivmodhi4.o
19
000000d2 l       .text  00000000 __udivmodhi4_ep
20
000000c4 l       .text  00000000 __udivmodhi4_loop
21
0000003e g     F .text  00000028 WriteByteToBuffer
22
000000bc g       .text  0000002c .hidden __udivmodhi4
23
00000000 g       .text  00000000 __trampolines_start
24
000000e8 g       .text  00000000 _etext
25
000000e8 g       *ABS*  00000000 __data_load_end
26
00000000 g       .text  00000000 __trampolines_end
27
000000e8 g       *ABS*  00000000 __data_load_start
28
00000000 g       .text  00000000 __dtors_end
29
008000e8 g       .bss   00000000 __bss_end
30
00000066 g     F .text  00000030 __vector_17
31
00000000 g       .text  00000010 .hidden __do_clear_bss
32
00810000 g       .comment       00000000 __eeprom_end
33
00000010 g     F .text  00000030 NextByteFromBuffer
34
00000096 g       .text  00000026 .hidden __divmodhi4
35
00000000 g       .text  00000000 __ctors_start
36
00800060 g       .bss   00000000 __bss_start
37
00800060 g     O .bss   00000044 SendBuffer
38
008000a4 g     O .bss   00000044 ReceiveBuffer
39
00000000 g       .text  00000000 __dtors_start
40
00000000 g       .text  00000000 __ctors_end
41
00800060 g       .data  00000000 _edata
42
008000e8 g       .comment       00000000 _end
43
00000096 g       .text  00000000 .hidden _div


GCC aufruf:
avr-gcc -std=gnu11 -Os -Wall -Wextra -Wconversion -fomit-frame-pointer 
-c -fmessage-length=0 -mmcu=atmega328p      -ffunction-sections 
-fdata-sections -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.c"


Linking:
avr-gcc -Xlinker --gc-sections -Xlinker --relax -Xlinker --strip-debug



Irgendwas mag er also beim linking nicht...

73

von Hans W. (Firma: Wilhelm.Consulting) (hans-)


Lesenswert?

Mir fällt gerade auf, dass nicht einmal main() mitgelinkt wird....

es wird immer schräger...

73

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Hans W. schrieb:
> Linking:
> avr-gcc -Xlinker --gc-sections -Xlinker --relax -Xlinker --strip-debug

Wie wär's dem Linker Objekte wie main.o zu überreichen?

Und wie wär's mit -mmcu=?

von Hans W. (Firma: Wilhelm.Consulting) (hans-)


Lesenswert?

Sorry, habe die Parameter gekürzt... aber der invoke sollte passen...
1
00:29:04 **** Build of configuration Debug for project BeeStalkerMk1Firmware ****
2
make all 
3
Building file: ../main.c
4
Invoking: Cross GCC Compiler
5
avr-gcc -std=gnu11 -Os -Wall -Wextra -Wconversion -mmcu=atmega328p -ffunction-sections -fdata-sections -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.c"
6
Finished building: ../main.c
7
 
8
Building target: BeeStalkerMk1Firmware
9
Invoking: Cross GCC Linker
10
avr-gcc -Xlinker -Map=output.map -Xlinker --gc-sections -Xlinker --strip-debug -o "BeeStalkerMk1Firmware"  ./main.o   
11
Finished building target: BeeStalkerMk1Firmware
12
 
13
make --no-print-directory post-build
14
avr-objcopy -O ihex -j .text -j .data -j .vectors BeeStalkerMk1Firmware  BeeStalkerMk1Firmware.hex; avr-objdump -D BeeStalkerMk1Firmware > BeeStalkerMk1Firmware.lst
15
 
16
17
00:29:04 Build Finished (took 111ms)

Damit bekomme ich kein vernünftiges binary.

Dagegen liefert
1
00:31:32 **** Build of configuration Debug for project BeeStalkerMk1Firmware ****
2
make all 
3
Building file: ../main.c
4
Invoking: Cross GCC Compiler
5
avr-gcc -std=gnu11 -Os -Wall -Wextra -Wconversion -mmcu=atmega328p -flto -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.c"
6
Finished building: ../main.c
7
 
8
Building target: BeeStalkerMk1Firmware
9
Invoking: Cross GCC Linker
10
avr-gcc -Xlinker -Map=output.map -Xlinker --strip-debug -o "BeeStalkerMk1Firmware"  ./main.o   
11
Finished building target: BeeStalkerMk1Firmware
12
 
13
make --no-print-directory post-build
14
avr-objcopy -O ihex -j .text -j .data -j .vectors BeeStalkerMk1Firmware  BeeStalkerMk1Firmware.hex; avr-objdump -D BeeStalkerMk1Firmware > BeeStalkerMk1Firmware.lst
15
 
16
17
00:31:32 Build Finished (took 124ms)

genau das was ich will....


Spannend...

73

von g457 (Gast)


Lesenswert?

> Sorry, habe die Parameter gekürzt... aber der invoke sollte passen...

Da fehlen immernoch Parameter wie mir scheint.

von Hans (Gast)


Lesenswert?

das ist copy/paste aus eclipse...

mir ist beim Vergleichen mit den Beispielmakefiles aus der 
Artikelsammlung nichts wesentliches aufgefallen.

73

von guest (Gast)


Lesenswert?

Um mal Johann zu zitieren:
Johann L. schrieb:
> Und wie wär's mit -mmcu=?

Scheint bei Deinen Linkeraufruf immer noch zu fehlen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

guest schrieb:
> Um mal Johann zu zitieren:
> Johann L. schrieb:
>> Und wie wär's mit -mmcu=?
>
> Scheint bei Deinen Linkeraufruf immer noch zu fehlen.

Damit erklärt sich auch wrum die ISR entsorgt wird:

Kein -mmcu= ==> es wird kein Startup-Code gelinkt ==> .vectors ist leer 
==> __vector_X wird nicht referenziert ==> __vector_X wird entsorgt.

Mit section(".vectors") kommt die ISR in eine KEEP-Section und das 
Problem schein behoben.  Dass so ein Code funktioniert würd ich stark 
bezweifeln.

von Hans W. (Firma: Wilhelm.Consulting) (hans-)


Lesenswert?

Klingt logisch.

Aber es funktioniert offensichtlich mit -flto (und ohne optimizer auch).


Mit -mmcu beim linking kommt folgendes:
1
21:56:22 **** Incremental Build of configuration Debug for project BeeStalkerMk1Firmware ****
2
make all 
3
Building file: ../main.c
4
Invoking: Cross GCC Compiler
5
avr-gcc -std=gnu11 -Os -Wall -Wextra -Wconversion -mmcu=atmega328p -ffunction-sections -fdata-sections -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.c"
6
Finished building: ../main.c
7
 
8
Building target: BeeStalkerMk1Firmware
9
Invoking: Cross GCC Linker
10
avr-gcc -mmcu=atmega328p -Xlinker -Map=output.map -Xlinker --gc-sections -Xlinker --strip-debug -o "BeeStalkerMk1Firmware"  ./main.o   
11
./main.o: In function `__vector_22':
12
(.text+0x8c): multiple definition of `__bad_interrupt'
13
makefile:29: recipe for target 'BeeStalkerMk1Firmware' failed
14
/usr/lib/gcc/avr/5.3.0/../../../../avr/lib/avr5/crtatmega328p.o:(.text+0x0): first defined here
15
./main.o: In function `__vectors':
16
(.text+0x0): multiple definition of `__vectors'
17
/usr/lib/gcc/avr/5.3.0/../../../../avr/lib/avr5/crtatmega328p.o:(.vectors+0x0): first defined here
18
collect2: error: ld returned 1 exit status
19
make: *** [BeeStalkerMk1Firmware] Error 1
20
21
21:56:22 Build Finished (took 116ms)

Irgendwas ist faul.

zugegebenermaßen vertraue ich meinem build-system gerade nicht... zuviel 
selbst dazucompiliert... wird zeit für slackware 14.2 ...

73

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Sachma was hast du da für eine komische Quelle?  Nimm erst mal das 
.vectors wieder raus du dass ISRs nach .text kommen.  Oder hast du noch 
mehr an Headern gepimpt?

Wieso definiert du __vectors?

: Bearbeitet durch User
von Hans W. (Firma: Wilhelm.Consulting) (hans-)


Lesenswert?

das ist eigentlich alles vanilla ... avr-libc SVN, binutils 2.25, 
gcc5.3!

nur die avr-size ist gepatcht.

ich glaube ich sollte mal in einer vm das auf einem sauberen system neu 
kompilieren... möglicherweise ist da was übergeblieben...

73

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Mit Quelle meine ich deine Quelle main.c.  Nach dem Fehler zu urteilen 
machst du da komische Sachen.

Als erstes kannst du den asm Code den gcc gegen den älterer Versionen 
vergleichen, ditto Disassembly vom gas.

: Bearbeitet durch User
von Hans W. (Firma: Wilhelm.Consulting) (hans-)


Lesenswert?

Nein mache ich nicht.

irgendwas ist an der toolchain faul... aber recompile muss warten.

einer meiner VPS muss umziehen...

73
1
/*
2
 * main.c
3
 *
4
 *  Created on: Jan 25, 2016
5
 *      Author: hans
6
 */
7
8
#include <avr/io.h>
9
#include <avr/interrupt.h>
10
11
12
#include <stdint.h>
13
#include <stdbool.h>
14
15
volatile uint8_t CurrentCommand;
16
17
ISR(SPI_STC_vect) {
18
  unsigned char Input;
19
  Input=SPDR;
20
21
  CurrentCommand=Input;
22
  SPDR=0x06; //ASCII ACK!
23
}
24
25
26
int main() {
27
28
  while(1) {
29
    switch (CurrentCommand) {
30
    case 0: //Idle
31
      break;
32
    case 1: //Enter Sleep
33
      break;
34
    case 2: //Read Channel 1
35
      break;
36
    case 3: //Read Channel 2
37
      break;
38
    default:
39
      break;
40
    }
41
42
43
    //sleep;
44
  }
45
  return 0;
46
}

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Und den Hack in interrupt.h hast du wieder rückgängig gemacht?

von hans (Gast)


Lesenswert?

Ja, alles wieder wie am Anfang...

Wie gesagt, interessanterweise gehts mit LTO aber nicht mit dem garbage 
collector....

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Was ich nicht verstehe ist das:

> avr-gcc -std=gnu11 -Os -Wall -Wextra -Wconversion -mmcu=atmega328p
> -ffunction-sections -fdata-sections -MMD -MP -MF"main.d" -MT"main.d"
> -o "main.o" "../main.c"

Du nennst das erzeugte Executable "main.o" und linkst es kann abermals 
genen den Startup-Code und nennst das dann "BeeStalkerMk1Firmware".

Endung .o wird ünlicherweise für Object-Files verwendet, d.h. Sachen, 
die mit -c compiliert und nicht gelinkt sind.

von Hans W. (Firma: Wilhelm.Consulting) (hans-)


Lesenswert?

Hmmm logische Erklärung... Wenn man dem Map-File glaubt funktioniert es 
auch.

Danke!

Wobei sich für mich die Frage stellt warum das (ohne -c) default bei 
eclipse (Keppler) ist...

73

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.