Hallo zusammen, wer verwendet den uC51-Compiler von Wickenhäuser? Was für Erfahrungen habt Ihr gemacht? Ist er zu empfehlen?
Warum muß es Wickenhäuser sein ? Ich verwende den SDCC und bin recht zufrieden damit.
@ Frank R. Der uC51-Compiler ist auf jeden Fall sehr zu empfehlen. Er hat einen sehr guten TCP/IP - Stack. Ist leicht zu händeln und liefert einen sehr kompakten Code. Der TCP/IP-Stack arbeitet mit DM9000E oder CS8900 bestens. Habe vorher Keil eingesetzt - uc51 gefällt mir aber besser. Ich kann ihn nur empfehlen.
Anfangs war ich auch sehr angetan vom yC51. Aber inzwischen habe ich drei massive Übersetzungsfehler entdeckt, die mich viele Stunden gekostet haben. Ich werde mir vermutlich, nachdem ja trotz Meldung an Wickenhäuser keine Updates gemacht werden, einen anderen zulegen.
@Sven Welche Übersetzungsfehler hast du entdeckt ? Vielleicht kannst du dazu etwas genaueres sagen.
@Rainer Lass mal folgendes laufen: void main(void) { short i,ii; i=6; i>>=1; ii=123; if (ii==2) ii=3; printf("i=%d",i); } Aber bitte keine Kürzungen machen. Alles genau so. Was für ein Ergebnis bekommst Du angezeigt?
@Sven, da ist ja gar keine Mainloop drin, d.h. das Main rennt Dir einfach hintenraus, völlig klar, daß da Blödsinn passieren muß. Main darf nie enden !!! Peter
Peter Dannegger wrote:
> Main darf nie enden !!!
Hängt vom Compiler ab, der SDCC macht für die '51er z.B. implizit eine
Endlosschleife, wenn du aus main returnst.
/Ernst
Nachtrag: avr-gcc macht das auch, für
1 | int main() { |
2 | return 0; |
3 | }
|
wird generiert: [ASM] ... Prolog, stack init, ... 00000052 <main>: 52: cf e5 ldi r28, 0x5F ; 95 54: d2 e0 ldi r29, 0x02 ; 2 56: de bf out 0x3e, r29 ; 62 58: cd bf out 0x3d, r28 ; 61 5a: 80 e0 ldi r24, 0x00 ; 0 5c: 90 e0 ldi r25, 0x00 ; 0 5e: 00 c0 rjmp .+0 ; 0x60 <_exit> 00000060 <_exit>: 60: ff cf rjmp .-2 ; 0x60 <_exit> [/ASM] Also auch eine schöne Endlosschleife
@Peter Welch sinniger Hinweis. Dann bau eben am Ende for(;;) ; ein. Jetzt zufrieden? Es geht nicht drum, ob das Programm angeblich irgendwohin springt (was es übrigens nicht tut), sondern daß es als Ergebnis "i=0" ausgibt. Und es muss "i=3" sein!! Und komm mir nicht mit "das hätte man auch einfacher programmieren können", denn ein Compiler muss genau mit diesem Quelltext zurechtkommen.
Und jetzt noch das Highlight: Wenn Du die Zeile if (ii==2) ii=3; aus meinem Beispiel rausnimmst, dann kommt tatsächlich "i=3" raus. Nur, die rausgenommene Zeile hat damit ja rein garnix zu tun!!
@Sven Ich kann das bestätigen, 3 kommt nur heraus wenn die Zeile if (ii==2) ii=3; herausgenommen ist. Benutze selten short, daher ist es mir noch nicht aufgefallen. Welchen anderen Probleme sind Dir noch aufgefallen ? Hat Herr Wickenhäuser schon irgendetwas dazu gesagt ? Gruß Rainer
Nachtrag: Wenn i global vorab als short deklariert gibts keine Probleme.
@Sven DerSchreckliche: Bei vorzeichenbehafteten Variablen sind Shifts nicht definiert. Aus dem C99-Standard: "These operators [gemeint sind u.a. die Shift-Operatoren] return values that depend on the internal representations of integers, and have implementation-defined and undefined aspects for signed types."
Sven DerSchreckliche wrote:
> ein. Jetzt zufrieden?
Es geht nicht darum, ob ich zufrieden bin, sondern daß man Code so
hinschreibt, daß er logisch richtig ist.
Und das nach dem Beenden des Main eine Endlosschleife aufgerufen wird,
steht in keinem C-Standard.
Hier wurden schon oft Fehler gesucht, die keine waren.
Nur weil der Fragesteller zu bequem war, Copy&paste zu bemühen, sondern
aus dem Gedächtnis was scheinbar Ähnliches elaboriert hatte.
Nochmal: Zeig doch einfach mal das Assemblerlisting.
Ich hab ja nur den Keil und der sollte es richtig machen.
Peter
@Peter Habe in mein Programm eingefügt : void mist(void) { short i,ii; i=6; i>>=1; ii=123; if (ii==2) ii=3; printf("i=%d",i); } 3 kommt nur heraus wenn if (ii==2) ii=3; fehlt. Das steht Assemblerlisting : .export _mist ; void mist(void) .hide .segment _mist_formal_near, size 0, fill, notext, sclass dram .segment _mist_local_near, size 0, fill, notext, sclass dram .sgraph _mist_formal_near, _mist_local_near, __mist .sgraph _mist_local_near, _printf_formal_near, __mist, 0 .segment _printf_formal_near, size 2, fill, notext, sclass dram .show .segment __mist _mist: ; void mist(void) .line "ed2hello.c" 226 3 mov R6,#0 mov R7,#6 ; variable 'i' assigned to register 'RW67' .line "ed2hello.c" 230 3 mov A,R6 mov C,ACC.7 rrc A mov R6,A mov A,R7 rrc A mov R7,A ; variable 'i' assigned to register 'RW45' .line "ed2hello.c" 232 3 mov R6,#0 mov R7,#123 ; variable 'ii' assigned to register 'RW67' .line "ed2hello.c" 233 7 mov A,R7 xrl A,#2 orl A,R6 jnz ?66 .line "ed2hello.c" 233 14 ?66: .line "ed2hello.c" 235 3 mov _printf_formal_near,R4 mov _printf_formal_near+1,R5 mov R6,#((?i68)>>8)&255 mov R7,#(?i68)&255 mov R4,#COS lcall _printf ret ; end of function mist ; used: R01234567 BR01234567 DPTR ACC PSW B
@Peter Also nochmals für Dich: es geht hier um den yc51 von Wickenhäuser. Und dieser yc51 macht am Ende der Main eine Endlosschleife. Außerdem war ich so frei und habe unnötigen Balast weggelassen. Anscheinend ist dieser Schritt für Dich zu viel. Sorry. Wozu bitte sollte ich hier das Assemblerlisting posten? Es geht hier um den Compiler. Der baut Mist. Das hat auch Rainer bestätigt. Glaubst Du im Ernst, ich kaufe einen Compiler, um dann hinterher den Assemblercode zu korrigieren? @Xenu Versuch doch mal ein Bißchen mitzudenken: Selbst wenn der Compiler irgendeinen Mist berechnen sollte, wieso kommt dann, wenn man die besagte Zeile weglässt, plötzlich das richtige Ergebnis raus? Der Compiler kann also Shifts auf vorzeichenbehaftete Variablen immer nur dann richtig ausführen, wenn 2 Zeilen später ein "If" weggelassen wird? Also, was soll dann Dein Beitrag? Und im Übrigen: Du kannst gerne statt "i>>=1;" dann auch "i/=2;" schreiben. Denn auch hier baut der Compiler den gleichen Mist!!
@Rainer Danke, daß Du es auch getestet hast. Inzwischen gibts auch von Herrn Wickenhäuser eine Antwort: "...also wir planen gegen Ende Januar eine neue Version rauszubringen. Vermutlich werden wir nicht alle Schwachstellen beheben können. Mal schau'n... Sie müssen bedenken, dass der uC/51 nur einen Bruchteil anderer Systeme kostet..." und speziell zu diesem Fehler: "...da scheint sich der Compiler (Optimierer) tatsächlich zu irren." Es tut mir Leid, aber wenn ich etwas kaufe, dann muss es funktionieren, völlig egal, wieviel es gekostet hat. Ich kann auch verstehen, daß man nicht alles testen kann. Aber wenn Fehler gefunden und deutlich beschrieben werden, dann sollte so schnell wie möglich dieser Fehler behoben werden. Eine Aussage "...Mal schaun" hilft mir da nicht! Auf die anderen von mir gemeldeten Fehler gab es u.a. die Mitteilung, daß ihm ähnliches auch schonmal aufgefallen war. Nur, wieso wurde das dann nicht behoben? Ich hoffe, daß diese Fehler schnellstens und gründlich behoben werden. Es wäre schade, wenn ich diesen ansich doch ordentlichen Compiler meiden müsste.
Was immer ANSI nach return aus main definiert, ist nur in Umgebungen relevant, in denen ein Prozessende irgendeine sinnvolle Bedeutung hat. Was bei Standalone-Controllern ohne Betriebssystem nicht der Fall ist. Ausserdem ist das für den erzeugten Code völlig ohne Belang. Und der erzeugte Code ist eindeutig falsch. Die Zuordnung von "i" zu einem Registerpaar erfolgt zweimal, zunächst R67, danach R45. Dadurch ist R67 wieder frei und wird für "ii" verwendet. Damit ist das Kind im Brunnen. "Es tut mir Leid, aber wenn ich etwas kaufe, dann muss es funktionieren" Meiner Erfahrung nach gibt es keine fehlerfreien Compiler für eine leidlich komplexe Sprache. Es gibt nur funktionierenden oder nicht funktionierenden Support bei erkannten und kritischen Fehlern. Nichtsdestoweniger ist das schon ein ziemlich dickes Ei.
@Rainer Hier ein weiterer kleiner Fehler: Bei folgender Zeile int ii; ii=0x01BE+i*16+0x04; bringt der Compiler den Fehler Error: '0x01BE+i' is an invalid integer constant Ist nicht wirklich wild, aber andererseits auch ein leicht zu behebender Fehler. Aber solche Fehler stören mich nicht wirklich, denn ich sehe beim Compilieren, daß da was nicht stimmt. Anders bei Fehlern, die allein beim Programmlauf auftreten und stundenlanges Fehlersuchen zur Folge haben.
@Rainer Hier noch Problem: struct { int cluster; int x[126]; // ab 127 stimmts nicht mehr!! } val[6]; void main(void) { char ichr; short ishrt; for (ichr=0; ichr<5; ichr++) val[ichr].cluster=ichr; for (ichr=0; ichr<5; ichr++) printf("%d ",val[ichr].cluster); printf("\r\n"); for (ishrt=0; ishrt<5; ishrt++) printf("%d ",val[ishrt].cluster); printf("\r\n"); for (;;) ; // extra für Peter } Das Programm gibt dann folgendes aus: 0 1 2 3 4 0 1 2 3 4 Und so sollte es auch sein. Aber, änderst Du in der dritten Zeile das Array auf z.B. 130 Elemente, dann kommt folgendes raus: 0 1 2 3 4 0 0 0 0 0 Und das ist definitiv falsch!
Da freilich hat der Compiler recht: "0x01BE+i" passt ins formale Schema eines Tokens, erinnernd an eine Fliesskommazahl, ist dann aber keine. Leerzeichen rein und gut ist.
@A.K. Da hat der Compiler leider NICHT Recht. Denn "0x" ist der Beginn einer Hex-Zahl und kann folglich NICHT mit einem Exponenten enden. Alle von mir verwendeten Compiler für Windows und Linux beherrschen das. Aber wie ich schon geschrieben hatte: dieser Fehler stört mich nicht so sehr. Wäre aber dennoch schön, wenn er behoben würde.
In C99 sind floating point literals um eine hexadezimale Notation erweitert worden. Damit ging der Spuk los. Da werden zwar "f" und "l" für den Exponenten verwenden, "e" geht ja nicht, aber um den Lexer nicht in de Wahnsinn zu treiben, wurde die tokenization etwas grosszügiger definiert. Wobei manche Compiler dann doch restriktiver sind, um ihrerseits den Benutzer nicht in den Wahnsinn zu treiben.
Sven DerSchreckliche wrote: > Wozu bitte sollte ich hier das Assemblerlisting posten? Es geht hier um > den Compiler. Der baut Mist. Das hat auch Rainer bestätigt. Mich interessiert eben, wobei der Compiler Probleme hat. Hier definiert er i nach R4,5 um, was ansich kein Problem wäre, wenn er dann auch R6,7 nach R4,5 kopieren würde und das macht er aber nicht. > Glaubst Du im Ernst, ich kaufe einen Compiler, um dann hinterher den > Assemblercode zu korrigieren? Ne, Assembler korrigieren geht ja nicht. Nachm nächsten Compile ist ja wieder alles falsch. Beim Keil ist es definitiv so, daß er Mist macht, wenn die Mainloop ins Nirwana rennt. Und da der C-Standard nicht vorschreibt, daß Main zu einer Endlosschleife zurückkehren muß, sollte man das immer explizit machen, wenn die Programme kompatibel sein sollen. Peter
@ Sven DerSchreckliche: >@Xenu >Versuch doch mal ein Bißchen mitzudenken: Selbst wenn der Compiler >irgendeinen Mist berechnen sollte, wieso kommt dann, wenn man die >besagte Zeile weglässt, plötzlich das richtige Ergebnis raus? Es gibt kein "richtiges" Ergebnis nach dem Shift einer vorzeichenbehafteten Variablen, das ist ja das Lustige. >Der Compiler kann also Shifts auf vorzeichenbehaftete Variablen immer >nur dann richtig ausführen, wenn 2 Zeilen später ein "If" weggelassen >wird? Es ist egal, was er ausgibt, weil der Wert von i ab dem Zeitpunkt, ab dem Du den Shift ausführst, nicht mehr definiert ist. >Also, was soll dann Dein Beitrag? Ich wollte Dich auf einen Denkfehler hinweisen, mal ganz unabhängig davon, ob der Compiler einen Bug hat oder nicht. >Und im Übrigen: Du kannst gerne statt "i>>=1;" dann auch "i/=2;" >schreiben. Denn auch hier baut der Compiler den gleichen Mist!! Das beweist, dass der Compiler einen Bug hat.
^ Das mit dem "nicht definiert" bezieht sich eben auf die hardwareabhängige Darstellung eines signed-Typs. Wenn eine Schiebeoperation auf der einen Plattform tut was der Programmierer erwartet, heißt das nicht das es auf einer anderen Plattform auch so ist. Aber das sich das Ergebnis einer Schiebeoperation ändert nur weil man den Code umstellt darf nicht sein. - Michael
Sorry, aber was haltet Ihr Euch denn an dieser Shifterei auf? Wie schon geschrieben kann das auch durch igendeine andere Rechenoperation ersetzt werden. Das ist doch hier nicht der Punkt. Außerdem darf sich das Ergebnis, wie auch immer es zustandegekommen sein mag, nicht durch eine IF-Anweisung verändern. Und ebenso würde ein Endlos-loop am Ende dies nicht verändern. Das ganze kommt mir hier vor wie eine Diskussion über die zulässige Höchstgeschwindigkeit von Autos und plötzlich wird über die Farbe der Rücksitzlehne gelabert...Sorry...bleibt mal bitte beim Thema!!
@Xenu Dir wäre ich dankbar, wenn Du meine Beiträge nicht wortweise kommentieren würdest, sondern mal 3 Sätze am Stück lesen würdest. Dann würdest Du entdecken, daß da eben keine Denkfehler drin sind! Eine Programmzeile führt bei exakt gleichem Input immer zum gleichen Ergebnis! Und dieses Ergebnis, sei es so gewollt oder nicht, kann und darf nicht durch das Vorhandensein oder Nicht-Vorhandensein eines nachfolgenden IF-Statement (das mit den verwendeten Variablen nichts zu tun hat) verändert werden!
Dankeschön für eure Beiträge. Der uC51-Compiler ist also Fehlerbehaftet. Welchen preiswerten Compiler könnt ihr mir noch empfehlen?
Hi Frank, auch auf die Gefahr hin das ich mich wiederhole, was hast du gegen Freeware ? Hast du den SDCC versucht ?? Support ist ebenso gegeben, ich habe mehrfach Support benötigt und die Jungs bei Sourceforge sind wirklich sehr hilfsbereit und gut. Ansonsten Keil (glaube das ist unbestritten aber auch unbezahlbar) oder IAR.
Hi Joe, ich habe nichts gegen Freeware. Erzeugt der SDCC guten/schnellen Code und ist er zuverlässig? Keil soll prima sein, aber der ist mir viel zu teuer.
Für meine Zwecke reichts, kann nicht klagen. Hast du ein besonderes Anliegen ? compilier doch einfach mal einige deiner Sourcen. Codedichte ist ok. Doku lesen ist auf jedenfall Pflicht, machst du allerdings auch bei anderen Compilern. Für die 8x51 Derivate verwende ich ausschließlich den SDCC, ein Vergleich ist daher nicht einfach. Auf jeden Fall ist es nicht so bequem wie mit dem Keil Compiler aber wie gesagt ganz ok. Keil kenne ich nur als Demo Version, umfangreiche Sourcecodes kann ich also nicht vergleichen. Ab 4k ist bei mir SDCC angesagt (auch unter 4k ;-)). Support ist, wie bereits erwähnt, sehr gut. Selbst an einem Sonntag Abend kam eine prompte Reaktion, Patch lag ca. 24:00 Uhr vor, das finde ich genial. Also, Versuch macht Klug, viel Spaß
@Frank Ich kann Dir auch nur empfehlen, den yC51 zu meiden. Inzwischen hat der Hersteller mir doch glatt erklärt, der Compiler sei nicht für den Entbenutzer entwickelt, sondern für Fachpersonal und Fachpersonal könne nicht erwarten, daß der Compiler auch funktioniere. Weiter sieht er keinerlei Anlass, Fehler zu beheben. Wenn Du also nicht "Fachpersonal" bist, sollst Du den Compiler nicht nutzen. Wenn Du "Fachpersonal" bist, ist es Dein Problem, wenn der Compiler nicht funktioniert.
ich weiß - das Thema ist schon sehr alt - aber gibt es eine Liste der bekannten Bugs min Hinweisen, wie man sie umgehen kann? Anscheinend kann der Herr Wickenhäuser gut mit dem Compiler leben, wenn er ihn nicht weiter korrigiert. Also sollte es auch workarounds geben. Vielen Dnak für Eure Hinweise
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.