Forum: Compiler & IDEs Makefile Ubuntu<->WinXP


von _CH_ (Gast)


Angehängte Dateien:

Lesenswert?

Hallo!

ich bin gerade dabei mein ganzes AVR-Zeug auf Ubuntu lauffähig zu 
kriegen.

Im Wiki steht, dass die Makefiles plattformunabhänging sind. Bei mir 
aber leider nicht... Wenn ich unter WinXP mit WinAVR kompiliere, dann 
funktioniert's einwandfrei. Beim Kompilieren mit avr-gcc unter Ubuntu 
erhalte ich zwar die gleiche Größe der .hex-Datei, aber wenn ich die 
Datei flashe, dann macht der Controller nur Quatsch bzw. nicht's 
definiertes.

Ein unter WinXP kompiliertes Hex-File kann ich auf Ubuntu mit "make 
program"  ohne Probleme flashen und läuft dann auch wie gewünscht.

Liegt das an einer Einstellung im Makefile, oder eher an was anderem?

Gruß,
Christian

von Stefan (Gast)


Lesenswert?

Es kann ja sein, dass du unter XP und Ubuntu unterschiedliche Compiler- 
und Libraryversionen hast und dadurch unterschiedliche Programme erzeugt 
werden. Die Größe des HEX-Files alleine besagt IMHO nix; ich nehme an 
auf's Byte genau wird die Größe nicht identisch sein.

Hast du mal die Versionsnummern verglichen? Und wie sieht es mit den 
anderen Dateien vom Kompilieren aus? Wie unterscheiden sich die LSS- 
(Listing) und die MAP (Mapping) Dateien?

von _CH_ (Gast)


Lesenswert?

Hallo Stefan,

Versionsnummern:
Ubuntu: gcc 4.1.0
WinXP:  gcc 3.4.3

LSS:
Ubuntu: 21.1kB
WinXP:  21.9kB

MAP:
Ubuntu: 15.4kB
WinXP:  17.1kB

HEX (etwas genauer hingesehen)
Ubuntu: 2718Byte
WinXP:  2804Byte

Hilft das was weiter?

Gruß,
Christian

von Stefan (Gast)


Lesenswert?

Ja aber noch nicht besonders viel. Man weiss jetzt, dass es 
unterschiedliche Toolchain-Versionen sind.

Deine WinAVR Version ist ziemlich alt. Die letzte auf Sourceforge ist 
die WinAVR-20060125 und die hat bereits GCC 3.4.5 drin. Dein WinAVR 
müsste also die Vorgängerversion WinAVR-20050214 sein; bei der wurde 
erstmals GCC 3.4.3 verwendet. Ich kann dir beim Vergleich nicht durch 
eigene Experimente helfen, weil ich keine so alte WinAVR installiert 
habe.

Um die Unterschiede herauszufinden kann man analytisch vorgehen und die 
beiden Listings und Mapfiles systematisch auf Unterschiede abklopfen. 
Kannst sie ja ggf. hier anhängen, wenn deine Source nicht für 
Bankautomaten gedacht ist.

Oder man kann Teile der Toolchains (aus include und lib Ordner, nicht 
bin Ordner) wechselseitig gegeneinander austauschen, um den Übeltäter zu 
finden. Die Gefahr ist aber, dass man durch Unachtsamkeit beim 
Copy&Paste ein wildes Mischmasch anrichtet.

Eine dritte Methode ist, weiter zu recherchieren, bis man jemanden 
findet, der das gleiche Problem schon gelöst hat. Die Versionsnummern 
helfen da möglicherweise bei der Suche.

Hier sind die gcc-avr Packages für Ubuntu gelistet:
http://packages.ubuntulinux.org/cgi-bin/search_packages.pl?keywords=gcc-avr&searchon=names&subword=1&version=all&release=all

Hast du ein Package von hier, dann scheinst du Ubuntu Edgy oder Feisty 
zu benutzen. Wieder ein Rahmschnitzel für die Jagd ähm Stichwort.

Leider habe ich beim Stöbern auch eine andere Entwicklertruppe gefunden, 
die Mitte Dezember noch heftige Probleme mit GCC-AVR 4.1.0 auf Ubuntu 
Edgy hatte und die deswegen auf 3.4.3 (und die entsprechende binutils 
und avr-libc) zurückgegangen sind (quasi Weg 2 oben allein unter 
Ubuntu).
http://nesl.ee.ucla.edu/pipermail/sos-user/2006-December/001011.html

