Forum: Mikrocontroller und Digitale Elektronik Variable wegoptimiert? :STM32 + Keil uVision


von Jan K. (jan_k)


Lesenswert?

Hallo Leute,

ich sehe vermutlich den Wald vor lauter Bäumen nicht, aber folgendes 
Problem werde ich nicht los:

Ich habe eine Funktion, in der ein paar Puffer gefüllt werden sollen. 
Dazu wird geprüft, ob diese leer sind. Wenn ich die Statusvariablen 
innerhalb der Funktion deklariere, kann ich sie mir hinterher beim 
Debuggen nicht angucken. Es scheint sie existieren nicht.
1
void fillLog() 
2
{
3
4
  uint8_t buffer1empty;
5
  uint8_t buffer2empty;
6
  uint8_t buffer3empty;
7
8
  buffer1empty = BUFFER_isEmpty(&positionCountBuffer,2);
9
  buffer2empty = BUFFER_isEmpty(&positionAbsBufferHigh,1);
10
  buffer3empty = BUFFER_isEmpty(&positionAbsBufferLow,1);
11
12
  while(1)
13
  {        
14
    dataCount = BUFFER_read(&positionCountBuffer,2);
15
    dataAbsH = BUFFER_read(&positionAbsBufferHigh,1);
16
    dataAbsL = BUFFER_read(&positionAbsBufferLow,1); 
17
... 
18
  }
19
}
In dem while steht eigentlich was anderes, aber zu Testzwecken steht 
halt nur ne 1 drin.

Wenn ich die Variablen so deklariere, bleiben die die empty Flags 
unsichtbar. Ich kann sie nicht zu watch1/watch2 hinzufügen.
volatile bringt keinerlei Änderung.
Wenn ich die Flags aber global ohne volatile definiere, funktioniert es. 
Es wurde sonst nichts geändert.

Woran könnte sowas liegen?

von Karl H. (kbuchegg)


Lesenswert?

Jan K. schrieb:

> Woran könnte sowas liegen?

An der Optimierung.
Mach irgendwas mit den Variablen. zb gib sie am Ende der Funktion an 
eine andere Funktion weiter, so dass sie der Compiler anlegen MUSS. Am 
besten gibst du ihre Adressen an eine Dummy Funktion weiter. Dann bleibt 
dem Compiler nichts mehr anderes übrig als tatsächlich Platz dafür zu 
schaffen.

von Jan K. (jan_k)


Lesenswert?

Aber sollte 'volatile' nicht genau dem entgegenwirken?

Wenn ich mit -O0 compiliere tritt auch das selbe auf. Schaltet -O0 nicht 
die Optimierung komplett aus?

Und wenn ich die variablen in der while Schleife verwende, wofür die 
eigentlich gedacht waren tritt ebenfalls das selbe Problem auf.

Werde, wenn ich morgen wieder auf der Arbeit bin, die Variable nochmal 
in eine Dummyfunktion packen und gucken was passiert.

Danke + schöne Grüße!

von Karl H. (kbuchegg)


Lesenswert?

Jan K. schrieb:
> Aber sollte 'volatile' nicht genau dem entgegenwirken?

volatile auf eine lokale Variable ist ziemlich sinnlos.
Das weiß auch der Compiler.

