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?
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
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: 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.
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 | }
|
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 | 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.