www.mikrocontroller.net

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


Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum ist das schräg?

Folgender Fall:

x = 1;
x = x + 1;

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

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tools -> Options -> Tools -> [WinAVR] Make all -> Edit -> Shortcut

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh je wie peinlich :) Danke !

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wann empfiehlt es sich eigentlich, ein "make clean all" zu machen ?

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn man ALLE resourcen neu Kompilieren und die dependencies neu
erzeugen möchte.

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ?

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.