Forum: Compiler & IDEs Optimieren von ungenutzter Variable verhindern


von Hexfile (Gast)


Lesenswert?

Hallo

Ich versuche grade die Firmware von TV-B-Gone mit dem AVRGCC zu 
kompilieren, dabei gibt es viele Arrays der Form
1
const uint16_t code_na003Times[] PROGMEM =
2
{
3
  26, 185,
4
  27, 80,
5
  27, 185,
6
  27, 4549,
7
};

Das Problem dabei ist jetzt aber, dass dieses Array nie direkt mit Namen 
angesprochen wird, sondern nur indirekt über ein durch den Flash 
laufenden Zeiger. Der Kompiler erkennt dies und optimiert die Variable 
raus. Wie kann ich dieses Verhalten am besten unterbinden, ohne jedoch 
auf Optimierungen zu verzichten?

MfG Hexfile

von Stefan++ (Gast)


Lesenswert?

Hallo,

woran erkennst du dass der Compiler die "Variable weg optimiert hat" ???

von Hexfile (Gast)


Lesenswert?

Hallo Stefan

Das erkenne ich daran, dass der Kompiler nur 744 Bytes für den Flash 
vorsieht. Schwer vorstellbar wenn die Arrays mehrere KB groß sind und 
grade so in den AVR (ATTiny85) passen. Das ganze Projekt besteht aus 
einem Hauptprogramm was die Codes aus dem Flash läd (dieses Programm ist 
wohl 744 Byte groß) und mehreren KB von LUTs die aus dem Flash gelesen 
werden. Da alle hintereinander stehen werden sie der Reihe nach aus dem 
Flash gelesen, ohne sie direkt mit Namen anzusprechen, was bei mehreren 
100 Namen auch etwas viel wäre. Im Code wird ein Zeiger auf den ersten 
Eintrag definiert welcher dann durch die Arrays durchläuft, folglich 
wird auch nur der erste Eintrag referenziert, der Rest wird vom Kompiler 
als "unused" erkannt und landet dementsprechend nicht im fertigen hex.

Ich möchte auch nicht umbedingt alle Symbole einzeln per dummy-verweiß 
(welcher ja auch Platz kostet) einbinden, das ist bei über 100 einfach 
zu Fehleranfällig und zu unflexibel.

von 666 (Gast)


Lesenswert?

static deklarieren

von Hexfile (Gast)


Lesenswert?

Bringt auch nix. Wird auch rausoptimiert

von Versuchsballon (Gast)


Lesenswert?

Ein dummy-read auf das erste Element am Programmanfang meldet dem 
Compiler das Vorhandensein dieser Datenstruktur und bindet sie dann im 
hexfile mit ein. Andernfalls müsstest du diese Tabellen händisch an das 
Ende des erzeugten hexfiles selbst anfügen.

von Falk B. (falk)


Lesenswert?

@  Hexfile (Gast)

>Das Problem dabei ist jetzt aber, dass dieses Array nie direkt mit Namen
>angesprochen wird, sondern nur indirekt über ein durch den Flash
>laufenden Zeiger.

Na und der muss ja irgendwann mal initialisiert werden. Dann kann der 
Compiler ihn auch nicht wegoptimieren. Lass die sinnlosen Hackertricks 
stecken und programmiere normales C, dann braucht es auch keine 
zusätzlichen Hackertricks, um den Compiler auszutricksen.

von 666 (Gast)


Lesenswert?

Hexfile schrieb:
> Bringt auch nix. Wird auch rausoptimiert

Sorry, meinte volatile. War schon spät.

von Hexfile (Gast)


Lesenswert?

Der Code ist nicht von mir, sondern kommt aus dem Projekt TV-B-Gone. 
Irgentwie werden diese netten Leute das Ding kompiliert bekommen haben, 
es muss also gehen. Das erste Array wird wohl auch im Flash stehen (kann 
das nur anhand der Größe überprüfen), aber wie gesagt, in dem Programm 
befinden sich hunderte von Arrays, welche alle indirekt angesprochen 
werden.

Siehe:
http://code.google.com/p/tv-b-gone/source/browse/trunk/codes/codes.h

Auch volatile hat nichts gebracht, was auch zu erwarten war. Selbst wenn 
die Variable veränderlich ist, was nie gelesen wird wird entfernt.

