Forum: Mikrocontroller und Digitale Elektronik uC51-Compiler von Wickenhäuser


von Frank R. (Gast)


Lesenswert?

Hallo zusammen,

wer verwendet den uC51-Compiler von Wickenhäuser?
Was für Erfahrungen habt Ihr gemacht?

Ist er zu empfehlen?

von Joe (Gast)


Lesenswert?

Warum muß es Wickenhäuser sein ? Ich verwende den SDCC und bin recht 
zufrieden damit.

von Rainer K. (Gast)


Lesenswert?

@ 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.

von Sven DerSchreckliche (Gast)


Lesenswert?

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.

von Rainer K. (Gast)


Lesenswert?

@Sven

Welche Übersetzungsfehler hast du entdeckt ?
Vielleicht kannst du dazu etwas genaueres sagen.

von Sven DerSchreckliche (Gast)


Lesenswert?

@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?

von Peter D. (peda)


Lesenswert?

@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

von Εrnst B. (ernst)


Lesenswert?

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

von Sven DerSchreckliche (Gast)


Lesenswert?

@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.

von Sven DerSchreckliche (Gast)


Lesenswert?

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!!

von Rainer K. (Gast)


Lesenswert?

@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

von Rainer K. (Gast)


Lesenswert?

Nachtrag:

Wenn i global vorab als short deklariert gibts keine Probleme.

von Xenu (Gast)


Lesenswert?

@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."





von Peter D. (peda)


Lesenswert?

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

von Rainer K. (Gast)


Lesenswert?

@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

von Sven DerSchreckliche (Gast)


Lesenswert?

@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!!

von Sven DerSchreckliche (Gast)


Lesenswert?

@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.

von A.K. (Gast)


Lesenswert?

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.

von Sven DerSchreckliche (Gast)


Lesenswert?

@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.

von Sven DerSchreckliche (Gast)


Lesenswert?

@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!

von A.K. (Gast)


Lesenswert?

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.

von Sven DerSchreckliche (Gast)


Lesenswert?

@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.

von A.K. (Gast)


Lesenswert?

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.

von A.K. (Gast)


Lesenswert?


von Peter D. (peda)


Lesenswert?

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

von Xenu (Gast)


Lesenswert?

@ 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.

von let (Gast)


Lesenswert?

^ 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

von Sven DerSchreckliche (Gast)


Lesenswert?

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!!

von Sven DerSchreckliche (Gast)


Lesenswert?

@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!

von Frank R, (Gast)


Lesenswert?

Dankeschön für eure Beiträge.

Der uC51-Compiler ist also Fehlerbehaftet.
Welchen preiswerten Compiler könnt ihr mir noch empfehlen?

von Joe (Gast)


Lesenswert?

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.

von Frank R, (Gast)


Lesenswert?

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.

von Joe (Gast)


Lesenswert?

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ß

von Sven DerSchreckliche (Gast)


Lesenswert?

@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.

von Christoph (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.