Aus Anwendersicht (deiner) ist das Problem vielleicht nicht so einfach 
lösbar.



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


Lesenswert?

Wobei das natürlich auch ein schlechtes Zeichen für diese Software
sein kann.  Sie behaupten auch einfach nur ohne Erklärung, man müsse
das halt so und so machen, sonst geht's nicht.  Eine Analyse vermisse
ich komplett.

Nicht, dass ich die Tools für bugfrei halten würde, aber ich kann mich
gerade nicht daran erinnern, dass AVR-GCC 4.1.x irgendeinen wesentlichen
Bug hätte, den nicht auch die Vorgängerversionen gehabt hätte.  (Ich
spreche hier nicht von schlechterer Optimierung, sondern von echten
Bugs.)

von Stefan (Gast)


Lesenswert?

Klar das kann sein. Die SOS Source unter dem Link habe ich mir nicht 
angesehen. Vielleicht schiebt Christian die Source ja rüber und man kann 
Problemstellen darin entdecken. Das Makefile jedenfalls sieht sauber 
aus.

von _CH_ (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Stefan!

vielen Dank für deine Bemühungen!

So, meine Source gehört nicht für Bankautomaten :-) Ist eh kein 
richtiges Programm, sondern nur was zum Testen. Hab dir mal was 
drangehängt, vielleicht hilft es dir ja weiter...

Habe mir noch schnell das neue WinAVR installiert mit gcc 3.4.6 - leider 
bleibt das Problem...

Wenn es keine andere Lösung gibt, dann rüste ich halt denn avr-gcc auch 
zurück - hab da kein Problem damit.

Viele Grüße,
Christian

von Stefan (Gast)


Lesenswert?

Kann es sein, dass das Programm an sich funktioniert und der Fehler 
darin besteht, dass das auf Ubuntu kompilierte Programm "nur" keine 
Ausgabe auf dem LCD macht?

Die LCD_Delay() in der Ubuntu-Version ist nämlich ähnlich wie diese, 
nämlich leer. Unter der WinAVR-Version ist eine for-Schleife drin.

void LCD_Delay(void)
{
}

Siehe an den Listings:

WINAVR unter XP
1
// main loop...
2
  while(1)
3
    {
4
      LCD_Locate(0,0);
5
  aa:  60 e0         ldi  r22, 0x00  ; 0
6
  ac:  86 2f         mov  r24, r22
7
  ae:  3a d0         rcall  .+116      ; 0x124 <LCD_Locate>
8
      LCD_Print_Str("Test");
9
  b0:  80 e6         ldi  r24, 0x60  ; 96
10
  b2:  90 e0         ldi  r25, 0x00  ; 0
11
  b4:  4b d0         rcall  .+150      ; 0x14c <LCD_Print_Str>
12
  b6:  f9 cf         rjmp  .-14       ; 0xaa <main+0x26>
13
14
000000b8 <LCD_Delay>:
15
}
16
17
void LCD_Delay()
18
{
19
  for (char a=0;a<255;a++)
20
  b8:  80 e0         ldi  r24, 0x00  ; 0
21
  ba:  8f 5f         subi  r24, 0xFF  ; 255
22
  bc:  8f 3f         cpi  r24, 0xFF  ; 255
23
  be:  e9 f7         brne  .-6        ; 0xba <LCD_Delay+0x2>
24
  c0:  08 95         ret
25
26
000000c2 <Write_LCD>:
27
  c2:  98 2f         mov  r25, r24
28
  c4:  66 23         and  r22, r22

UBUNTU
1
// main loop...
2
  while(1)
3
    {
4
      LCD_Locate(0,0);
5
  aa:  60 e0         ldi  r22, 0x00  ; 0
6
  ac:  80 e0         ldi  r24, 0x00  ; 0
7
  ae:  3b d0         rcall  .+118      ; 0x126 <LCD_Locate>
8
      LCD_Print_Str("Test");
9
  b0:  80 e6         ldi  r24, 0x60  ; 96
10
  b2:  90 e0         ldi  r25, 0x00  ; 0
11
  b4:  2b d0         rcall  .+86       ; 0x10c <LCD_Print_Str>
12
  b6:  f9 cf         rjmp  .-14       ; 0xaa <main+0x26>
13
14
000000b8 <LCD_Delay>:
15
    }// loop */
16
}// main */
17
18
// end programm
19
20
  b8:  08 95         ret