von jack (Gast)


Lesenswert?

Falk Brunner schrieb:
> Na und der muss ja irgendwann mal initialisiert werden. Dann kann der
> Compiler ihn auch nicht wegoptimieren. Lass die sinnlosen Hackertricks
> stecken und programmiere normales C, dann braucht es auch keine
> zusätzlichen Hackertricks, um den Compiler auszutricksen.

1) so wie ich das verstehe handelt es sich um mehrere hintereinander 
liegende Arrays. D.h. durch die Initialisierung bleibt genau das erste 
Array erhalten, die nachfolgenden werden ja nicht angesprochen.

2) das ist nicht auf seinem Mist gewachsen sondern der TE versucht ein 
relativ bekanntes Projekt zu kompilieren.

von 666 (Gast)


Lesenswert?

Sorry, aber volatile MUSS die Variable erhalten. Das ist die Definition 
von volatile!

Wahrscheinlich liegt das Problem woanders.

von Peter (Gast)


Lesenswert?

>Sorry, aber volatile MUSS die Variable erhalten. Das ist die Definition
>von volatile!
Ich denke nicht, wenn sie gar nie verwendet wird.

>welche alle indirekt angesprochen werden.
Zeige ein Beispiel, wie sie angesprochen werden. Irgend woher musst Du 
ja die Adresse wissen, bzw. einen Pointer auf die Variablen definieren. 
Wenn Du dies den Compiler über den Array-Namen machen lässt, sollte es 
eigentlich gehen!

von 666 (Gast)


Lesenswert?

Peter schrieb:
> Ich denke nicht, wenn sie gar nie verwendet wird.

Doch, genau dazu ist doch volatile da verdammt nochmal!

wenn ich folgenden Code compiliere
1
int main(void)
2
{
3
        volatile int foo = 0;
4
5
}

dann kommt das raus

gcc -c -g -Wa,-a,-ad -O3 volatile.c | less
1
ARM GAS  /tmp/cc0hIqS7.s                        page 1
2
3
4
   1                            .arch armv4t
5
   2                            .fpu softvfp
6
   3                            .eabi_attribute 20, 1
7
   4                            .eabi_attribute 21, 1
8
   5                            .eabi_attribute 23, 3
9
   6                            .eabi_attribute 24, 1
10
   7                            .eabi_attribute 25, 1
11
   8                            .eabi_attribute 26, 2
12
   9                            .eabi_attribute 30, 2
13
  10                            .eabi_attribute 18, 4
14
  11                            .file   "volatile.c"
15
  12                            .text
16
  13                    .Ltext0:
17
  14                            .cfi_sections   .debug_frame
18
  15                            .section        .text.startup,"ax",%progbits
19
  16                            .align  2
20
  17                            .global main
21
  19                    main:
22
  20                    .LFB0:
23
ARM GAS  /tmp/cc0hIqS7.s                        page 1
24
25
26
   1                            .arch armv4t
27
   2                            .fpu softvfp
28
   3                            .eabi_attribute 20, 1
29
   4                            .eabi_attribute 21, 1
30
   5                            .eabi_attribute 23, 3
31
   6                            .eabi_attribute 24, 1
32
   7                            .eabi_attribute 25, 1
33
   8                            .eabi_attribute 26, 2
34
ARM GAS  /tmp/cc0hIqS7.s                        page 1
35
36
37
   1                            .arch armv4t
38
   2                            .fpu softvfp
39
   3                            .eabi_attribute 20, 1
40
   4                            .eabi_attribute 21, 1
41
   5                            .eabi_attribute 23, 3
42
   6                            .eabi_attribute 24, 1
43
   7                            .eabi_attribute 25, 1
44
   8                            .eabi_attribute 26, 2
45
   9                            .eabi_attribute 30, 2
46
  10                            .eabi_attribute 18, 4
47
  11                            .file   "volatile.c"
48
  12                            .text
49
  13                    .Ltext0:
50
  14                            .cfi_sections   .debug_frame
51
  15                            .section        .text.startup,"ax",%progbits
52
  16                            .align  2
53
  17                            .global main
54
  19                    main:
55
  20                    .LFB0:
56
  21                            .file 1 "volatile.c"
