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
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?
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.
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.)
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.
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
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:60e0ldir22,0x00;0
6
ac:862fmovr24,r22
7
ae:3ad0rcall.+116;0x124<LCD_Locate>
8
LCD_Print_Str("Test");
9
b0:80e6ldir24,0x60;96
10
b2:90e0ldir25,0x00;0
11
b4:4bd0rcall.+150;0x14c<LCD_Print_Str>
12
b6:f9cfrjmp.-14;0xaa<main+0x26>
13
14
000000b8<LCD_Delay>:
15
}
16
17
voidLCD_Delay()
18
{
19
for(chara=0;a<255;a++)
20
b8:80e0ldir24,0x00;0
21
ba:8f5fsubir24,0xFF;255
22
bc:8f3fcpir24,0xFF;255
23
be:e9f7brne.-6;0xba<LCD_Delay+0x2>
24
c0:0895ret
25
26
000000c2<Write_LCD>:
27
c2:982fmovr25,r24
28
c4:6623andr22,r22
UBUNTU
1
// main loop...
2
while(1)
3
{
4
LCD_Locate(0,0);
5
aa:60e0ldir22,0x00;0
6
ac:80e0ldir24,0x00;0
7
ae:3bd0rcall.+118;0x126<LCD_Locate>
8
LCD_Print_Str("Test");
9
b0:80e6ldir24,0x60;96
10
b2:90e0ldir25,0x00;0
11
b4:2bd0rcall.+86;0x10c<LCD_Print_Str>
12
b6:f9cfrjmp.-14;0xaa<main+0x26>
13
14
000000b8<LCD_Delay>:
15
}// loop */
16
}// main */
17
18
// end programm
19
20
b8:0895ret
21
22
000000ba<Write_LCD>:
23
ba:282fmovr18,r24
24
bc:6623andr22,r22
25
be:11f4brne.+4;0xc4<Write_LCD+0xa>
26
c0:c598cbi0x18,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.
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.
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
voidLCD_Delay()
2
{
3
for(chara=0;a<255;a++)
4
{
5
for(charb=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