21
22
000000ba <Write_LCD>:
23
  ba:  28 2f         mov  r18, r24
24
  bc:  66 23         and  r22, r22
25
  be:  11 f4         brne  .+4        ; 0xc4 <Write_LCD+0xa>
26
  c0:  c5 98         cbi  0x18, 5  ; 24

Wenn das eine essentielle Timing-Funktion ist (und das ist sie, siehe in 
LCD-Init()!), ist es klar, dass das LCD anders reagiert. Es ist möglich, 
dass die Funktion wegoptimiert wurde. Kannst du den Sourcecode dieses 
Programmteils aus posten (ist vermutlich in lcd.h drin)

Die Frage ist jetzt, wie man dem gcc-avr unter Ubuntu ausredet 
LCD-Delay() leerzuoptimieren. Ein brutaler Weg wäre per Makefile die 
Optimierung komplett auszuschalten (-O0) und mal kucken, was der Ball 
macht.

Es gibt vielleicht auch eine Funktionsattribut, um "diese Funktion nicht 
optimieren" an LCD_Delay() anzuhängen. Zur Not ein asm volatile ("nop"); 
im Schleifenkörper der for-Schleife.


von Stefan (Gast)


Lesenswert?

Du kannst die LCD-Delay() Funktion auch so schützen, so wie es in diesem 
Beispiel für die wait() Funktion gemacht wurde:

http://www.mikrocontroller.net/articles/MSPGCC
1
void
2
LCD_Delay(void)
3
{
4
   volatile unsigned char a;
5
   for(a = 0; a < 255; a++)
6
   ;
7
}

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


Lesenswert?

Stefan wrote:

> Die Frage ist jetzt, wie man dem gcc-avr unter Ubuntu ausredet
> LCD-Delay() leerzuoptimieren.

Indem man statt sinnloser zufällig erratener Schleifen die Funktionen
aus <util/delay.h> benutzt.  Dafür sind sie da.

von Stefan (Gast)


Lesenswert?

Oder so. Das ist die beste Methode.

von _CH_ (Gast)


Lesenswert?

Hallo Stefan,

>Kann es sein, dass das Programm an sich funktioniert und der Fehler
>darin besteht, dass das auf Ubuntu kompilierte Programm "nur" keine
>Ausgabe auf dem LCD macht?
ja ganz genau, mehr hab ich nicht reingepackt - wollte ja nur sehen ob 
der Kleine nach dem Flashen überhaupt was macht

>Wenn das eine essentielle Timing-Funktion ist...
ja ist es auch; Alle Wartezeiten für's LCD werden mit "bussy-waiting" 
realisiert.
Der Code ist ziemlich primitiv, sind einfach nur zwei geschachtelte 
(leere) for-Schleifen.
1
void LCD_Delay()
2
{
3
   for (char a=0;a<255;a++)
4
   {
5
      for (char b=0;b<10;b++);
6
   }
7
}
Als ich in den Anfängen meiner "Controllerzeit" diese kurze LCD-Lib 
geschrieben hatte, dachte ich noch nicht an Kompileroptimierung oder 
ähnliches - es hat halt funktioniert und gut war.

Ich habe kurz mal zum Testen "asm volatile ("nop");" eingefügt und 
getestet - funktioniert prima.

Den Vorschlag von Jörg werde ich berücksichtigen und die LCD-Lib mit der 
<util/delay.h> ausbessern. Danke! Oder gleich mal eine neue und 
"saubere" Variante coden, wäre wahrscheinlich noch besser.

So, momentan sieht's gut aus - wieder was dazugelernt.

Wie hast du denn die beiden Dateien verglichen? Gibt es da nen Editor 
der zwei Dateien vergleichen kann und die Differenzen "anmeckert" oder 
hast du da zu Fuß durchgeschaut?

Dann vielen Dank, dass du dich da so reingehängt hast! Hast was gut bei 
mir. Ich geb dir schon mal ein virtuelles Bier aus :)

Viele Grüße,
Christian



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.