Forum: Compiler & IDEs Array anlegen und zugreifen geht nicht


von Martin S. (sirnails)


Lesenswert?

Guten Morgen,

vielleicht stehe ich ja nur auf der Leitung. Aber folgende Zeilen wollen 
nicht:


const uint16_t LED[9][10] PROGMEM = {{0, 0, 549, 1098, 1647, 2196, 2745, 
3294, 3843, 5856}, {0,0,0,0,0,0,0,0,0,0}, {0, 
5000,4451,3902,3353,2804,2255,1706,1157,810}, 
{0,1098,2196,3294,4392,5490,6588,7686,8784,13176}, 
{0,0,0,0,0,0,0,0,0,0}, 
{13333,8902,7804,6706,5608,4510,3412,2314,1216,157}, 
{732,1098,1647,2196,2745,3294,3843,4392,4941,0}, {0,0,0,0,0,0,0,0,0,0}, 
{5935,3902,3353,2804,2255,1706,1157,608,59,0}};

(Entschuldigung für die miese Formatierung)


Wenn ich aufrufe(n will):


uint16_t test;
test = LED[0][0];



Und einen Breakpoint auf die Zeile test = ... lege, dann sagt die IDE, 
dass dieser Punkt nie erreicht wird. Scheinbar optimiert der Compiler 
die kompletten Codezeilen weg.

Weiß jemand, warum das so ist?

von Karl H. (kbuchegg)


Lesenswert?

Martin Schwaikert schrieb:

> (Entschuldigung für die miese Formatierung)

dann machs besser


> uint16_t test;
> test = LED[0][0];
>
>
>
> Und einen Breakpoint auf die Zeile test = ... lege, dann sagt die IDE,
> dass dieser Punkt nie erreicht wird. Scheinbar optimiert der Compiler
> die kompletten Codezeilen weg.
>
> Weiß jemand, warum das so ist?

weil die Variable test nirgends verwendet wird?

(Dir ist auch klar, dass du so nicht an den Wert im Array rankommst? Da 
das PROGMEM ist, musst du mit den entsprechenden pgm_read_.... 
Funktionen darauf zugreifen um an die Werte zu kommen).

von Martin S. (sirnails)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Martin Schwaikert schrieb:
>
>> (Entschuldigung für die miese Formatierung)
>
> dann machs besser

Oh, ich habe die Tags total übersehen. Tut mir leid.

>> uint16_t test;
>> test = LED[0][0];
>>
>>
>>
>> Und einen Breakpoint auf die Zeile test = ... lege, dann sagt die IDE,
>> dass dieser Punkt nie erreicht wird. Scheinbar optimiert der Compiler
>> die kompletten Codezeilen weg.
>>
>> Weiß jemand, warum das so ist?
>
> weil die Variable test nirgends verwendet wird?

Dann reicht die Zuweisung nicht aus, um dem Compiler eine Verwendung zu 
signalisieren?

> (Dir ist auch klar, dass du so nicht an den Wert im Array rankommst? Da
> das PROGMEM ist, musst du mit den entsprechenden pgm_read_....
> Funktionen darauf zugreifen um an die Werte zu kommen).

Nein, das war mir nicht klar. Muss es überhaupt über PROGMEM ablaufen?

von Karl H. (kbuchegg)


Lesenswert?

Martin Schwaikert schrieb:

>> weil die Variable test nirgends verwendet wird?
>
> Dann reicht die Zuweisung nicht aus, um dem Compiler eine Verwendung zu
> signalisieren?

Überleg mal.
Würde sich am Verhalten deines Programms (also jetzt nicht im Debugger, 
sondern das was du zb in Ausgaben oder an den Port Pins siehst) 
irgendetwas ändern, wenn diese Zuweisung nicht im Programm ist?

Wenn deine Antwort 'nein, da würde sich nichts ändern; ob die Variable 
da ist oder nicht, spielt so gesehen keine Rolle' lautet, dann kann der 
Compiler das wegoptimieren.

> Nein, das war mir nicht klar. Muss es überhaupt über PROGMEM ablaufen?

Das musst du wissen, ob du die so viele Werte hast, dass du sie aus dem 
SRAM weghaben und im Flash haben willst.

von Martin S. (sirnails)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Martin Schwaikert schrieb:
>
>>> weil die Variable test nirgends verwendet wird?
>>
>> Dann reicht die Zuweisung nicht aus, um dem Compiler eine Verwendung zu
>> signalisieren?
>
> Überleg mal.
> Würde sich am Verhalten deines Programms (also jetzt nicht im Debugger,
> sondern das was du zb in Ausgaben oder an den Port Pins siehst)
> irgendetwas ändern, wenn diese Zuweisung nicht im Programm ist?
>
> Wenn deine Antwort 'nein, da würde sich nichts ändern; ob die Variable
> da ist oder nicht, spielt so gesehen keine Rolle' lautet, dann kann der
> Compiler das wegoptimieren.