57
   1:volatile.c    **** int main(void)
58
   2:volatile.c    **** {
59
  22                            .loc 1 2 0
60
  23                            .cfi_startproc
61
  24                            @ Function supports interworking.
62
  25                            @ args = 0, pretend = 0, frame = 8
63
  26                            @ frame_needed = 0, uses_anonymous_args = 0
64
  27                            @ link register save eliminated.
65
  28 0000 08D04DE2              sub     sp, sp, #8
66
  29                    .LCFI0:
67
  30                            .cfi_def_cfa_offset 8
68
   3:volatile.c    ****         volatile int foo = 0;
69
  31                            .loc 1 3 0
70
  32 0004 0030A0E3              mov     r3, #0
71
  33 0008 04308DE5              str     r3, [sp, #4]
72
  34                    .LVL0:
73
   4:volatile.c    ****
74
   5:volatile.c    **** }
75
  35                            .loc 1 5 0
76
  36 000c 08D08DE2              add     sp, sp, #8
77
  37 0010 1EFF2FE1              bx      lr
78
  38                            .cfi_endproc
79
  39                    .LFE0:
80
  41                            .text
81
  42                    .Letext0:
82
^LARM GAS  /tmp/ccgJ3M2v.s                      page 2
83
84
85
DEFINED SYMBOLS
86
                            *ABS*:00000000 volatile.c
87
     /tmp/ccgJ3M2v.s:16     .text.startup:00000000 $a
88
     /tmp/ccgJ3M2v.s:19     .text.startup:00000000 main
89
                     .debug_frame:00000010 $d
90
91
NO UNDEFINED SYMBOLS

von Karl H. (kbuchegg)


Lesenswert?

666 schrieb:
> Peter schrieb:
>> Ich denke nicht, wenn sie gar nie verwendet wird.
>
> Doch, genau dazu ist doch volatile da verdammt nochmal!


Eigentlich nicht.

Der C Standard sagt über volatile
1
An object that has volatile-qualified type may be modified in ways
2
unknown to the implementation or have other unknown side effects.
3
Therefore any expression referring to such an object shall be evaluated
4
strictly according to the rules of the abstract machine, as described in
5
5.1.2.3. Furthermore, at every sequence point the value last stored in
6
the object shall agree with that prescribed by the abstract machine,
7
except as modified by the unknown factors mentioned previously.114)
8
What constitutes an access to an object that has volatile-qualified
9
type is implementation-defined.

Davon, dass volatile dafür sorgt, dass eine überhaupt nicht benutzte 
Variable erhalten bleibt, davon steht da nichts.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hexfile schrieb:
> Siehe:
> http://code.google.com/p/tv-b-gone/source/browse/trunk/codes/codes.h

Habe mir den Code gerade angeschaut. Sämtliche Arrays/Strukturen in 
codes.h werden in powerCodes[NUM_CODES] referenziert. In makebin.c sieht 
man, dass genau auf dieses Array vom Programm zugegriffen wird. Daher 
sehe ich überhaupt nicht, was da wegoptimiert werden sollte.

> Auch volatile hat nichts gebracht, was auch zu erwarten war. Selbst wenn
> die Variable veränderlich ist, was nie gelesen wird wird entfernt.

volatile ist hier NICHT das Mittel der Wahl, sondern Referenzierung. Und 
die ist gegeben. Auf powerCodes wird innerhalb main() in makebin.c 
zugegriffen. Da kann nichts wegoptimiert werden. Die Daten werden daher 
auch im Flash stehen.

Du bist da irgendwo auf dem Holzweg. Wie kommst Du auf 744 Bytes? 
Wahrscheinlich lässt Du Dich von der Ausgabe von avr-size in die Irre 
führen.

Gruß,

Frank

von Karl H. (kbuchegg)


Lesenswert?

> Das Problem dabei ist jetzt aber, dass dieses Array nie direkt mit
> Namen angesprochen wird, sondern nur indirekt über ein durch den
> Flash laufenden Zeiger.

Und genau das ist das, was mir Angst macht.
In irgendeiner Form MUSS jedes Array irgendwo referenziert sein, selbst 
wenn danach über Zeiger darauf zugegriffen wird.
Ansonsten kann man auch gleich einen Zeiger irgendwo im Flash aufsetzen 
und dann auf gut Glück einfach irgendwas aus dem Flash lesen.

