Forum: Compiler & IDEs WinAVR, AVR Studio und cof-File


von Thorsten (Gast)


Lesenswert?

Hallo,

ich möchte gerne mit AVR Studio 4.08 ein mit WinAVR erzeugtes Programm
simulieren. Dazu erstelle ich mit "make extcoff" das cof-File und
lade es in AVR Studio. Nur bei der Simulation springt er ziemlich
wahlos in den Sourcen umher. Es werden Zeilen übersprungen, oder er
springt in Leerzeilen. Zusammengefasst funktioniert die Siumulation
nicht. Kann mir jemand sagen, was ich falsch mache ?

Vielen Dank.

Mfg
Thorsten

von mthomas (Gast)


Lesenswert?

mglw. garnichts, ueberspringen von Zeilen kann daran liegen, dass es
aufgrund der Compiler-Optimierung keine Debug-Symbole fuer die
entsprechende Quellcode-Zeile gibt. Vielleicht auch mal mit dem neuen
elf-Parser ausprobieren (neustes WinAVR, neustes AVRStudio) naeheres
dazu im wiki (avr-gcc-tutorial).

von Thorsten (Gast)


Lesenswert?

Danke, das Stichwort Optimierung war das richtige. Ich hatte folgendes
programmiert:

void DisplayTime(U32 * time)
{
   U08 hours, min, sec, Buffer[9] = "00:00:00\0";

   hours = *time / 3600;
   min   = (*time % 3600) / 60;
   sec   =  *time % 3600 % 60;

   Buffer[0] += (hours / 10); Buffer[1] += (hours % 10);
   Buffer[3] += (min / 10)  ; Buffer[4] += (min % 10);
   Buffer[6] += (sec / 10)  ; Buffer[7] += (sec % 10);

   /*
   #ifdef LCD4LINES
     LCD_SetCursorPos(LINE3+6);
   #else
     LCD_SetCursorPos(LINE2+6);
   #endif

   LCD_PutString(Buffer);
   */
}

Entscheidend ist der auskommentierte Teil. Die drei Zeilen darüber
(Buffer[0]...) hat der Compiler wohl komplett wegoptimiert, weil
offensichtilich mit Buffer später nichts mehr angestellt wurde. Daran
hat sich trotz Abschaltung der Optimierung im Makefile nichts geändert.
Erst nachdem die Auskommentierung aufgehoben wurde, funktionierte alles.
Das finde ich jetzt mal extrem schräg. Mit der Deklarierung

U08 volatile Buffer[9]=...

funktionierts übrigens auch.

Danke nochmals.

von OldBug (Gast)


Lesenswert?

Warum ist das schräg?

Folgender Fall:

x = 1;
x = x + 1;

Das wird warscheinlich auch in ein simples "x = 2" übersetzt...

von Thorsten (Gast)


Lesenswert?

Wird es interssanterweise nicht. Bei der Deklaration "volatile unsigned
char x" ensteht folgendes:

;x=1
LDI     R24,0x01
STD     Y+1,R24
;x=x+1
LDD     R24,Y+1
SUBI    R24,0xFF
STD     Y+1,R24

Ohne volatile wird mal wieder überhaupt kein Code erzeugt.

von OldBug (Gast)


Lesenswert?

Klar, weil mit x ja "nichts passiert" und "nicht benötigt" wird.

Kurzes Beispiel:

#include <avr/io.h>
#include <inttypes.h>

int
main(void)
{
   uint8_t x = 0;

   DDRB = 0xFF;
   PORTB = x;

   while(1)
   {
      x++;
      PORTB = x;
   }

   /* NEVEREACHED */
   return 0;
}

[..]
  29                 .LM2:
  30 0008 90E0          ldi r25,lo8(0)
  31                 .LM3:
  32 000a 8FEF          ldi r24,lo8(-1)
  33 000c 87BB          out 55-0x20,r24
  34                 .L4:
  35                 .LM4:
  36 000e 98BB          out 56-0x20,r25
  37                 .LM5:
  38 0010 9F5F          subi r25,lo8(-(1))
  39 0012 FDCF          rjmp .L4
[..]

Hier erkennt der Compiler, daß x zur Laufzeit dem PORTB zugewiesen
wird.
Als nächstes dann der Beweis zu meiner These "x = 2":


#include <inttypes.h>

int
main(void)
{
   uint8_t x = 1;

   DDRB = 0xFF;
   PORTB = 0;

   x = x + 1;
   PORTB = x;

   while(1)
   {
   }

   /* NEVEREACHED */
   return 0;
}

[..]
  29                 .LM2:
  30 0008 8FEF          ldi r24,lo8(-1)
  31 000a 87BB          out 55-0x20,r24
  32                 .LM3:
  33 000c 18BA          out 56-0x20,__zero_reg__
  34                 .LM4:
  35 000e 82E0          ldi r24,lo8(2)
  36 0010 88BB          out 56-0x20,r24
  37                 .L2:
  38                 .LM5:
  39 0012 FFCF          rjmp .L2
[..]

