Hallo, eine Frage, die die Experten sicher schnell beantworten können: Hat sich zwischen WinAVR 2003 09 13 und der aktuellen Version 2008 02 04 soviel geändert, daß man die alten Programme mit der neuen Version überhaupt nicht mehr kompiliert bekommt? Die Bitmanipulationen scheinen nicht mehr zu funktionieren, ist denn da inzwischen alles depreceated? Müssen z.B. Zeilen wie " TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); " gänzlich neu geschrieben werden, damit es wieder funktioniert? Und noch ein kleineres Problem: füher konnte man schreiben #include <avr/util/twi.h>, jetzt wird der gesamte Pfad verlangt, also z.B. #include <C:/Progr-MCU/WinAVR0800204/avr/include/avr/twi.h>. Ist denn das normal oder ist da bei meiner Installation etwas falsch gelaufen? mfg Peter
> Ist denn das normal
Nein.
Gast
#828049
>Hat sich zwischen WinAVR 2003 09 13 und der aktuellen Version 2008 02 04 >soviel geändert, daß man die alten Programme mit der neuen Version >überhaupt nicht mehr kompiliert bekommt? Ja, so ist es! Allerdings trifft es auf die zwei von dir genannten Fänomehne nicht zu.
Peter Leistikow wrote: > Die Bitmanipulationen scheinen nicht mehr zu funktionieren, ist denn da > inzwischen alles depreceated? Deprecated waren sie selbst 2003 schon. Deine Software hat sich offenbar nur nicht dran gehalten.
Peter Leistikow wrote: > Müssen z.B. Zeilen wie > " TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); " > gänzlich neu geschrieben werden, damit es wieder funktioniert? Nein. Die Zeile ist voll o.k. > füher konnte man schreiben > #include <avr/util/twi.h>, Ist immer noch so. > jetzt wird der gesamte Pfad verlangt, also z.B. > #include <C:/Progr-MCU/WinAVR0800204/avr/include/avr/twi.h>. Dann ist was schief gelaufen bei der Installation. Peter
Gast
#828162
Naja...ein Compiler, der Ansprüche bei Bitmanipulationen stellt...grummmel...
Peter Leistikow wrote:
> #include <avr/util/twi.h>,
Wenn das mal so war, hat sich das geändert.
Der Ordner util ist jetzt nicht im avr Verzeichnis, sondern eine Ebene
oberhalb! Also:
#include <util/twi.h>
bzw. geht auch
#include <compat/twi.h>
was aber auch nur util/twi.h einbindet. Dass dein kompletter Pfad
funktioniert, ist klar: dort berücksichtigst du ja, dass util nicht in
avr steht.
Stefan "stefb" B. wrote: > Peter Leistikow wrote: > > Der Ordner util ist jetzt nicht im avr Verzeichnis, sondern eine Ebene > oberhalb! Also: > > #include <util/twi.h> > Stimmt! Ich hätte genauer hinsehen sollen! Vielen Dank Peter
Jupp wrote: > Naja...ein Compiler, der Ansprüche bei Bitmanipulationen > stellt...grummmel... Macht er doch gar nicht. Er hat die Standard-Bitoperatoren von C schon immer verstanden und wird sie immer verstehen. Nur manche Nutzer tun sich zuweilen schwer damit, diese zu verstehen, und benutzen daher allerlei andere Darstellungen stattdessen.
Hallo, Auch ich habe so einige Probleme mit den neuen Versionen. 20060421 ist meine letzte funktionstüchtige Winavr-Toolchain. Alle Versionen danach liefern entweder keinen lauffähigen Maschinenkode oder haben wie die jetztige Ausgabe ein Problem mit den ...._P Funktionen bzw PSTR. Das heißt der selbe Quellkode bringt ohne Warning oder Error unterschiedliche Ergebnisse. Ich verwende keine Optimierungen. Der Grund warum ich auf eine neuere Version umsteigen möchte, liegt in der Hoffnung dass nun vielleicht schon mehr _P Funktionen zur Verfügung stehen. Hat wer eine Ahnung woran das liegen könnte? Mich wundert natürlich, dass andere keine Probleme damit haben. Gruß Willi
Gast
#890672
>Ich verwende keine Optimierungen.
Da solltest Du aber unbedingt tun! Verwende zumindest die Stufe O-1,
höhere Stufen bringen dann nicht mehr wahnsinnig viel.
Wilhelm Stejskal wrote: > Hallo, > > Auch ich habe so einige Probleme mit den neuen Versionen. > 20060421 ist meine letzte funktionstüchtige Winavr-Toolchain. > Alle Versionen danach liefern entweder keinen lauffähigen Maschinenkode > oder haben wie die jetztige Ausgabe ein Problem mit den ...._P > Funktionen bzw PSTR. Das heißt der selbe Quellkode bringt ohne Warning > oder Error unterschiedliche Ergebnisse. Ich verwende keine > Optimierungen. > > Hat wer eine Ahnung woran das liegen könnte? > > Mich wundert natürlich, dass andere keine Probleme damit haben. Wenn der Compiler nachweislich falschen Code erzeugt ist das ein Bug. Der Compiler muss auch ohne Optimierung korrekten Code liefern. Manche Fehler treten eben nur mit -O0 auf und bei höhrern Optimierungsstufen nicht mehr. O0 wird selten verwendet, daher ist vielleicht noch nicht aufgefallen. Ich erinnere mich da ab Probleme bei local static im Zusammenhang mit PROGMEM. Ohne Quelle ist's aber Lesen ausm Kaffeesatz...
Gast
#890861
>Mich wundert natürlich, dass andere keine Probleme damit haben. Stell doch mal ein Beispiel hier rein, der nur mit einem 2006er WinAVR funktioniert. Oliver
Jetzt muss ich erst einmal mein laufendes Projekt fertigstellen. Danach werde ich mich erneut zu diesem Thema äußern. Also bitte um etwas Geduld. Gruß Willi Ps.: Was ich im Listing gesehen habe, könnte es sich um ein near/far-Problem handeln.
Ich habe heute folgendes festgestellt: Bei der Version 080610 wird beim Konvertieren des HEX-Files in ein SREC-File (z.B srec_cat test.hex -Intel -Output test.srec -Motorola -Line_Length 142) kein S9-Record gesetzt. Damit haben Programmer und Bootloader schon mal ihre Probleme. Weiters führen die Funktionen eeprom_read_byte(&test8) und eeprom_read_word(&test16) zum Absturz. Die Schreibfunktionen hingegen scheinen keine Probleme zu machen. Ob ins EEProm tatsächlich geschrieben wird kann ich im Moment aber nicht prüfen. Selber Sourcecode mit einer Toolchainversion von 2006 kompiliert läuft tadellos. WinAVR aus 2006 hat allerdings Probleme mit Windows Vista. Darum bin ich auf die derzeitge 2008er Version angewiesen.
Wilhelm Stejskal wrote: > Ich habe heute folgendes festgestellt: > > Bei der Version 080610 wird beim Konvertieren des HEX-Files in ein > SREC-File (z.B srec_cat test.hex -Intel -Output test.srec -Motorola > -Line_Length 142) kein S9-Record gesetzt. srec_cat gehört zu srecord (http://srecord.sourceforge.net/) und damit nicht zum GCC. vielleicht gibts da ne neue Option um das einzustellen? > Damit haben Programmer und > Bootloader schon mal ihre Probleme. Weiters führen die Funktionen > eeprom_read_byte(&test8) und eeprom_read_word(&test16) zum Absturz. Wer stürzt ab? deine Kaffetasse, dein Windows, AVRStudio, der GCC-Compiler, der AVR nachher? Oder meinst du mit "abstürzen": "er gibt eine Warn/Fehlermeldung aus, die ich nicht lesen wollte"? > Die > Schreibfunktionen hingegen scheinen keine Probleme zu machen. Ob ins > EEProm tatsächlich geschrieben wird kann ich im Moment aber nicht > prüfen. Selber Sourcecode mit einer Toolchainversion von 2006 kompiliert > läuft tadellos. Kompilier doch mal mit allen Warnings eingeschaltet (-Wall), behebe die angezeigten Probleme, und versuchs erneut. Solche Probleme entstehen oft, wenn der Quelltext von Anfang an Fehlerhaft war, und nur durch Zufall mit der alten Version funktioniert hat.
Gast
#912881
Mein lieber Ernst, Klar hast du Recht das srec_cat nicht zum gcc gehört. Aber es ist nun mal ein Teil der Toolchain WinAVR und daher im Ganzen gesehen erfolgsbestimmend. Deine Frage von wegen Errors, Warnings und unsauberen Kode kann ich dir leicht beantworten. Nein ich habe keine Errors und keine Warnings. Ein Warning würde ich persöhnlich bereits als Error werten und somit nicht zulassen. Fakt ist, dass ein und der selbe Kode unterschiedliche Ergebnisse bringt. 2006 läuft und 2007 bzw. 2008 läuft nichtmehr. Der GCC ist mit dem Makefile standardmäßig konfiguriert (MFILE). Die einzigen Änderungen der Konfig waren die Abschaltung der Optimierung, setzen der float für die printf, CPU-Geschwindigkeit und der Dateiname. Gleiches neues Makefile wurde auch für die 2006er-Version erfolgreich verwendet. Ich hoffe das dies jetzt auch für dich klar und eindeutig beschrieben ist und erhoffe mir anstatt wortglauberischen Standardsätzen vielleicht doch noch zu kompetenten Antworten zu kommen. Gruß Willi
Wilhelm Stejskal wrote: > Ich hoffe das dies jetzt auch für dich klar und eindeutig beschrieben > ist und erhoffe mir anstatt wortglauberischen Standardsätzen vielleicht > doch noch zu kompetenten Antworten zu kommen. Glaube ich nicht. Werd' mal konkreter. EDIT: Etwas entschärft. Sorry ;)
Wilhelm Stejskal wrote: > Fakt ist, dass ein und der selbe Kode unterschiedliche Ergebnisse > bringt. 2006 läuft und 2007 bzw. 2008 läuft nichtmehr. Der GCC ist mit > dem Makefile standardmäßig konfiguriert (MFILE). Die einzigen Änderungen > der Konfig waren die Abschaltung der Optimierung, setzen der float für > die printf, CPU-Geschwindigkeit und der Dateiname. Gleiches neues > Makefile wurde auch für die 2006er-Version erfolgreich verwendet. Fakt ist, ein und derselbe Code liess sich sowohl mit diversen 3er als auch mit 4er AVR-GCC-Versionen compilieren, ohne Abstürze, und hat jedesmal ein funktionierendes Hexfile ergeben, auch wenn der Speicherbedarf immer etwas geschwankt hat. Wenn das bei dir anders war, musst du uns schon ein Beispiel-Codefragment zeigen. Reines "Früher war alles besser"-Gejammer bringt dir nix, und hilft auch den AVR-GCC-Maintainern nicht weiter, das Problem zu finden.
So, ich habe es nun. Es ist ein echter bug. Da ihr aber ja sooo gut und erhaben seid, alle anderen von Haus aus erstmal für einen Trottel anseht und selbst nur blanke Sprüche von euch geben könnt, lasse ich euch einfach mal selber weiter raten woran es liegt. Wer natürlich nur dumme Reden schwingen kann oder über eine "Hello world" selbst noch nicht darüber hinaus gekommen ist, wird's wohl nicht merken. Wer sich allerdings mit der Materie wirklich beschäftigt der wird es über kurz oder lang auch entdecken. Alles nur eine Frage des Einsatzes und der aufzuwendenten Zeit. Also schwelgt weiter in eurem Hochmut und drescht Phrasen was das Zeug hält. Bedanke mich somit für die überaus fachlich kompetenten Wortmeldungen. Gruß Willi
Behalt ihn ruhig für dich. Das ist die beste Garantie, dass der Bug auch wirklich nie gefixt wird.
Gast
#914670
Don't feed the Trolls - wahrscheinlich wars nur ein vergessenes Semikolon, der Rest ist frei erfunden. Oliver
Das sicher nicht, denn die Syntax hat sich nicht geändert, das wäre also früher auch schon ein Syntaxfehler gewesen. ;-)
Wilhelm Stejskal wrote:
> So, ich habe es nun. Es ist ein echter bug.
Klar, ein Bug in deinem Programm. Das hätte ich dich auch vorher sagen
können ;)
lol Mit euch hat man ja wirklich richtig Spass. Oliver hat scheinbar keine Ahnung von C. Ansonsten würde er nicht meinen dass ein fehlendes Semikolon den Kontroller ins Nirwana schicken könnte. Aber immerhin hat er wenigstens neben dummen Sprüchen auch einen Versuch gewagt. g Simon ist da ja noch nicht soweit. Er beschränkt sich nur auf's Glauben und Mutmaßen. Diese Art wird euch sicher weiter bringen. @Jörg (dl8dtl) Keine Sorge, beide Bugs melde ich natürlich. Aber nicht in diesem Forum sondern direkt beim Team. Wäre hier auch bei solchen Spezialisten sinnlos. ;-) Gruß Willi (oe1msc)
Na, dann bin ich mal gespannt... Für den GCC 4.3.0 (und dessen WinAVR-Implementierung mit all den Xmega-Patches) gab's ja nun schon ein paar Bugs, die Eric teilweise auch repariert haben, aber du schreibst ja, dass bei dir auch der GCC 4.2.2 (oder 4.2.3, weiß ich gerade nicht ganz genau, was bei WinAVR 20071224 dabei war) nicht tut. Der hat sich eigentlich als ziemlich stabil erwiesen, insofern würde es mich schon wundern, wenn der tatsächlich für irgendwas, was früher ging, falschen Code generieren würde.
Gast
#914950
Schau die doch mal den arroganten Schreibstil von Wilhelm an. Er schreibt das ganze hier doch nur, weil er unbedingt Recht behalten möchte. @Wilhelm: Wir kommen hier auch ganz gut ohne deine Bugmeldung aus. Insofern, sind wir nicht sonderlich getroffen von deiner Ankündigung, uns diesen nicht mitzuteilen.
Gast
#914979
Bei den 2007er Versionen lag die CPU gleich bei der Einschaltmeldung flach. Das heißt beim ersten P-String. Ich habe dem aber aus Zeitmangel nicht sonderlich viel Interesse geschenkt und einfach mit der 2006er weiter gearbeitet. Erst mit dem Vista wurde ich gezwungen auf die 2008er umzusteigen. Da laufen zwar nun die P-Strings wieder, aber dafür das EEPROM "nicht". Meine momentane "Lösung" wird wahrscheinlich eine VirtualBox werden um die 2006er unter XP weiter am laufen zu halten.
Wilhelm Stejskal wrote: > Oliver hat scheinbar keine Ahnung von C. Ansonsten würde er nicht meinen > dass ein fehlendes Semikolon den Kontroller ins Nirwana schicken könnte. > Aber immerhin hat er wenigstens neben dummen Sprüchen auch einen Versuch > gewagt. *g* Natürlich kann ein fehlendes Semikolon auch zu falschem Code führen, wenn das ganze semantisch trotzdem korrekt ist. while (PINB & _BV(PB0)) PORTA=0xff; je nachdem ob du hinter dem while ein Semikolon hast oder nicht kommt anderer Code dabei raus. Beides ist semantisch richtig, funktionell aber doch nicht das selbe.
Oliver schrieb von einem "VERGESSENEN" Semikolon und nicht von einem das zuviel wäre. Jörg hat euch auch darauf hingewiesen dass der selbe Kode ja auf anderen Version läuft. (Bitte immer vor dem Posten lesen und verstehen!) Ich glaube aber wir sollten hier einen Schlußstrich ziehen. Das führt hier nämlich zu nichts und ich habe andere Aufgaben auch noch zu bewältigen. Wenn wer das gleiche Problem hat oder kennt, dann kann er mir ja eine PN mit konstruktivem Inhalt senden. Gruß Willi
Da du keine einzige Zeile an Code rausgerückt hast, ist es schier unmöglich herauszufinden, ob ein bestimmtes Problem dasselbe ist wie deins. Ich bin auf deine WinAVR-Bugreports gespannt.
Wilhelm Stejskal wrote: > Oliver schrieb von einem "VERGESSENEN" Semikolon und nicht von einem das > zuviel wäre. Jörg hat euch auch darauf hingewiesen dass der selbe Kode > ja auf anderen Version läuft. (Bitte immer vor dem Posten lesen und > verstehen!) Ich hab gelesen und verstanden, du aber anscheinend nicht. Es gibt nunmal Stellen an denen man das Semikolon weglassen kann, der Code immernoch compiled, aber halt nicht macht was er soll.
Nico Erfurth wrote: > Ich hab gelesen und verstanden, du aber anscheinend nicht. Es gibt > nunmal Stellen an denen man das Semikolon weglassen kann, der Code > immernoch compiled, aber halt nicht macht was er soll. Nun hör doch mal auf damit. Das sind zwar prima konstruierte Fälle, doch aber alles keine, bei denen das Kompilat dann auch früher schon keine Chance gehabt hätte, lauffähig zu sein.
Gast
#915117
>Oliver hat scheinbar keine Ahnung von C.
Naja, das mit dem Semikolon ist als einfache Umschreibung irgend eines
dummen Fehlers in deinem Programm gemeint gewesen.
Hättest du Ahnung vom Programmieren, hättest du hier gleich zu Anfang
ein aussagekräftiges und kompilierbares Codebeispiel gepostet, und nicht
nur ein banales "es stürzt ab". Ohne dieses wird auch das "Team"
fröhlich ratlos sein. Aber das weißt du ja alles sicherlich besser.
Oliver
Gast
#915142
Falls von Wilhelm ein konkreter bug-report mit nachvollziebarem code kommt, wäre ich durchaus interessiert! Das ist ja nicht unwichtig. Bitte auf dem laufenden halten. (bin aber skeptisch)
Icke wrote: > Falls von Wilhelm ein konkreter bug-report mit nachvollziebarem code > kommt, wäre ich durchaus interessiert! Das ist ja nicht unwichtig. https://sourceforge.net/tracker/?group_id=68108&atid=520074 Bugs 2009712 und 2009732
Wilhelm Stejskal wrote: > @Jörg (dl8dtl) > > Keine Sorge, beide Bugs melde ich natürlich. Aber nicht in diesem Forum > sondern direkt beim Team. Wäre hier auch bei solchen Spezialisten > sinnlos. ;-) Hehe, Ob du es hier, im avrfreaks-Forum oder als Bugreport einreichst, Jörg (und die anderen Maintainer natürlich) bekommt ihn so oder so. Sei also vorsichtig wen du abfällig hier als Spezialist bezeichnest :P http://savannah.nongnu.org/projects/avr-libc/ Rechts unter "Mitglieder" stehen die Maintainer.
Kann diese Bugs mal jemand nachvollziehen? Das ist ja kaum zu glauben.
Hab mir aus lauter Neugierde den letzten WINAVR installiert. Normalerweise nutze ich meine eigene Toolchain unter WinXP. Hab mein Webserver-Projekt (v. U.Radig) damit kompiliert. Das Binärfile wurde um weitere 400 Byte größer - puh. "warning: array subscript is above array bounds" Es trat ein mir bis dato unbekannter Warning auf, der einen Arrayfehler in einem meiner Module aufdeckte, den ich noch nie gesehen hatte. Das lob ich mir. Im GCC4.3.0 scheint also was ganz Neues drin zu sein. Im Gegensatz zum Original-Quellcode von Ulrich Radig mache ich bei meinem Projekt sehr umfangreichen Gebrauch von EEPROM-Varibalen (div. Arrays u. Variablen von uint8_t bis uint32_t), deren Speicherorganisation ich dem Compiler überlasse. Ulrich benutzt diese Möglichkeiten nicht. Also entspricht das in etwas dem erkannten EEPROM-Fehler - nur bei mir ist alles in Ordnung. (Atmega128)
Jörg Wunsch wrote: > https://sourceforge.net/tracker/?group_id=68108&atid=520074 > > Bugs 2009712 und 2009732 Oh Gott, das solln Bugreport sein? Kein Wunder, daß er sich nicht traut, den hier zu posten. Da mache ich mir auch keinerlei Hoffnung, daß sich das jemand näher ansieht. Man muß sich also erstmal nen Beispielcode basteln und hoffen, daß der Fehler auftritt. Und einen Reset macht die CPU auf keinen Fall, wenn nicht der Watchdog enabled ist. Warscheinlich wird der Stack zerschossen, ein Memorydump vor dem initialisieren des SRAM könnte hilfreich sein. Bzw. erstmal das Assemblerlisting der Codestellen. Peter
Gast
#915673
Neben dem Watchdog kann es auch ein Interrupt ohne ISR sein. Wenn ich mich richtig erinnere, unterscheiden sich da tatsächlich die älteren avr-libc-Versionen im Verhalten von den neuen. Oliver
Gast
#915683
Nachtrag: Da hab ich mich wohl falsch erinnert, zumindest bis 2005xxxx rückwärts gibts da immer einen reset. Oliver
Peter Dannegger wrote: > Oh Gott, das solln Bugreport sein? Mach's mal halblang, Peter. WinAVR hat naturgemäß sehr viele Nutzer, die bislang nicht mit Opensource und dort üblichen Vorgehensweisen vertraut sind. Daher wünscht sich Eric auch, dass WinAVR-Nutzer primär erst einmal Bugs bei WinAVR selbst aufmachen statt bei den im Hintergrund benutzten Tools selbst. Wenn sich dabei Bugs in den eigentlichen Tools ergeben, kann man auf diese Weise die notwendigen Details erst einmal beschaffen, um danach dann einen fundierten Bugreport für das jeweilige Tool daraus zu generieren. > Kein Wunder, daß er sich nicht traut, den hier zu posten. Wilhelms Auftreten hier finde ich teilweise auch etwas überheblich, aber euer Verhalten erinnert auch eher an Rüsseltiere im Porzellan- laden. Mit solchen Sprüchen wirst Du Wilhelm kaum dazu bringen, hier konstruktiver zu agieren. > Und einen Reset macht die CPU auf keinen Fall, wenn nicht der Watchdog > enabled ist. Ein Rücksprung auf Adresse 0 kann aber bei inkorrektem Inline-Asm-Code schon einmal passieren, und die EEPROM-Funktionen sind in der aktuellen avr-libc aus diversen Gründen neu geschrieben worden. Mir wäre ein nachvollziehbares Beispiel natürlich auch lieber, aber das Mindeste wäre erst einmal die Angabe des CPU-Typs.
Gast
#915697
>aber das Mindeste wäre erst einmal die Angabe des CPU-Typs.
Der ist ja inzwischen bekannt, ein Mega128.
Oliver
Oliver wrote: > Neben dem Watchdog kann es auch ein Interrupt ohne ISR sein. Naja, nicht als Reset, sondern als Sprung auf Adresse 0, aber der Unterschied ist nur wahrnehmbar, wenn man sich den Status der IO-Register ansieht. > Wenn ich > mich richtig erinnere, unterscheiden sich da tatsächlich die älteren > avr-libc-Versionen im Verhalten von den neuen. Nö, das hat sich nicht geändert. Es wurde darüber diskutiert, ob man vielleicht standardmäßig einen RETI machen sollte, aber das würde ja den Programmierfehler nur kaschieren. Je nachdem, welche ISR es ist, würde dadurch der Fehler u. U. unbemerkt bleiben, aber selbst eine Endlosschleife der CPU ist denkbar (bspw. bei einem UART-Interrupt).
Da das Problem nach wie vor noch ansteht und auch der Bugreport noch immer nicht behandelt wurde habe ich heute mir mal die Listings angesehen. Dabei sind mir folgende Sachen unklar aufgefallen. Also wir sind immer noch beim Thema WinAVR 2006 funktionier und 2008 mit dem selben Sourccode mit EEPromzugriff nicht. 2006: 00000afc <__eeprom_read_byte_1C1D1E>: afc: e1 99 sbic 0x1c, 1 ; 28 afe: fe cf rjmp .-4 ; 0xafc <__eeprom_read_byte_1C1D1E> b00: bf bb out 0x1f, r27 ; 31 b02: ae bb out 0x1e, r26 ; 30 b04: e0 9a sbi 0x1c, 0 ; 28 b06: 11 96 adiw r26, 0x01 ; 1 b08: 0d b2 in r0, 0x1d ; 29 b0a: 08 95 ret und 2008: 0000039a <eeprom_read_byte>: /** \ingroup avr_eeprom Read one byte from EEPROM address \a __p. */ _ATTR_PURE__ static __inline_ uint8_t eeprom_read_byte (const uint8_t *__p) { 39a: df 93 push r29 39c: cf 93 push r28 39e: 00 d0 rcall .+0 ; 0x3a0 <eeprom_read_byte+0x6> 3a0: cd b7 in r28, 0x3d ; 61 3a2: de b7 in r29, 0x3e ; 62 3a4: 9a 83 std Y+2, r25 ; 0x02 3a6: 89 83 std Y+1, r24 ; 0x01 do {} while (!eeprom_is_ready ()); 3a8: ec e3 ldi r30, 0x3C ; 60 3aa: f0 e0 ldi r31, 0x00 ; 0 3ac: 80 81 ld r24, Z 3ae: 88 2f mov r24, r24 3b0: 90 e0 ldi r25, 0x00 ; 0 3b2: 82 70 andi r24, 0x02 ; 2 3b4: 90 70 andi r25, 0x00 ; 0 3b6: 00 97 sbiw r24, 0x00 ; 0 3b8: b9 f7 brne .-18 ; 0x3a8 <eeprom_read_byte+0xe> #if E2END <= 0xFF EEARL = (unsigned)__p; #else EEAR = (unsigned)__p; 3ba: ee e3 ldi r30, 0x3E ; 62 3bc: f0 e0 ldi r31, 0x00 ; 0 3be: 89 81 ldd r24, Y+1 ; 0x01 3c0: 9a 81 ldd r25, Y+2 ; 0x02 3c2: 91 83 std Z+1, r25 ; 0x01 3c4: 80 83 st Z, r24 #endif EECR |= (1 << EERE); 3c6: ac e3 ldi r26, 0x3C ; 60 3c8: b0 e0 ldi r27, 0x00 ; 0 3ca: ec e3 ldi r30, 0x3C ; 60 3cc: f0 e0 ldi r31, 0x00 ; 0 3ce: 80 81 ld r24, Z 3d0: 81 60 ori r24, 0x01 ; 1 3d2: 8c 93 st X, r24 return EEDR; 3d4: ed e3 ldi r30, 0x3D ; 61 3d6: f0 e0 ldi r31, 0x00 ; 0 3d8: 80 81 ld r24, Z } 3da: 0f 90 pop r0 3dc: 0f 90 pop r0 3de: cf 91 pop r28 3e0: df 91 pop r29 3e2: 08 95 ret Was mir als erstes auffällt ist die Codegröße. Aber die stört mich eigentlich nicht wirklich. Vielmehr frage ich mich bereits bei den ersten zwei Zeilen wer oder was holt die CPU aus der von mir interpretierten Endlosschleife??? Muss aber dazu sagen dass die Programme klaglos arbeiten. Bei der Version WinAVR 2008 (letzte Ausgabe) frage ich mich was die Zeile mit "3ae: 88 2f mov r24, r24" an dieser Stelle für einen Sinn hat. Des weiteren frage ich mich warum die Register R30 und R31 benutzt werden ohne sie vorher gesavet zu haben. Als Draufgabe frage ich mich auch noch warum am Ende der Routine zweimal zum Register R0 gepopt wird. Stimmt denn da danach der Stackpointer noch??? Sofern ich hier nichts falsch verstanden habe, würde ja dies alles mir Erklären warum es zum Nichtfunktionieren der Programme führt.
Gast
#955939
> Was mir als erstes auffällt ist die Codegröße. Das zweite (lange) Beispiel ist ohne Optimierung kompiliert worden. Da treten dann mitunter "NOPs" wie MOV R24,R24 auf. Das sieht beim "alten" Compiler auch nicht viel anders aus. > Vielmehr frage ich mich bereits bei den ersten zwei Zeilen wer oder > was holt die CPU aus der von mir interpretierten Endlosschleife??? Du meinst die im ersten Beispiel? SBIC ist ein bedingter Sprungbefehl, der aus der Schleife herausführt.
Ups..., da habe ich mir als Legastheniker selbst ein Ei gelegt. SBCI != SBIC. Ganz klar. Allerdings unbegreiflich wie das mir nur passieren konnte. ;-) Dabei habe ich ja noch dazu 10 Min. (dumm) herumgerätselt obwohl ja der Kode gut läuft. Naja, war halt ein Bier zuviel. Aber freut mich dass du dich trotzdem damit beschäftigt hast. Das eigentliche Problem ist aber dass der selbe Sourccode und auch jedweder Neue mit Versionen nach 2006 nicht mehr lauffähig ist. Dazu habe ich auch ein Demo im Bugreport mitangehängt. Also ganz einfach den Maschinenkode (srec) in einen ATmega128 laden und sehen was passiert. Auf Wunsch kann ich auch jederzeit den selben Kode mit der 2006er Version zur Verfügung stellen. Nur damit man eben sieht dass er auch funktioniert (kann). ;-) Ps.: Optimierung ist bei mir immer ausgeschalten. Was ich programmiere möchte ich ja auch haben und nicht mehr oder weniger.
Gast
#956004
>Auf Wunsch kann ich auch jederzeit den selben Kode mit der 2006er >Version zur Verfügung stellen. Nur damit man eben sieht dass er auch >funktioniert (kann). ;-) Viel hilfreicher wäre ein Beispiel im Source-Code. >Optimierung ist bei mir immer ausgeschalten. Was ich programmiere möchte >ich ja auch haben und nicht mehr oder weniger. Dann solltest du aber direkt in Assembler programmieren. Da hast du dann die volle Kontrolle. Das, was der gcc (oder irgend ein anderer C-Compiler) produziert, ist, egal, ob mit oder ohne Optimierung, selten das, was man von Hand programmiert hätte. Trotzdem funktioniert es. Oliver
Das Demo gibt es ja im Bugreport von mir auf der Souceforgseite herunter zu laden. Mein Zusatzangebot bezieht sich darauf wenn einer ein lauffähiges 2006er-File haben möchte. Um den Bootloader braucht sich auch keiner Sorgen zu machen. Im gesamten Projekt sind Source, Listungs, Hex und Srec-Files vorhanden. Also im Prinzip alles was man zum Nachvollziehen braucht. Wer ein persöhnliches Demo haben möcht wird natürlich auch bedient werden. Ich verarbeite so ca. zwischen 1800 und 2500 128er pro Jahr. Da sind rund 30 verschiedene Applikationen. Dass WINAVR nicht für den kommerziellen Gebrauch vorgesehen ist, mindert meine "Reklamation" aber sicher auch nicht. Ich bin es vielleicht nur nicht gewohnt etwas was "open source" ist so abwickeln zu müssen. Da ich selbst natürlich nicht unfehlbar bin, nehme ich auch Hinweise betreffend einer etwaigen Fehlnutzung gerne entgegen. Es ist also ohne weiteres möglich dass bei mir selbst ein Unsinn entsteht. Ob die Versionen nach 2006 funktionieren oder nicht, berührt mich in erster Linie nur deswegen weil ein Teil meiner Rechner mit VISTA arbeiten und die WINAVR 2006er Version dort als Entwicklungsumgebung nicht läuft. Aber selbst wenn ich eine 2007er oder 2008er Version auf XP installiere kommt nur Buggycode heraus. Also beschränken wir uns bitte darauf dass ein und der selbe Sourccode der auf 2006 lauffähig ist mit einer 2007er und einer 2008er Version nicht mehr funktioniert. Bei der 2007er habe ich zB. keine PSTR verwenden können. Da wurde wild im Speicher herumgelesen. Bei der 2008er funktionieren die PSTR zwar wieder, aber dafür habe ich das Problem auf ungerade Adressen im EEProm zuzugreifen. Heute Mittag habe ich mir nach langer Zeit mal einige Minuten dafür gewidmet und eben mal einen Kodevergleich durchgeführt. Also Grund genug hier wieder einen Post abzusetzen.
Wilhelm Stejskal wrote: > und 2008: > 0000039a <eeprom_read_byte>: > > /** \ingroup avr_eeprom > Read one byte from EEPROM address \a __p. > */ > _ATTR_PURE__ static __inline_ uint8_t eeprom_read_byte (const uint8_t > *__p) > { > 39a: df 93 push r29 > 39c: cf 93 push r28 > 39e: 00 d0 rcall .+0 ; 0x3a0 > <eeprom_read_byte+0x6> > 3a0: cd b7 in r28, 0x3d ; 61 > 3a2: de b7 in r29, 0x3e ; 62 > 3a4: 9a 83 std Y+2, r25 ; 0x02 > 3a6: 89 83 std Y+1, r24 ; 0x01 > do {} while (!eeprom_is_ready ()); > 3a8: ec e3 ldi r30, 0x3C ; 60 > 3aa: f0 e0 ldi r31, 0x00 ; 0 > 3ac: 80 81 ld r24, Z > 3ae: 88 2f mov r24, r24 > 3b0: 90 e0 ldi r25, 0x00 ; 0 > 3b2: 82 70 andi r24, 0x02 ; 2 > 3b4: 90 70 andi r25, 0x00 ; 0 > 3b6: 00 97 sbiw r24, 0x00 ; 0 > 3b8: b9 f7 brne .-18 ; 0x3a8 <eeprom_read_byte+0xe> > #if E2END <= 0xFF > EEARL = (unsigned)__p; > #else > EEAR = (unsigned)__p; > 3ba: ee e3 ldi r30, 0x3E ; 62 > 3bc: f0 e0 ldi r31, 0x00 ; 0 > 3be: 89 81 ldd r24, Y+1 ; 0x01 > 3c0: 9a 81 ldd r25, Y+2 ; 0x02 > 3c2: 91 83 std Z+1, r25 ; 0x01 > 3c4: 80 83 st Z, r24 > #endif > EECR |= (1 << EERE); > 3c6: ac e3 ldi r26, 0x3C ; 60 > 3c8: b0 e0 ldi r27, 0x00 ; 0 > 3ca: ec e3 ldi r30, 0x3C ; 60 > 3cc: f0 e0 ldi r31, 0x00 ; 0 > 3ce: 80 81 ld r24, Z > 3d0: 81 60 ori r24, 0x01 ; 1 > 3d2: 8c 93 st X, r24 > return EEDR; > 3d4: ed e3 ldi r30, 0x3D ; 61 > 3d6: f0 e0 ldi r31, 0x00 ; 0 > 3d8: 80 81 ld r24, Z > } > 3da: 0f 90 pop r0 > 3dc: 0f 90 pop r0 > 3de: cf 91 pop r28 > 3e0: df 91 pop r29 > 3e2: 08 95 ret > > > Bei der Version WinAVR 2008 (letzte Ausgabe) frage ich mich was die > Zeile mit "3ae: 88 2f mov r24, r24" an dieser Stelle für einen > Sinn hat. Hier wurde ein trivialer MOV nicht wegoptimiert. Der MOV mag im asm-Code trivial sein, die Behandlung im Compiler ist es aber mitunter nicht... > Des weiteren frage ich mich warum die Register R30 und R31 > benutzt werden ohne sie vorher gesavet zu haben. R30 und R31 sind call clobbered in der avr-gcc ABI, d.h. der Compiler darf dieser Register in einer Funktion ändern ohne sie zu sichern/wieder herzustellen. > Als Draufgabe frage ich > mich auch noch warum am Ende der Routine zweimal zum Register R0 gepopt > wird. Stimmt denn da danach der Stackpointer noch??? Ja. Die zwei POP gehören zum trivialen RCALL .+0, der wohl auf einen geinlinten indirekten Call zurückgeht. Der indirekte Call ist auch der Grund für den Codezuwachs im Vergleich zur 3.4.x.; ist für die avr-libc-Leute aber wohl bequemer... Die Fehlfunktion des besagten Codes beruht auf Nichtbefolgung der EEPROM Schreib-Sequenz, siehe Handbuch -> AVR Memories -> EEPROM read/write access. Der Zugriff auf die SFRs darf nicht in C implementiert werden, weil das keinen spezifizierten Code erzeugt. Der Zugriff muss in (Inline)-Assembler ausgetextet werden.
Danke für deine Antwerten. Schlüssig zum begreifen sind sie aber teilweise nicht für mich. Möchte aber auch gleich dazu sagen dass deine kritischen Bemerkungen nur an die Entwickler der AVR-Lib gerichtet sein können. Denn ich benutze ja lediglich nur ihre dafür vorgesehenen Funktionen wie eben die eeprom_read_byte. Also was du da siehst ist rein nur der Kode der aus der Lib kommt. Die Funktionen zur Nutzung des EEProms sind im Datenblatt klar erklärt und auch mit einem Beispiel versehen. 2006 hatte man ja diese auch fast 1:1 übernommen und sie funktionieren. Dass das nun eher cryptisch abläuft ist halt schon verwunderlich. Noch dazu scheint hier auch der Grund der Probleme begraben zu sein. Im Gegensatz zu anderen mCs habe ich bei den 128ern noch keine einzige Zeile, mit Ausnahme eines InlineNOP, als Assemblerkode geschrieben. Daher bin ich gerade erst dabei mir den CPU-Kode anzusehen. Um so mehr bin ich geschockt wenn der Copiler Register benutzt die nicht gesaved wurden. Da stelle ich mir vor was passiert wenn ich in die C-Source Assemblerteile miteinfüge in denen ich diverse Register nutze und dazwischen die eeprom_read_byte nutze. Also bei anderen Toolchains wie zB. für Hitachi, welche teilweise auch auf Basis von GCC arbeiten, konnte ich immer darauf vertrauen dass alle Register save sind. Gibt's da vielleicht eine Doku dazu? Woher hast du denn das Insiderwissen her? Wie sieht denn das mit diesen Zeilen aus? 3a0: cd b7 in r28, 0x3d ; 61 3a2: de b7 in r29, 0x3e ; 62 3a4: 9a 83 std Y+2, r25 ; 0x02 3a6: 89 83 std Y+1, r24 ; 0x01 Wird denn da nicht der WERT von 0x3d (EEDR) ins Y-Reglow und der WERT von 0x3e (EEARL) ins Y-Reghigh geschrieben? Für mich sieht's im Moment so aus als würde man dann gleich danach je nach Inhalt der Portadresse wild irgendwo hinein schreiben. Also überall hin nur nicht auf die EEProm-Adressregister. Aber wer weiß, vielleicht wird der in-Befehl auch als immediat interpretiert ;-). Ich kann's mir zwar nicht vorstellen, aber wer weiß? Die Meinung dass SFR-Register in C nicht genutzt werden dürfen habe ich einerseits nirgens gelesen und andererseits seit Jahren keine negativen Erfahrungen gemacht. Gibt ja auch extra Headerdatein dafür. Sollte daher der preprocessor auch richtig handlen können. Dass Lib-Funktionen natürlich nur in Assembler zu schreiben sind ist auch klar. Da gebe ich dir natürlich recht. Aber als Anwender darf mich das nicht berühren müssen.
Wilhelm Stejskal wrote: > Die Meinung dass SFR-Register in C nicht genutzt werden dürfen habe ich > einerseits nirgens gelesen und andererseits seit Jahren keine negativen > Erfahrungen gemacht. Hat ja auch gar niemand behauptet ;) > Gibt ja auch extra Headerdatein dafür. EBEN. Und diese müssen benutzt werden. Das ist, was Johann meinte. Sollte daher > Dass Lib-Funktionen > natürlich nur in Assembler zu schreiben sind ist auch klar. Funktionen aus Bibliotheken können entweder in Assembler oder in C (oder beliebig) geschrieben sein, nur werden diese dann kompiliert und somit in Binärcode/Maschinencode umgewandelt (und nicht in Assembler. Das ist was anderes) AKA kompiliert.
Nein, BITTE nicht solche Posts. Das führt zu nichts. Bleiben wir bitte schlicht beim Problem und polemisieren wir nicht. Kostruktive Antworten sind gefragt. Sonst nichts. Ich stehe hier allein gegen den Rest der Welt. Bin mir in dieser Position also vollkommen im Klaren. Meine "Vorwüfe" sind also rein durch Aufklärung mir gegenüber zu beseitigen oder sie sind berechtigt und dann muss vom Team her eine Lösung gefunden werden. Wie ich mir aus der Lage vielleicht heraushelfen kann weiß ich selbst. Also die "guten Ratschläge" suche ich nicht. Ich hätte lieber kongrete Antworten auf meine Fragen die mein verloren gegangenes Vertrauen auf WINAVR wieder herstellen. Möchte euch damit aber nicht beleidigen!!! Bei mir geht's nicht ums Hobby.
Wilhelm Stejskal wrote: > Danke für deine Antwerten. > > [...] Denn ich benutze ja > lediglich nur ihre dafür vorgesehenen Funktionen wie eben die > eeprom_read_byte. Also was du da siehst ist rein nur der Kode der aus > der Lib kommt. Wenn die C-Kommentare aus dem Listing aus der avr-libc kommen, dann ist das ein Bug. Bzw der Bug ist im C-File, aus dem erzeugt wurde. Selbst wenn ohne Optimierung übersetzt wurde, muss ein Compiler korrekten Code machen. Wie gesagt, der Fehler ist hier nicht im Compiler selbst, es werden aber offenbar Implikationen an den Compiler gemacht, die nicht (immer) zutreffen, und die nirgends niedergeschrieben sind, auch nicht im C-Standard. > Die Funktionen zur Nutzung des EEProms sind im Datenblatt > klar erklärt und auch mit einem Beispiel versehen. 2006 hatte man ja > diese auch fast 1:1 übernommen und sie funktionieren. Dass das nun eher > cryptisch abläuft ist halt schon verwunderlich. Noch dazu scheint hier > auch der Grund der Probleme begraben zu sein. Unerfreulich, sicher. Aber bis sich da was tut... > Um so mehr bin ich geschockt wenn der > Copiler Register benutzt die nicht gesaved wurden. Da stelle ich mir vor > was passiert wenn ich in die C-Source Assemblerteile miteinfüge in denen > ich diverse Register nutze und dazwischen die eeprom_read_byte nutze. Der Compiler ist Herr der GPRs, nicht Du. Wenn Du nicht willst, daß irgendwer ausser Dir die GPRs verwaltet, dann ist Assembler Dein Freund. Wenn der Compiler am Werk ist, muss er über jede GPR-Änderung informiert werden. Hierzu gibt es Dokus zu Inline-Assembler. Aber selbst mit Inlnie-Assembler ist es nicht ratsam, explizit bestimmte GPRs zu verwenden. Bei Verwendung von Assembler musst Du ebenfalls die ABI beachten. > Also bei anderen Toolchains wie zB. für Hitachi, welche teilweise auch > auf Basis von GCC arbeiten, konnte ich immer darauf vertrauen dass alle > Register save sind. Für manche Toolchains mag das sein, aber die ABI richtet sich nach dem µC und was sinnvoll ist darauf zu tun, zudem ist sie compilerabhängig. Auf jedem µC immer alle GPRs zu sichern ist nicht sinnvoll. Für AVR bekäme man deutlich schlechteren Code. > Gibt's da vielleicht eine Doku dazu? http://www.roboternetz.de/wissen/index.php/Avr-gcc/Interna#Registerverwendung http://www.roboternetz.de/wissen/index.php/Inline-Assembler_in_avr-gcc Sowie hier auf der Seite und in Deiner avr-libc-Doku, dort aber in Englisch. > Woher hast du denn das Insiderwissen her? Compilerbau (gcc). > Wie sieht denn das mit diesen Zeilen aus? > > 3a0: cd b7 in r28, 0x3d ; 61 > 3a2: de b7 in r29, 0x3e ; 62 > 3a4: 9a 83 std Y+2, r25 ; 0x02 > 3a6: 89 83 std Y+1, r24 ; 0x01 > > Wird denn da nicht der WERT von 0x3d (EEDR) ins Y-Reglow und der WERT > von 0x3e (EEARL) ins Y-Reghigh geschrieben? Für mich sieht's im Moment > so aus als würde man dann gleich danach je nach Inhalt der Portadresse > wild irgendwo hinein schreiben. Hier wird eine lokale 16-Bit-Variable (in r25:r24) im Frame der Funktion abgelegt. Y ist der Framepointer in der avr-gcc ABI. Für einfache Funktionen wird kein FP benötigt und Y kann für normale Daten verwendet werden. Wenn der FP benötigt wird, dann wird er in Y gehalten und die meisten lokalen Variablen leben im Frame der Funktion und nicht in GPRs. Das ist zB ohne Optimierung der Fall (-O0) oder wenn eine lokale Variable volatile ist, oder wenn eine lokale Struktur/Union ne krumme Größe hat oder zu groß ist, oder eben wenn es zu viele lokale Variablen gibt, als daß sie alle in GPRs verwaltet werden können. > Die Meinung dass SFR-Register in C nicht genutzt werden dürfen habe ich > einerseits nirgens gelesen und andererseits seit Jahren keine negativen > Erfahrungen gemacht. Habe ich nie behauptet. Natürlich kann man von C aus GPRs verwenden und es ist gängige Praxis. Allerdings kann man damit keine definierten Code-Sequenzen erzeugen, wie sie im vorliegenden Fall nötig wären.
1 | |
2 | |
Wenn SFR1 und SFR2 Zeiger auf volatile sind, so wie sie etwa über die avr/io.h et. al. definiert werden, bewirkt der C-Code, daß SFR1/SFR2 auf jeden Fall mit foo/bar in dieser Reihenfolge genau einmal beschrieben werden. So weit, so gut. Aber es steht nirgends geschrieben, daß die beiden Zuweisungen direkt hintereinander erfolgen müssen (der Compiler könnte und dürfte zwischen den Anweisungen zB ein Reload machen, wenn er den braucht). Wenn bar etwa eine Variable ist, die im Frame lebt, dann wäre der erzeugte Code ziemlich sicher äquivalent zu
1 | |
2 | |
3 | |
Gleiches kann der Fall sein, wenn bar eine Konstante ist, die erst geladen werden muss, etwa durch einen späten Reload im greg-Pass von gcc. Des weiteren sagen die C-Zeilen nix darüber aus, wie der Zugriff erfolgt, also ob er direkt oder indirekt geschieht. Zeilen wie
1 | |
2 | |
führen entgegen weit verbreiteter Meinung (auch die Optimerungs-Tipps dieser Seite enthalten die falsche Aussage, dies führe zu indirektem Zugriff) nicht zum gewünschten Code, sondern avr-gcc "optimert" das zu
1 | |
> Gibt ja auch extra Headerdatein dafür. Die freilich richtig angewandt werden müssen (das gilt auch, wenn die libc der "Anwender" ist" ;-)) > Dass Lib-Funktionen > natürlich nur in Assembler zu schreiben sind ist auch klar. Nein, es gibt auch C-libs wie die libc oder die libm. Aber es gibt auch asm-Bibliotheken wie der libgcc2. Und Inline-Assembler wird man natärlich nicht in einer asm-Bibliothek finden ;-) Hier geht es wie gesagt darum, daß eine spezielle Sequenz eingehalten werden muss. Das geht nur in (Inline)-Assembler. Zudem müssen IRQs deaktiviert werden, damit die definierte Sequenz nicht unterbrochen werden kann.
Nochwas: Diese Sequenz muss nur beim Schreiben eingehalten werden. Beim Lesen siehts anders aus, d.h. es ist eintgegen meiner vorschnellen Aussage kein Bug in der avr-libc.
Danke für deine qualifizierte Antwort. Dass man mit dem leben muss was vorhanden ist, ist klar. Bitte auch um Entschuldigung des von mir falsch verstanden Teils bezüglich der SFRs in C. Danke auch für die weiterführenden Links. Wenn ich dich aber schon an der Angel habe, ich hoffe du bist mir darüber jetzt nicht böse, möchte ich dich bitten mal meine beiden Bugreports bezüglich des Themas bei Souceforge anzusehen. Mein geposteter Auszug aus dem compiliten Listig samt c-Source sind dort komplet vorhanden. Deine aussagen bestätigen nähmlich meine Meinung dass es sich ja auch tatsächlich um einen echten Bug handelt. Ist halt nur schwer eben hier alleine dazustehen. Möglicher Weise trage ich ja selber Schuld in meiner vielleicht naiven Art etwas aufzeigen zu wollen, was bis Dato seltsamer Weise noch niemanden aufgefallen ist. Wenn die Funktionen, welche bisher zur Benutzung des EEProms nunmehr keine Gültigkeit haben dann sollten sie aber auch nicht mehr nutzbar sein. Egal wie auch immer, bitte tu mir den Gefallen und schaue dir die C-Source an und lade eventuel den Output des Compilats in einen 128er. Serielle Schnittstelle 0 müsste dazu allerdings vorhanden sein. Naja, wenn du die Source liest, dann ist ja sowieso alles klar. Der zu erwartende Effekt ist, dass nach dem Lesen an einer ungeraden Adresse im EEProm die "Einschaltmeldung" immer wieder kommt. Würde das Programm normal und richtig ablaufen, also so wie es aus der Toolchain 2006 herauskommt, dann würden nur jeweils einmal die Texte für geraden adresszugriff und ungeraden Adresszugriff ausgegeben werden. Danach erscheinen immer nur zeitverzögert '+'-Zeichen. Nochmals besten Dank für dein Gehör. Gruß Willi Ps.: Ohne dir hier gleich zu nahe treten zu wollen biete ich auch eine direkte Kommunikation per Email, Skype oder Telefon an. Geht mir eben nur um eine saubere Lösung des Problems. Email: w.stejskal@wiste.at Skype: w.stejskal (nach Vereinbarung) Telefon: Ich rufe zurück.
Gast
#957429
>Nochwas: Diese Sequenz muss nur beim Schreiben eingehalten werden. Beim >Lesen siehts anders aus, d.h. es ist eintgegen meiner vorschnellen >Aussage kein Bug in der avr-libc. Damit sind wir wieder am Anfang. >Würde das Programm >normal und richtig ablaufen, also so wie es aus der Toolchain 2006 >herauskommt, dann würden nur jeweils einmal die Texte für geraden >adresszugriff und ungeraden Adresszugriff ausgegeben werden. Danach >erscheinen immer nur zeitverzögert '+'-Zeichen. Im Simulator (VMLAB) tut es das. Sowohl mit WinAVR 20072112, als auch mit 20080610 (ohne deinen bootloader). Das muß jetzt noch nicht bedeuten, daß da nicht doch irgend ein Timing durcheinander geht, aber prinzipiell funktioniert der Code. >Bei der 2007er habe ich zB. keine PSTR >verwenden können. Da wurde wild im Speicher herumgelesen. Gibt es dafür auch ein Beispiel? Oliver
Johann L. wrote: > Wilhelm Stejskal wrote: >> Wie sieht denn das mit diesen Zeilen aus? >> >> 3a0: cd b7 in r28, 0x3d ; 61 >> 3a2: de b7 in r29, 0x3e ; 62 >> 3a4: 9a 83 std Y+2, r25 ; 0x02 >> 3a6: 89 83 std Y+1, r24 ; 0x01 >> >> Wird denn da nicht der WERT von 0x3d (EEDR) ins Y-Reglow und der WERT >> von 0x3e (EEARL) ins Y-Reghigh geschrieben? Für mich sieht's im Moment >> so aus als würde man dann gleich danach je nach Inhalt der Portadresse >> wild irgendwo hinein schreiben. > > Hier wird eine lokale 16-Bit-Variable (in r25:r24) im Frame der Funktion > abgelegt. Y ist der Framepointer in der avr-gcc ABI. Für einfache > Funktionen wird kein FP benötigt und Y kann für normale Daten verwendet > werden. Wenn der FP benötigt wird, dann wird er in Y gehalten und die > meisten lokalen Variablen leben im Frame der Funktion und nicht in GPRs. > Das ist zB ohne Optimierung der Fall (-O0) oder wenn eine lokale > Variable volatile ist, oder wenn eine lokale Struktur/Union ne krumme > Größe hat oder zu groß ist, oder eben wenn es zu viele lokale Variablen > gibt, als daß sie alle in GPRs verwaltet werden können. Ja, das ist klar. Aber was ich meine ist, dass der IN-Befehl den Inhalt der Adresse 0x3d bzw. 0x3e liest und in Y-Low bzw. Y-High ablegt. Das bedeutet dass je nach dem welchen Inhalt die beiden Adressen hatten gleich danach mit std Y+2 und std Y+1 geschrieben wird. Da der Inhalt von 0x3d und 0x3e unbestimmt sind, behaupte ich dass hier wild im Speicher geschrieben wird. Meines Erachtens ist hier der in-Befehl der falsche Befehl. Richtiger müsste diese Sequenz so aussehen: ldi r28, 0x3d ; Die Adresse von EEDR clr r29 std Y+1, r24 ; Die Low-Adresse des gewünschten EEPrombytes ins EEARL schreiben std Y+2, r25 ; Die Hi-Adresse des gewünschten EEPrombytes ins EEARH schreiben @ Oliver Hast du dafür neu compiliert oder hast du das fertige Hex oder SREC-File im Simulator laufen lassen? Sei doch mal so nett und poste die Sequenz der eeprom_read_byte aus dem .LSS File nach dem du mit "deiner" Version 2008 und 2007 compiliert hast. Optimierung aber dazu ausschalten!
Gast
#957479
Ich habe es neu compiliert. Allerdings kommt für 20080610 der gleiche Code raus, wie bei dir. Unterschiede gibt es nur bei den debug-Infos und ein paar Blanks/CRs. Beide .lss-Files habe ich angehängt. Oliver
Wilhelm Stejskal wrote: > Ja, das ist klar. Aber was ich meine ist, dass der IN-Befehl den Inhalt > der Adresse 0x3d bzw. 0x3e liest und in Y-Low bzw. Y-High ablegt. Das > bedeutet dass je nach dem welchen Inhalt die beiden Adressen hatten > gleich danach mit std Y+2 und std Y+1 geschrieben wird. Da der Inhalt > von 0x3d und 0x3e unbestimmt sind, behaupte ich dass hier wild im > Speicher geschrieben wird. Nein, der Inhalt von 0x3d und 0x3e ist nicht unbestimmt, in diesen beiden Registern liegt der Stack-Pointer. Bedenke, dass IN eine IO-Adresse erwartet, nicht eine Memory-Mapped-Adresse. Ist natürlich schon ein verwirrender Zufall, dass unter den gleichen Adressen (aber Memory-Mapped) zwei EEPROM-Register liegen.
Danke. Bitte poste auch noch die HEX-Files. Dann kann ich den Kode mal in eines der Bords laden und sehen wie es läuft.
Danke Stefan. Damit steht das wieder in einem anderen Licht und ist somit abgehakt.
Gast
#957527
Hexfiles anbei. Das 2008er ist identisch zu deinem. Oliver
Gast
#957660
Nachtrag: Das 2007er hex wird sich um ein paar byte von deinem unterscheiden. Das hängt mit VMLAB zusammen (das mag eine ganz bestimmte Befehlsfolge nicht, die daher im hex-file geändert wird), und hat auf die Funktion keinen Einfluß. Oliver
Dsnke für die Files. Die 2007er läuft und die 2008er nicht. Die 2007er Toolchain habe ich nicht mehr gefunden. Wurde bei mir warscheinlich aufgrund des damaligen Misserfolgs gleich wieder gelöscht. Ist aber egal. Weil ich möchte ja dass die 2008er läuft.
@Wilhelm: So wie Oliver schreibt funktioniert der Code im Simulator, und der erzeugte Code für den EEPROM-Zugriff ist auch ok. Du greifst direkt nach dem Reset aufs EEPROM zu. Hast Du denn die BrownOut-Erkennung aktiviert? Ansonsten funktioniert das EEPROM unzuverlässig, wenn der µC-Core schon anrollt, die VCC aber noch nicht sauber ist. Alternativ zum BOD kann man anfang von main zB 100ms warten, wenn der BOD zu viel Strom braucht. Aus diesem Grund hatte ich schon beim gleichen µC (anderes Exemplar, gleicher Typ, gleiches Produktionsdatum, gleiche Schaltung) unterschiedliches Verhalten beim EEPROM-Zugriff direkt nach nem PowerUp-Reset.
Ob BOD ein oder ausgeschaltet ist hat sichtlich keinen Einfluß. Außerdem habe ich auf der Programmierplatte ständig Strom und einen eigenen Resettaster. Es ist auch egal was ich wo im Sourcetext mache. Sobald ich eine EEPROMRoutine verwende ist es geschehen. Wohl gemerkt die selbe Source mit Version 2006 compiliert funktioniert und mit der 2008er nicht. Betrifft aber nicht nur das Demo sondern sämliche Programme die ich bisher geschrieben habe und auch alle von heute.
Das hier schon gesehen? http://savannah.nongnu.org/bugs/?23969 Dort stehen zumindest ein paar Workarounds.
Danke für den Link. Jedoch außer dem Titel sehe ich keinen beschreibenden Text??? Was muss ich machen um da heran zu kommen? Schätze zwar die Leute der "offenen Gemeinde", aber unsereinereins ist in dieser hinsicht vielleicht ein Dau. Muss ich da sonst noch was machen? Tja, die ganze Welt ist gegen mich. Nichts funktioniert... ;-) Vom Titel her fühle ich mich angesprochen. Letzte Nacht habe ich wieder experimentiert. Ich habe die C-Routine aus dem Datenblatt in einer meiner Sourcen werwendet. Das Ergebnis war das Gleiche. Im .lss-File sah ich die selbe, für mich eher cryptische Übersetzung, wie sie auch bei Verwendung der eeprom_read_byte entsteht. Mit Simulator und Debugger läuft alles "perfekt". Jedoch im Chip herrscht das Chaos. Schrittweise habe ich mich zum Absturz hinbewegt und bin darauf gekommen dass alles soweit funktioniert bis zum Zeitpunkt wo das Readbit gesetzt wird. Sobald dies geschieht macht die CPU einen "Reset". Assembler ist für mich eigentlich nicht unbekannt, aber im Fall AVR müsste ich noch etwas mehr Erfahrung sammeln. Ich habe mich da eben noch nie damit wirklich beschäftigt. War bisher auch nicht erforderlich. :-) Da ich erst in den letzen paar Stunden mal den simulavr und den insight in Betrieb genommen habe und dabei sich gleich 1000 neue Fragen aufgetan haben (im Fenster vom simulavr kommen lauter warnings und er zeigt lauter Adressen und Daten an die es nicht gibt, obwohl der insight es "richtig" anzeigt), kann ich nicht behaupten was ich alles vermute. Also zum debuggen bräuchte ich auch noch Hilfe oder jemanden der diese Symtome deuten könnte. :-) Zusammenfassend möchte ich aber immer darauf verweisen, dass unterschiedliche IDEs unterschiedlichen Erfolg bringen!!! Also 2006 funktioniert und 2008 nicht. Wenn mir einer sagen könnte wie die IDE 2006 auf Vista zum laufen zu bringen wäre, könnte ich mich über eine Zeit lang auch damit über Wasser halten bis es wieder eine stabile Lösung gibt.
> Jedoch außer dem Titel sehe ich keinen beschreibenden Text???
Ich schon. Hier der Text:
Hello,
in a project previously built with avr-libc before 1.6 eeprom access
through avr-libc worked fine.
After switching to avr-libc 1.6.x the controller resets when accessing
the eeprom through avr-libc methods.
This is caused by a thrown EE_READY interrupt from inside
eeprom_read_byte() function when EECR|(1<<EERE) value is stored to EECR,
although eeprom ready interrupt enable bit (EERIE) isn't set at all.
confusing
The corresponding isr body is not defined. Thus the mcu resets
(__bad_interrupt).
This problem only occurs after building with optimization level 0 or 1.
Testing platforms were ATmega64 and ATmega16.
Disabling interrupts globally before calling eeprom functions worked
around the problem, as well as defining empty ISR for EE_READY interrupt
or compiling with optimization level 2/3/s.
Meine Meinung dazu: Ich habe mir den Code auch noch mal angesehen und ich kann beim besten Willen nicht sehen, dass da etwas schief läuft. Es wird auch nicht durch fehlerhaften Code das EERIE-Bit versehentlich gesetzt. Also wird anscheinend ein Interrupt ausgelöst, obwohl EERIE nicht gesetzt ist, so dass der eigentliche Bug wohl im Chip liegt. Da der Optimierungslevel eine Rolle spielt, ist das Timing wohl der auslösende Faktor. Das Setzen von EERE zum "richtigen" Zeitpunkt löst wohl den Interrupt aus.
Stefan Ernst wrote: > Das hier schon gesehen? > http://savannah.nongnu.org/bugs/?23969 > > This is caused by a thrown EE_READY interrupt from inside > eeprom_read_byte() function when EECR|(1<<EERE) value is stored to EECR, > although eeprom ready interrupt enable bit (EERIE) isn't set at all. Ok, damit ist es ein Fehler in der avr-libc, weil sie einen bekannten und im Handbuch beschriebenen Silicon-Bug nicht umschifft: Auf EECR darf nicht mittels ST oder STS zugegriffen werden, (wahrscheinlich auch nicht über STD), sondern es muss via IN/OUT zugegriffen werden. Mit dem leeren EE_READY sollte das Problem erst mal aus der Welt sein, bis der nächste drüber stolpert und sich den Wolf sucht...
Johann L. wrote: > Ok, damit ist es ein Fehler in der avr-libc, weil sie einen bekannten > und im Handbuch beschriebenen Silicon-Bug nicht umschifft: > > Auf EECR darf nicht mittels ST oder STS zugegriffen werden, > (wahrscheinlich auch nicht über STD), sondern es muss via IN/OUT > zugegriffen werden. Kannst du mir dazu mal die Quelle angeben? Ich hatte nämlich schon nach Erratas gesucht, aber nichts dazu gefunden.
> Kannst du mir dazu mal die Quelle angeben? > Ich hatte nämlich schon nach Erratas gesucht, aber nichts dazu gefunden. Hat sich erledigt, mein Datasheet war nicht aktuell.
Stefan Ernst wrote: > Johann L. wrote: > >> Ok, damit ist es ein Fehler in der avr-libc, weil sie einen bekannten >> und im Handbuch beschriebenen Silicon-Bug nicht umschifft: >> >> Auf EECR darf nicht mittels ST oder STS zugegriffen werden, >> (wahrscheinlich auch nicht über STD), sondern es muss via IN/OUT >> zugegriffen werden. > > Kannst du mir dazu mal die Quelle angeben? > Ich hatte nämlich schon nach Erratas gesucht, aber nichts dazu gefunden. Gesehen in der ATmega64 Summary, Erratum #6, pp. 19 http://atmel.com/dyn/resources/prod_documents/2490S.pdf
D-A-N-K-E !!! Somit wäre ja einmal klar dass meine Bugmeldung eine Berechtigung hat. Traurig stimmt mich halt nur die Art wie man von manch anderen Leuten hier im Forum behandelt wird. Generell bin ich ja der Auffasung das Support über ein Forum nicht gut sein kann und in Wirklichkeit auch nicht gut ist. Auf eine gestellte Frage kommen meistens gleich mal irgendwelche Phrasendrescher daher und die eigentlich wirklich Wissenden halten sich im Hintergrund. Um das Prozedere zu überleben braucht starke Nerven. Siehe den Anfang meiner Geschichte. Keiner glaubt dir und alle halten dich für einen Trottel. Alle Trockenschwimmer posten. Keiner prüft wirklich mit Hardware. Wo doch gerade meine Reklamation eigentlich jeden ECHTEN Anwender auffallen müsste. Unverständlich ist mir auch der Umstand warum man vonder einst guten und vorallem wesentlich effizienteren Assemblerroutine auf eine generisch compilierte C-Routine in einer Lib umgestiegen ist. Diesen Bug stufe ich als schwerwiegend ein und erhoffe mir das er schnellstmöglich auch gepacht wird. Weil das Vertrauen zu dieser Toolchain hat bereits bei mir den Nullpunkt erreicht. Was kann ich in dieser Version sonst noch an Bugs erwarten??? Ist das denn alles nur Hobby und sportlicher Geist? Wenn jemand eine Libfunktion schreibt muss er sie doch auch physisch testen. Oder etwa nicht? Naja, scheinbar ist das halt nicht mehr Gang und Gebe. Eine Bitte hätte ich allerdings noch an euch Beide. Könntet ihr mir vielleicht noch erklären wie ich als Übergangslösung die eeprom_read_byte und alle anderen Ähnlichen Derivate substituieren kann. GCC ist in deln letzten drei Jahrzehnten derart komplex geworden sodass ich vor lauter Bäumen den Wald nicht mehr sehe. Ich kann mich noch daran erinnern dass es einen Switch gibt mit dem ich den Compiler bzw Linker veranlassen kann nicht die Libfunktion sondern eine selbstgeschriebene Routine unter dem selben Namen zu verwenden. Tät mich freuen wenn ihr mir da vielleicht auch noch helfen könntet. Nicht dass ihr jetzt glaubt ich wäre nur zu faul um all die Docs zu lesen. Nein, ich habe bloß nur fürchterlichen Stress weil mit dem Prob ein Haufen Arbeit liegen bleiben musste.
> Keiner glaubt dir und alle halten dich für einen Trottel. Es ist nun mal so, dass in (mindestens!) 999 von 1000 Fällen der Fehler im Programm liegt und nicht im Compiler oder der Lib. Da ist es völlig legitim, den Fehler zunächst im Programm zu vermuten und zu suchen. > Weil das Vertrauen zu dieser Toolchain hat bereits bei mir den > Nullpunkt erreicht. Du musst sie ja nicht benutzen, oder zwingt dich jemand? > Wenn jemand eine Libfunktion schreibt muss er sie doch > auch physisch testen. "Müssen" muss er gar nichts. Man kann auch nicht erwarten, dass er es unter allen denkbaren Rahmenbedingungen testet (bedenke, dass der Fehler bei eingeschalteter Optimierung nicht auftaucht, und "Optimierung ein" ist eigentlich der Normalfall). Open-Source lebt vom Mitmachen. Das betrifft nicht nur das Schreiben von Code, sondern auch (vielleicht in noch stärkerem Maße) das Testen und die Fehlersuche. > Eine Bitte hätte ich allerdings noch an euch Beide. Könntet ihr mir > vielleicht noch erklären wie ich als Übergangslösung die > eeprom_read_byte und alle anderen Ähnlichen Derivate substituieren kann. Der von mir verlinkte Bug-Report enthält mittlerweile eine gefixte eeprom.h. Einfach die in deiner WinAVR-Installation durch die gefixte ersetzen.
Ja, ist schon in Ordnung und ich kühle auch lagsam wieder ab. Hier auf dem Win2000-Rechner sehe ich auch den Text vom Link und habe die .h kopieren können. Vista mit IE7 ist auch ein Kapitel für sich. ;-) Ich werde heute Nacht noch mal einen Versuch starten und bis zum Wochenende ein wenig testen. Bedanke mich nochmals für eure Hilfe und möchte mich auch für meine Art entschuldigen. Ich bin halt den Umgang in der open source Gemeinde nicht gewohnt. Verspreche aber mich darin noch zu verbessern. Gruß Willi
Beitrag #5996430 wurde von einem Moderator gelöscht.
Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.