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
>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
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
>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...
>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.
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
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.
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.
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.
>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
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)
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.
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
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
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.
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.
> 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.
>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#Registerverwendunghttp://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
SFR1=foo;
2
SFR2=bar;
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
SFR1=foo;
2
x=bar;
3
SFR2=x;
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
type_t*v=&var;
2
v->x=0;
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
var.x=0;
> 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.
>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!
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.
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.
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