Gut, das sehe ich ein. Ich dachte allerdings, im Debugmodus optimiert 
der Compiler nicht. So kann man sich täuschen.


>> Nein, das war mir nicht klar. Muss es überhaupt über PROGMEM ablaufen?
>
> Das musst du wissen, ob du die so viele Werte hast, dass du sie aus dem
> SRAM weghaben und im Flash haben willst.

Ach jetzt. Ok. Dass geht mir ein.

von Martin S. (sirnails)


Lesenswert?

Gut. Ich habe das PROGMEM rausgeschmissen. Aber auch mit folgenden 
Zeilen wird wegoptimiert:
1
uint16_t test;
2
test = LED[1][1];
3
PORTB = test;

Jetzt wird die Variable doch eigentlich verwendet?

von Peter II (Gast)


Lesenswert?

Martin Schwaikert schrieb:
> Aber auch mit folgenden
> Zeilen wird wegoptimiert:

woher weist du das? Wird der code überhaupt aufgerufen? Zeig bitte eine 
completten quellcode.

von Martin S. (sirnails)


Lesenswert?

Ich habe nen Haltepunkt auf die Codezeile mit der Portzuweisung und eine 
Überwachung auf die test-Variable. Die IDE sagt dazu nur: "Variable: 
test, Value: Optimized away".


LEDRGB.h
1
#ifndef LEDRGB_H_
2
#define LEDRGB_H_
3
4
  const uint16_t LED[10][9] =  {{0, 0, 0, 0, 0, 13333, 732, 0, 5935}, 
5
    {0, 0, 5000, 1098, 0, 8902, 1098, 0, 3902}, 
6
    {549, 0, 4451, 2196, 0, 7804, 1647, 0, 3353}, 
7
    {1098, 0, 3902, 3294, 0, 6706, 2196, 0, 2804}, 
8
    {1647, 0, 3353, 4392, 0, 5608, 2745, 0, 2255}, 
9
    {2196, 0, 2804, 5490, 0, 4510, 3294, 0, 1706}, 
10
    {2745, 0, 2255, 6588, 0, 3412, 3843, 0, 1157}, 
11
    {3294, 0, 1706, 7686, 0, 2314, 4392, 0, 608}, 
12
    {3843, 0, 1157, 8784, 0, 1216, 4941, 0, 59}, 
13
    {5856, 0, 810, 13176, 0, 157, 0, 0, 0}};
14
15
16
#endif /* LEDRGB_H_ */


main.cpp
1
  while(1) {  
2
    
3
    if (ADC_TIMER == 0xFFFF)
4
    {
5
      ADC_TIMER = 0x0000;
6
      ADC_Value = ADC_Read(0);
7
          
8
      // LM35DZ gives 10mV/K
9
      // => 10°C = 100mV, 28°C = 280mV
10
      // 2^10 = 1024 values with 2,56V internal reference 
11
      // => 2,5mV steps
12
      // => 10°C = 100mV = 100mV/2,5mV = 40
13
      // => 28°C = 280mV = 280mV/2,5mV = 112
14
      // => Expected Values = [40;112] with 4 steps/°C = 0,25°C resolution
15
      
16
      if ((ADC_Value >= 40) || (ADC_Value <= 112))
17
      {
18
        TEMPERATURE = ADC_Value * 0.25;
19
      } else {
20
        if (ADC_Value < 40) TEMPERATURE = 10;
21
        if (ADC_Value > 112) TEMPERATURE = 28; 
22
      }        
23
      
24
      // Calc, which LEDs has to illuminate
25
      CALC_LEDS();
26
      
27
      
28
      
29
      
30
    } else {
31
      ADC_TIMER++;    
32
      
33
      uint16_t test;
34
      test = LED[1][1];
35
      PORTB = test;      
36
      _delay_us(100);
37
    
38
    }
39
40
  }    
41
   return 0;                
42
}

von Peter II (Gast)


Lesenswert?

naja test wird ja nicht gebraucht, die Frage ist ob in PORTB das richtig 
danach drin steht. Da es ja eine konstante ist macht der optimieren 
vermutlich

PORTB = 0;

von Martin S. (sirnails)


Lesenswert?

Hmm... das kann sein. Irgendwie frustrierend, wenn der Compiler soviel 
mitdenkt. Mal schnell eben kurz ne Zeile Code zum Testen schreiben, um 
debuggen zu können, ist also heute scheinbar nicht mehr möglich.

von Martin S. (sirnails)


Lesenswert?

Ok Peter, Du hast recht. Ohne Optimierungen läuft das so, wie ich das 
gerne hätte. Scheinbar streicht er das alles recht radikal zusammen.

Vielen Dank.

Grüße M. Schwaikert.

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.