von Anja (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> volatile auf eine lokale Variable ist ziemlich sinnlos.

mann könnte aber "static volatile" verwenden

Gruß Anja

von Karl H. (kbuchegg)


Lesenswert?

Anja schrieb:
> Karl Heinz Buchegger schrieb:
>> volatile auf eine lokale Variable ist ziemlich sinnlos.
>
> mann könnte aber "static volatile" verwenden

sollte IMHO keinen Unterschied machen.
Solange die Adresse der Variablen nicht an 'ausserhalb der Funktion' 
weggeben wird, ist klar, dass sich diese Variable eben nicht auf für den 
Compiler nicht einsehbaren Wegen ändern kann.

Bei einem 'celveren' Compiler würde ich eigentlich erwarten, dass er 
drauf kommt, ob der 'volatile macht den Unterschied'-Fall überhaupt 
eintreten kann und er dann das volatile ignoriert.

in

void foo()
{
  volatile i;

  i = bar();
}

gibt es nun mal keine (standard konforme) Möglichkeit, wie sich i jemals 
ändern kann, ohne das der Compiler das merkt. Der Scope ist auf die 
Funktion begrenzt, alle potentiellen Änderungen können nur im Kontext 
dieser Funktion stattfinden. static würde daran nichts ändern.

Oder überseh ich da jetzt etwas?

von Ralph (Gast)


Lesenswert?

Bei dem Aufbau werden die Variablen im Speicher nicht angelegt.
Der Compiler wird die Werte entweder in den Prozessorregistern oder auf 
dem Stack verwalten.

Um den Compiler dazu zu zwingen das diese Variablen als Variablen mit 
eigenem Speicher angelegt werden, wirst du diese als Global Variablen 
anlegen müssen.

von Steel (Gast)


Lesenswert?

Es liegt nicht an der Optimierung, es liegt daran, dass du nur globale 
variablen zum watch hinzufügen kannst. Die von dir in der Funktion 
angelegten Variablen sind nur im Scope der Funktion sichtbar, du 
müsstest sie aber unter locals angucken können wenn du in der funktion 
einen breakpoint machst.

von Karl H. (kbuchegg)


Lesenswert?

Steel schrieb:
> Es liegt nicht an der Optimierung, es liegt daran, dass du nur globale
> variablen zum watch hinzufügen kannst.

Echt?

Schwacher Debugger.
Das kann sogar der MS-Debugger seit 20 Jahren. Ist die Funktion nicht 
aktiv, dann ist die Variable 'out of scope'. Wird die Funktion betreten, 
bestimmt der Debugger die Speicheradresse der lokalen Var neu und 
befüllt das Watch-Fenster wieder mit Werten.

von Steel (Gast)


Lesenswert?

Die Keil Entwicklungsumgebung hat ja bestimmt auch schon 20 Jahre aufm 
Buckel und wurde höchstens mal was aufgehübscht aber nie von Grund auf 
neu Entwickelt.

von Daniel (Gast)


Lesenswert?

Also bei µVision V4.53.0.0 kann man auch locale Variable zum Watch 
hinzufügen und sehen. Das Verhalten ist genau so, wie es Karl Heinz 
Buchegger beschreibt. Bei CodeBlocks z.B. werden die lokalen Variablen 
unter "locals" angezeigt. Der µVision Editor ist aber echt zum kotz... 
;-)

von A. B. (funky)


Lesenswert?

yep isser!! so ein altes vermurkstes mistding. komfort gleich null!!

hmmm...lokale Variablen seh ich übrigens nicht im watch window...ich seh 
die nur im extra "watch locals" fenster, was ein wenig nervig ist, da 
dort dann alle variablen stehen und nicht nur die, welche ich eigentlich 
sehen will.

Meinst du das? oder habe ich etwas falsch konfiguriert?!

habe auch 4.53.0.0

von Jan K. (jan_k)


Lesenswert?

Rechtsklick auf die Variable -> add to Watch 1/2?

Funktioniert hier und gibt auch <out of scope> an, wenn ich mich 
außerhalb der Funktion befinde.

von A. B. (funky)


Lesenswert?

nö...lokale variablen sehe ich nicht, auch wenn ich mich innerhalb der 
funktion befinde. die sind immer out of scope im watch 1/2 fenster.
die sehe ich nur im watch/locals fenster

welchen debugger benutzt du? ich habe den keil2. kann das einen 
unterschied machen?

von Jan K. (jan_k)


Lesenswert?

Hier meine Infos :
1
IDE-Version:
2
µVision V4.20.03.0
3
Copyright (C) 2011 ARM Ltd and ARM Germany GmbH. All rights reserved.
4
5
License Information:
6
*****
7
LIC=----
8
9
Tool Version Numbers:
10
Toolchain:        MDK-Lite  Version: 4.20
11
Toolchain Path:    BIN40\
12
C Compiler:         Armcc.Exe       V4.1.0.644 [Evaluation]
13
Assembler:          Armasm.Exe       V4.1.0.644 [Evaluation]
14
Linker/Locator:     ArmLink.Exe       V4.1.0.644 [Evaluation]
15
Librarian:             ArmAr.Exe       V4.1.0.644 [Evaluation]
16
Hex Converter:      FromElf.Exe       V4.1.0.644 [Evaluation]
17
CPU DLL:               SARMCM3.DLL       V4.20
18
Dialog DLL:         DCM.DLL       V1.02
19
Target DLL:             STLink\ST-LINKIII-KEIL.dll       V1.5.6
20
Dialog DLL:         TCM.DLL       V1.02

von A. B. (funky)


Lesenswert?

hmm...ok.
ich hab die 4.5 und davor hatte ich die 4.22a(wars glaube ich)

mit der 4.20 hab ich es nie ausprobiert.

mal im keil forum nachfragen ob das dort jemand bestätigen kann.

von A. B. (funky)


Lesenswert?

ok,

habe es nochmal ausprobiert und es geht. keine ahnung was das war...bin 
mir eigentlich 100% sicher das es neulich nicht funktioniert hat, aber 
evtl. hat da was rumgesponnen oder der Fehler sass vorm PC ;P

von Jan K. (jan_k)


Lesenswert?

Es ist auch durchaus möglich, dass uVision da gesponnen hat, ab und zu 
kann ich mir z.B. in "System Viewer Windows" die einzelnen Register der 
Peripherie nicht angucken. Und wie oben erwähnt wurde ist der Editor 
auch eher suboptimal ;-)

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.