Speziell Zeile 35 verdeutlicht das!

von OldBug (Gast)


Lesenswert?

Nachtrag:

1. Da ist mir beim zweiten Beispiel ne Zeile verloren gegangen:

#include <avr/io.h>

2. Kompiliert für einen ATMega8 mit Optimierungslevel "s".
3. MFile zum Erzeugen des Makefiles benutzt.

von Thorsten (Gast)


Lesenswert?

Alles klar, ich muß mich wohl an volatile gewöhnen, wenn alles so
ausgeführt werden soll, wie auch programmiert.

Noch ne Frage, die mit diesem Thema nichts zu tun hat: kann man bei
Programmers Notepad 2 die Funktion "Make All" auch über ein
Tastaturkürzel erreichen ? Ich habe nirgends eine Beschreibung gefunden
und ständig mit der Maus ins Menu gehen nervt mich schon etwas. Denn
eigentlich finde ich es sehr angenehm mit dem PN2 zu arbeiten.

Vielen Dank.

MfG
Thorsten

von OldBug (Gast)


Lesenswert?

Tools -> Options -> Tools -> [WinAVR] Make all -> Edit -> Shortcut

von Thorsten (Gast)


Lesenswert?

Oh je wie peinlich :) Danke !

von OldBug (Gast)


Lesenswert?

Ich hab mir, obwohl ich PN nur gelegentlich nutze, noch "[WinAVR]
Rebuild" angelegt.

Command: make.exe
Folder: %d
Parameters: clean all
Shortcut: F7 (bin ich so gewohnt)
Save: All Files

von Thorsten (Gast)


Lesenswert?

Wann empfiehlt es sich eigentlich, ein "make clean all" zu machen ?

von OldBug (Gast)


Lesenswert?

Wenn man ALLE resourcen neu Kompilieren und die dependencies neu
erzeugen möchte.

von Jörg Wunsch (Gast)


Lesenswert?

> Alles klar, ich muß mich wohl an volatile gewöhnen, ...

Nein, um Himmels Willen!

Gewöhn' Dich bitte lieber an die Optimierungen und schreibe keinen
Code, der am Ende nicht benutzt wird, von dem Du aber erwartest, daß
der Compiler ihn umsetzt...

Wenn Du die Optimierung ganz oder teilweise (volatile) abschaltest,
erzeugst Du nicht nur größeren und/oder langsameren Code, sondern Du
debuggst eine völlig andere Applikation als die, die es künftig mal
werden soll.  Das ist schade um die Arbeit.

von Thorsten (Gast)


Lesenswert?

ich habe jetzt aber wirklich ein Problem. Ich möchte eine Funtkion
testen (Laufzeit), die gleiche übrigens aus meinem dritten Posting.
Dazu habe ich jetzt im Hauptprogramm folgendes gemacht:

#define U32 unsigned long;

int main(void)
{
   volatile U32 test;

   test = 215999;      //
   DisplayTime(&test);
   ...
}

Er macht es einfach nicht, weder setzt er test auf den geforderten
Wert, noch erzeugt er Code für DisplayTime(). Was soll ich denn jetzt
machen ?

von Thorsten (Gast)


Lesenswert?

Seltsmerweise bekomme ich außerdem folgende Warnung:
"passing arg 1 of `DisplayTime' discards qualifiers from pointer
target type". Damit kann ich nichts anfangen, zumal alles mal
funktioniert hat.

von Jörg Wunsch (Gast)


Lesenswert?

Warum er für Deine Funktion keinen Code erzeugt hat, ist mir so
erstmal nicht ersichtlich.  Wenn die Funktion DisplayTime sehr simpel
ist, könnte er sie inline erweitert haben (also ohne RCALL).

Die Warnung besagt, daß Deine Variable mit dem volatile qualifier
deklariert worden ist (übrigens völlig unsinnig an dieser Stelle, da
für die Übergabe einer Adresse zwangsläufig Speicher eingeräumt werden
muß), die Funktion aber ohne volatile ... * deklariert ist, d. h. die
Funktion weiß nicht mehr, daß sie das übergebene Objekt als volatile
behandeln soll.

von Micha (Gast)


Lesenswert?

Ich bin jetzt kein AVR-GCC Profi, aber aufpassen beim Zuweisen von
literals (konstanten Zahlenwerten) normalerweise werden die als integer
(16bit-> max. 65535) behandelt, vor die Zuweisung der Zahl 215999 sollte
ein cast auf long erfolgen, sonst fehlen in der variable test nach der
Zuweisung die oberen 16 bits...

von Jörg Wunsch (Gast)


Lesenswert?

Ein Compiler, der das (zumindest bei einer simplen Zuweisung) tut,
wäre nicht Standard konform.  Der Standard verlangt, dass die
Konstante den Datentyp bekommt, der für die komplette Darstellung
notwendig ist.

Anyway, es ist eine sinnvolle und gute Gewohnheit, im Falle einer
Bereichsüberschreitung von `int' auch in der Tat die Konstante (42)
als long (42L) oder unsigned long (42UL) zu deklarieren.

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.