Also, noch mal den Code studieren, wie der Erfinder sich das ganze 
gedacht haben könnte.

von Hexfile (Gast)


Lesenswert?

Du setzt die Variable ja auch auf null. Also greifst du auf sie zu, das 
ist keine Kunst. Im Projekt sieht es so aus:

(gekürzt)
1
// for every POWER code in our collection
2
for(i=0 ; i < j; i++)
3
{   
4
      // point to next POWER code, from the right database
5
      if (region == US) {
6
  code_ptr = (PGM_P)pgm_read_word(NApowerCodes+i);  
7
      } else {
8
  code_ptr = (PGM_P)pgm_read_word(EUpowerCodes+i);  
9
      }

NApowerCodes und EUpowerCodes zeigen dabei auf jeweils ein Array was wie 
folgt definiert ist:

(gekürzt)
1
const struct IrCode *NApowerCodes[] PROGMEM = {
2
#ifdef NA_CODES
3
  &code_na000Code,
4
  &code_na001Code,
5
         &code_na002Code,
6
  &code_na003Code,
7
  &code_na004Code,
8
  &code_na005Code,
9
  &code_na006Code,
10
  &code_na007Code,
11
  &code_na008Code,
12
  &code_na009Code,
13
  &code_na010Code,
14
  &code_na011Code,

Es sind die Startaddressen von allen Arrays eingetragen. Trotzdem 
scheint das nicht auszureichen den Kompiler dazu zu bewegen alle in das 
Hexfile zu schreiben. Das ganze Projekt soll ca 8Kb groß sein. Das 
Hexfile ist grade mal 3Kb groß. Da stimmt einfach was nicht. Die 
Tabellen sind nicht drin...

von Peter II (Gast)


Lesenswert?

Hexfile schrieb:
> Die
> Tabellen sind nicht drin...

hast du denn auch das define  NA_CODES gesetzt?

von Hexfile (Gast)


Lesenswert?

Mal die Ausgabe des Kompilers
1
rm -rf main.o util.o WORLDcodes.o  TV-B-Gone.elf dep/* TV-B-Gone.hex TV-B-Gone.eep TV-B-Gone.lss TV-B-Gone.map
2
Build succeeded with 0 Warnings...
3
avr-gcc  -mmcu=attiny85 -Wall -gdwarf-2 -std=gnu99     -DF_CPU=10000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d  -c  ../main.c
4
../main.c: In function 'main':
5
../main.c:270: warning: passing argument 1 of 'putnum_uh' makes integer from pointer without a cast
6
avr-gcc  -mmcu=attiny85 -Wall -gdwarf-2 -std=gnu99     -DF_CPU=10000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT util.o -MF dep/util.o.d  -c  ../util.c
7
avr-gcc  -mmcu=attiny85 -Wall -gdwarf-2 -std=gnu99     -DF_CPU=10000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT WORLDcodes.o -MF dep/WORLDcodes.o.d  -c  ../WORLDcodes.c
8
avr-gcc -mmcu=attiny85 -Wl,-Map=TV-B-Gone.map main.o util.o WORLDcodes.o     -o TV-B-Gone.elf
9
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature  TV-B-Gone.elf TV-B-Gone.hex
10
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex TV-B-Gone.elf TV-B-Gone.eep || exit 0
11
avr-objdump -h -S TV-B-Gone.elf > TV-B-Gone.lss
12
13
AVR Memory Usage
14
----------------
15
Device: attiny85
16
17
Program:     744 bytes (9.1% Full)
18
(.text + .data + .bootloader)
19
20
Data:          6 bytes (1.2% Full)
21
(.data + .bss + .noinit)
22
23
24
Build succeeded with 1 Warnings...

Die 744 Byte sind auch genau die Anzahl der Nutzbytes die im *.hex 
stehen.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hast Du NA_CODES bzw. EU_CODES auch definiert? Sonst ist das Array, 
welches die Referenz auf die PROGMEM-Strukturen herstellt, ziemlich 
leer.

von 666 (Gast)


Lesenswert?

Hexfile schrieb:
> Du setzt die Variable ja auch auf null. Also greifst du auf sie zu, das
>
> ist keine Kunst. Im Projekt sieht es so aus:

Äh, ja und? Deine Variable wird ja auch initialisiert. Ich seh da 
nämlich ein fettes Gleichheitszeichen nach dem PROGMEM.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hexfile schrieb:
> Mal die Ausgabe des Kompilers
>
> [code]
> ...
> avr-gcc  -mmcu=attiny85 -Wall -gdwarf-2 -std=gnu99
> -DF_CPU=10000000UL -Os -funsigned-char -funsigned-bitfields
> -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d  -c
> ../main.c
> ../main.c: In function 'main':
> ../main.c:270: warning: passing argument 1 of 'putnum_uh' makes integer
> from pointer without a cast

Zeig mal Deinen Code. Unter Deinem angegebenen Link

  http://code.google.com/p/tv-b-gone/source/browse/trunk/codes/

kann ich kein main.c entdecken. Auch kein ../WORLDcodes.c. Greifst Du 
überhaupt irgendwo auf powerCodes[] zu? Da sind alle Referenzen auf die 
in codes.h definierten Arrays/Strukturen drin.

von Karl H. (kbuchegg)


Lesenswert?

Frank M. schrieb:
> Hexfile schrieb:
>> Mal die Ausgabe des Kompilers
>>
>> [code]
>> ...
>> avr-gcc  -mmcu=attiny85 -Wall -gdwarf-2 -std=gnu99
>> -DF_CPU=10000000UL -Os -funsigned-char -funsigned-bitfields
>> -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d  -c
>> ../main.c
>> ../main.c: In function 'main':
>> ../main.c:270: warning: passing argument 1 of 'putnum_uh' makes integer
>> from pointer without a cast
>
> Zeig mal Deinen Code. Unter Deinem angegebenen Link
>
>   http://code.google.com/p/tv-b-gone/source/browse/trunk/codes/

so wie ich das sehe, handelt es sich bei dem dortigen Programm um ein 
Hilfsprogramm, welches die Codetabellen für eine Assembler-Lösung 
erzeugt.

Ich schätze mal, er hat die #define übersehen, die im dortigen makebin.c 
für dem #include "codes.h" eine gewisse Steuerungsmöglichkeit bieten, 
welche Codes inkludiert werden sollen.

Im Original ....
1
#ifndef NA_CODES        //select default code-set
2
  #ifndef EU_CODES
3
    //#define NA_CODES
4
    #define EU_CODES
5
  #endif
6
#endif
7
8
...
9
10
#include "codes.h"      //the original code file (remove #includes inside this file)
11
//-------------------------------------------------------------------------------------------------

... wird auf jeden Fall EU_CODES definiert, auch wenn sonst nichts da 
ist.

von Leo C. (rapid)


Lesenswert?

Hexfile schrieb:
> Program:     744 bytes (9.1% Full)
> (.text + .data + .bootloader)

Welche Version hast Du denn?
Nimmst Du auch das darin enthaltene Makefile?

Ich habe http://ladyada.net/media/tvbgone/firmwarev12.zip gesaugt und 
make liefert folgendes:
1
leo@cb:~/src/avr/TV-B-Gone/firmware_v1.2$ make
2
set -e; avr-gcc -MM -mmcu=attiny85 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -DF_CPU=8000000 -Wa,-adhlns=util.lst  -std=gnu99 -DEU_CODES -DNA_CODES util.c \
3
  | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > util.d; \
4
  [ -s util.d ] || rm -f util.d
5
set -e; avr-gcc -MM -mmcu=attiny85 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -DF_CPU=8000000 -Wa,-adhlns=WORLDcodes.lst  -std=gnu99 -DEU_CODES -DNA_CODES WORLDcodes.c \
6
  | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > WORLDcodes.d; \
7
  [ -s WORLDcodes.d ] || rm -f WORLDcodes.d
8
set -e; avr-gcc -MM -mmcu=attiny85 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -DF_CPU=8000000 -Wa,-adhlns=main.lst  -std=gnu99 -DEU_CODES -DNA_CODES main.c \
9
  | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > main.d; \
10
  [ -s main.d ] || rm -f main.d
11
12
-------- begin --------
13
avr-gcc (GCC) 4.7.0
14
Copyright (C) 2012 Free Software Foundation, Inc.
15
This is free software; see the source for copying conditions.  There is NO
16
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18
19
Compiling: main.c
20
avr-gcc -c -mmcu=attiny85 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -DF_CPU=8000000 -Wa,-adhlns=main.lst  -std=gnu99 -DEU_CODES -DNA_CODES main.c -o main.o
21
main.c: In function ‘main’:
22
main.c:271:7: warning: passing argument 1 of ‘putnum_uh’ makes integer from pointer without a cast [enabled by default]
23
In file included from main.c:22:0:
24
util.h:11:6: note: expected ‘uint16_t’ but argument is of type ‘const char *’
25
26
Compiling: WORLDcodes.c
27
avr-gcc -c -mmcu=attiny85 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -DF_CPU=8000000 -Wa,-adhlns=WORLDcodes.lst  -std=gnu99 -DEU_CODES -DNA_CODES WORLDcodes.c -o WORLDcodes.o
28
29
Compiling: util.c
30
avr-gcc -c -mmcu=attiny85 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -DF_CPU=8000000 -Wa,-adhlns=util.lst  -std=gnu99 -DEU_CODES -DNA_CODES util.c -o util.o
31
32
Linking: tvbgone.elf
33
avr-gcc -mmcu=attiny85 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -DF_CPU=8000000 -Wa,-adhlns=main.o  -std=gnu99 -DEU_CODES -DNA_CODES main.o WORLDcodes.o util.o   --output tvbgone.elf -Wl,-Map=tvbgone.map,--cref -lm
34
35
Creating load file for Flash: tvbgone.hex
36
avr-objcopy -O ihex  -R .eeprom tvbgone.elf tvbgone.hex
37
38
Creating load file for EEPROM: tvbgone.eep
39
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
40
  --change-section-lma .eeprom=0 -O ihex  tvbgone.elf tvbgone.eep
41
avr-objcopy: --change-section-lma .eeprom=0x0000000000000000 never used
42
43
Creating Extended Listing: tvbgone.lss
44
avr-objdump -h -S tvbgone.elf > tvbgone.lss
45
46
Creating Symbol Table: tvbgone.sym
47
avr-nm -n tvbgone.elf > tvbgone.sym
48
49
Size after:
50
tvbgone.elf  :
51
section     size      addr
52
.text       7946         0
53
.data          2   8388704
54
.bss           4   8388706
55
.stab      10164         0
56
.stabstr   11674         0
57
.comment      17         0
58
Total      29807
59
60
61
62
Errors: none
63
-------- end --------

Wg. gcc 4.7 allerdings mit folgender Änderung:
1
extern const PGM_P * const NApowerCodes[] PROGMEM;
2
extern const PGM_P * const EUpowerCodes[] PROGMEM;
In WORLDcodes.c entsprechend.

von Karl H. (kbuchegg)


Lesenswert?

Hier
1
avr-gcc -c -mmcu=attiny85 -I. -g -Os -funsigned-char -funsigned-bitfields
2
  -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -DF_CPU=8000000
3
  -Wa,-adhlns=util.lst  -std=gnu99 -DEU_CODES -DNA_CODES ....
4
                                   ********** **********
5
                                   ********** **********

liegt der entscheidende Unterschied zum Log des Thread Openers.
Ohne diese #defines - keine Codes

von Karl H. (kbuchegg)


Lesenswert?

666 schrieb:
> Hexfile schrieb:
>> Du setzt die Variable ja auch auf null. Also greifst du auf sie zu, das
>>
>> ist keine Kunst. Im Projekt sieht es so aus:
>
> Äh, ja und? Deine Variable wird ja auch initialisiert. Ich seh da
> nämlich ein fettes Gleichheitszeichen nach dem PROGMEM.

Deine Variable ist lokal, seine global.
D.h. da hat auch noch der Linker ein Wörtchen mitzureden.
Und der schmeisst Unreferenziertes üblicherweise raus, was im Normalfall 
auch gut ist. Denn du willst nicht alle Funktionen und Variablen der 
Runtime-Library immer mitgelinkt haben, nur weil sie im Linkerinput 
auftauchen aber nirgends benutzt werden.

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


Lesenswert?

Hexfile schrieb:
> Da alle hintereinander stehen

Wer garantiert das denn?

Das ist ein mächtiges va-banque-Spiel.

Wenn man das sauber machen will, packt man jeden Eintrag in eine
eigene section und erklärt den Eintrag als "benutzt":
1
... __attribute__((section("flashdata"), used))

Dazu dann ein Linkerscript, das alle "flashdata"-Abschnitte
zusammenfügt und davor und danach noch ein globales Symbol anlegt.
Auf diese beiden globalen Symbole bezieht sich dann die Schleife,
die da durch alle Einträge durchgeht.

(So ähnlich erfolgt die Laufzeitinitialisierung von Variablen im
data-Segment, die ja mit Werten aus dem Flash vorbelegt werden
müssen.)

Klingt umständlich, aber alles andere ist einfach Pfusch.

von Stefan++ (Gast)


Lesenswert?

Hallo,

ich hatte gefragt

Stefan++ schrieb:
> woran erkennst du dass der Compiler die "Variable weg optimiert hat" ???

und hätte als Antwort erwartet: "wenn ich die ... Optimierung einschalte 
ist das Array da und wenn ich die ... ein/ausschalte, dann nicht !!!

Aufgrund der Länge des erzeugten HEX-Files zu sagen "hat der Compiler 
wegoptimiert" ist ganz einfach suboptimal
weil es da viele andere Sachen gibt die da Einfluss haben wie z.B. die 
genannten "#defines ..." mit "#ifdef" die den Compiler "steuern"

Ansonsten ist im gcc folgende Option zuständig

>  -fkeep-static-consts
>   Emit variables declared static const when optimization isn't turned on,
>   even if the variables aren't referenced.
>
>   GCC enables this option by default. If you want to force the compiler
>   to check if a variable is referenced, regardless of whether or not
>   optimization is turned on, use the -fno-keep-static-consts option.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Stefan++ schrieb:
>>  -fkeep-static-consts
>>   Emit variables declared static const when optimization isn't turned on,
>>   even if the variables aren't referenced.

So ein (schlechter) Hack ist hier überhaupt nicht notwendig.

Der TO geht irrigerweise davon aus, dass die unzähligen globalen Arrays 
im FLASH einfach über einen (wie auch immer gearteten) Zeiger 
angesprochen werden, der "irgendwie" über den Flash-Speicher "wandert" - 
siehe Ausgangsposting.

Das was er im Ausgangsposting erzählt, ist schlichtweg Unsinn. Er hat 
einfach übersehen, dass sämtliche Arrays/Strukturen (z.B. sein zitiertes 
code_na003Times) in powerCodes referenziert sind. Wenn er aber 
powerCodes nicht nutzt, wirft der Compiler alles raus.

von Karl H. (kbuchegg)


Lesenswert?

Frank M. schrieb:

> Das was er im Ausgangsposting erzählt, ist schlichtweg Unsinn. Er hat
> einfach übersehen, dass sämtliche Arrays/Strukturen (z.B. sein zitiertes
> code_na003Times) in powerCodes referenziert sind. Wenn er aber
> powerCodes nicht nutzt, wirft der Compiler alles raus.

Entweder das oder er hat schlicht die #ifdef übersehen oder ihnen keine 
Beachtung geschenkt. Ich tendiere zu letzterer Erklärung.

Kurz und gut: Der Compiler hat genau das gemacht, was zu erwarten ist. 
Der Fehler sitzt vor dem Monitor und nicht im Compiler. Macht man es im 
Source Code richtig, gibt es auch das Problem nicht.

von Hexfile (Gast)


Lesenswert?

Stimmt, ihr habt recht, der Fehler war (wie so oft) vor dem Monitor.
Tatsächlich haben die beiden defines gefehlt. Beim durchgucken des 
Headers ist mir ein ähnliches define aufgefallen, daher dachte ich, das 
macht das schon... fixed... Danke an euch alle, der Fehler hat mich 
lange Zeit gekostet weil ich an alles gedacht hab nur nicht an diese 
einfache Lösung...

MfG Hexfile

von Rudi (Gast)


Lesenswert?

In einer vernünftigen IDE, zB Eclipse, werden solche blöcke ausgegraut 
wenn das dazugehörige define fehlt.

Und jetzt schnell weg bevor die vim fraktion auftaucht :)

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.