gcc 5 mit --gc-sections killt interrupt vectoren

(Firma: Wilhelm.Consulting) #4441213
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
Persönliche Seite #4441268
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.
(Firma: Wilhelm.Consulting) #4441335
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
(Firma: Wilhelm.Consulting) #4441356
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
Persönliche Seite #4442701
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.
(Firma: Wilhelm.Consulting) #4442769
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
(Firma: Wilhelm.Consulting) #4448049
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
}
Persönliche Seite #4448723
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren