Hallo Gemeinde...
Ich habe ein Problem mit dem o.g. Compiler von MICROE.
Habe schon hier im Forum gesucht, aber noch keinen Beitrag gefunden.
Vielleich kann mir j ajemand helfen , der eventuell auf das gleiche
Problem gestoßen ist.
Dieser Compiler hat ein Problem mit der Speicherverwaltung (XDATA).
gekürztes Beispiel:
test;
var txt1,txt2 : string[10];
txt1:='RAM intern';
txt2:='RAM extern'; xdata;
Datenausgabe(txt1); //res: funktioniert
Datenausgabe(txt2); //res: funktioniert nicht, undefinierter Wert
Hat jemand eine Lösung dafür?
Habe schon mit dem Support vor zwei Jahren darüber gesprochen, die
wissen davon, hat sich aber noch nichts getan.
Das Programm wird immer noch genauso verkauft , ohne Hinweis auf diesen
Fehler.
Stefan H. schrieb:> txt2:='RAM extern'; xdata;
Bist du dir sicher, dass das so richtig ist?
Muss das 'xdata' nicht eher bei der Deklaration der Variabele plaziert
sein?
Sprich:
Einer schrieb:> Laut handbuch.>>> var xdata txt2 : string[10];
Wow, was für eine Grammatik-Vergewaltigung! Die haben anscheinend zu
viel C geraucht, mit Pascal hat sowas nicht mehr viel Ähnlichkeit.
Stefan H. schrieb:> Habe schon mit dem Support vor zwei Jahren darüber gesprochen, die> wissen davon, hat sich aber noch nichts getan.
Wenn das so ist, dann hat man offenbar kein Interesse mehr am Kunden.
Was spricht dagegen, den Compiler zu wechseln, z.B.:
http://turbo51.com/ ?
Ich habe já einen anderen Compiler. Habe bis jetzt mit dem Turbo51
gearbeitet. Hatte mir aber mal das Teil für knapp 200 Eur geleistet und
nun möchte man ja auch das das irgendwann mal funktioniert.
Geld gibt es ja nicht zurück.
Noch ein Wort zu dem Beispiel, was ich hier angefügt hatte. Ich habe ja
geschrieben, das dies etwas verkürzt war.
Die Deklarationen sind richtig.
Laut Speichermonitor schreibt er ja auch betreffende Zeichen in den RAM.
Nur rückwärts funktioniert das Ganze nicht.
Also wenn ich einer Variablen diese Zeichen zuweisen möchte.
Wie geschrieben, das Problem ist dem Entwickler bekannt, schon seit
mindestens 2Jahren.
Eric B. schrieb:> Stefan H. schrieb:> txt2:='RAM extern'; xdata;>> Bist du dir sicher, dass das so richtig ist?> Muss das 'xdata' nicht eher bei der Deklaration der Variabele plaziert> sein?> Sprich:var txt2: string[10] xdata;
Du hast Recht, ist ein Fehler von mir heute gewesen.
Im Programm steht es richtig.
Var txt1, txt2 : String[10]; xdata;
Danach dann die Wertzuweisung.
Stefan Hat. schrieb:> Var txt1, txt2 : String[10]; xdata;
Ein memory type specifier im VAR Bereich steht laut Doku von
MikroElektronika vor dem Namen der Variablen, wie oben schon erwähnt
wurde. Hier steht nichts, also sollte es demgemäss den durch das
gewählte memory model definierten memory type geben, für beide Vars
gleich.
Ein isoliertes Statement
xdata;
ergibt nicht nur der Doku gemäss keinen Sinn. Selbst wenn der Compiler
das kommentarlos frisst, ist das kein Indiz für sinnvollen Code.
Es ist nicht immer klug, in Fragen einen abstrahierten Phantasiecode zu
posten, in der meist vergeblichen Hoffnung, dass es bei einem Leser
klingelt. Zumal sich später herausstellt, dass das Problem nicht darin
liegt, oder wie hier falsch übertragen wurde.
Sinnvoller: Echter und fehlerfrei übersetzbarer Code, minimiert auf das
absolut notwendige, in dem der Fehler noch auftritt.
Stefan Hat. schrieb:> Wie geschrieben, das Problem ist dem Entwickler bekannt, schon seit> mindestens 2Jahren.
Je nach Höflichkeit des Compiler-Programmierers kann eine offen
gelassene Problemmeldung auch bedeuten, dass das Problem sich seiner
Ansicht nach beim Kunden zwischen Stuhl und Tastatur befindet. Und
Aussagen wie "ich mache alles richtig, aber es funktioniert nicht" nur
im zweiten Teil des Satzes zutreffen.
Soll heissen, dass bei
(1) Es gibt ein Problem.
(2) Ich mache alles richtig.
(3) Der Compiler macht alles richtig.
Mindestens eine dieser Aussage falsch ist. Und das muss nicht (3) sein.
So, dann machen wir doch ein
A. K. schrieb:> Ein memory type specifier im VAR Bereich steht laut Doku von> MikroElektronika vor dem Namen der Variablen, wie oben schon erwähnt> wurde. Hier steht nichts, also sollte es demgemäss den durch das> gewählte memory model definierten memory type geben, für beide Vars> gleich.
So , dann schicke ich doch hier mal das Beispiel aus dem Handbuch von
MIKROE.
Description
External RAM (XRAM) or Internal expanded RAM (ERAM); accessed by opcode
MOVX @DPTR. See Xdata Specifics
This memory is indirectly accessed using 16-bit addresses and is the
external data RAM of the 8051. The amount of xdata is limited in size
(to 64K or less).
Example // puts x in xdata
var x : byte; xdata;
Ich weiß nicht, aber nach meiner Meinung nach , steht XDATA hier nach
der Variablen....
Stefan H. schrieb:> Example // puts x in xdata> var x : byte; xdata;>> Ich weiß nicht, aber nach meiner Meinung nach , steht XDATA hier nach> der Variablen....
Dann reden wir von verschiedenen Compilern. In der mir zugänglichen Doku
sieht das nämlich anders aus. Siehe Anhang. In diesem Fall wäre es wohl
sinnvoll, einen Link zur Doku bereit zu stellen.
Stefan H. schrieb:> Example // puts x in xdata> var x : byte; xdata;
Du denkst echt, dass die eine Referenz auf das (aus dem Jahre 2013)
noch relevant ist? Schau noch mal nach.
leo
A. K. schrieb:> Stefan H. schrieb:>> Example // puts x in xdata>> var x : byte; xdata;
Wenn das so richtig ist, dann muss ich Bernd zustimmen. Dann sollten die
mal das Kraut wechseln, dass sie rauchen. Das ist, aus syntaktischer
Systematik betrachtet, einfach Hühnerkacke.
A. K. schrieb:> Soll heissen, dass bei> (1) Es gibt ein Problem.> (2) Ich mache alles richtig.> (3) Der Compiler macht alles richtig.> Mindestens eine dieser Aussage falsch ist. Und das muss nicht (3) sein.
Also , weil ich mich fast blöde gesucht hatte in einem Programm,was ich
vor zwei Jahren mal geschrieben hatte, bin ich it folgendem Testprogramm
auf besagten Fehler gekommen und habe mich an den Support gewandt.
program Test;
Var S1: string [5]; Xdata;
S2: string [5];
L1, l2: word;
Begin
S1: = '1234';
S2: = '1234';
L1: = strlen (s1); // res = 0
L2: = strlen (s2); // res = 4
end.
Wie unschwer zu erkennen ist, sollte nur die Länge des Textes
festgestellt werden. Funktioniert im internen RAM , aber extern nicht.
Die Antwort des Entwicklers war.... über eine Funktion die Länge
festzustellen die mit Pointern arbeitet.
A. K. schrieb:> Dann reden wir von verschiedenen Compilern. In der mir zugänglichen Doku> sieht das nämlich anders aus. Siehe Anhang. In diesem Fall wäre es wohl> sinnvoll, einen Link zur Doku bereit zu stellen.
Das was ich hier kopiert habe, ist aus der Hilfe des Programms.
Ich habe hier die Version 3.6.0
Stefan H. schrieb:> Das was ich hier kopiert habe, ist aus der Hilfe des Programms.> Ich habe hier die Version 3.6.0
Und ich die Version -1. Ohne Doku-Link ins Netz bin ich also weg.
leo schrieb:> Du denkst echt, dass die eine Referenz auf das (aus dem Jahre 2013)> noch relevant ist? Schau noch mal nach.
Also nach meiner Erkenntnis ist das Programm Stand 2013 oder 2014.
Da hat sich bis heute nichts geändert.
leo schrieb:> Hast du mal geschaut, wie antik das ist?
Leider zu spät gemerkt und schon gekauft, dann aber Probleme bekommen
die eigentlich bei einer IDE nicht sein sollten.
Einfache Sache, externen Speicher ansprechen, macht jeder kostenloser
Compiler.
Zumindest erklärt das den Seufzer des ME-Supports. Selbst wenn da also
der Bug echt ist, ist ein Fix für eine Asbach-Version nicht mehr so ganz
selbstverständlich. Irgendwo steht bei denen was von lifetime upgrades.
Yalu X. schrieb:> Es scheinen mindestens zwei verschiedene Versionen der Dokumentation zu> existieren, eine mit xdata vor dem Variablennamen
"... covers version 1.1".
Ok, mit der ist natürlich nichts anzufangen.
Yalu X. schrieb:> Die zweite (HTML) liegt zwar auf der Hersteller-Webseite, scheint> allerdings verwaist zu sein.
Offenbar die richtigere. Wobei deren Compilerbauer einen sehr schrägen
Sinn für Syntax hat.
A. K. schrieb:> Wobei deren Compilerbauer einen sehr schrägen Sinn für Syntax hat.
Ich finde die Syntax mit dem durch ein Semikolon abgetrennten und damit
außerhalb der eigentlichen Deklaration stehenden xdata auch ziemlich
schräg.
Anderen gefällt allerdings die andere Syntax nicht:
Bernd K. schrieb:> Einer schrieb:>> Laut handbuch.>>>>>> var xdata txt2 : string[10];>> Wow, was für eine Grammatik-Vergewaltigung! Die haben anscheinend zu> viel C geraucht, mit Pascal hat sowas nicht mehr viel Ähnlichkeit.
(wobei ich an dieser Deklaration auch beim zehnten Mal Hinschauen beim
besten Willen nichts C-ähnliches erkennen kann)
Das Schöne an Pascal ist, dass jeder Compiler-Entwickler bei der Wahl
der Syntax alle künstlerischen Freiheiten hat. Bei Pascal-scm (AVRco)
von E-LAB hat man sogar die meisten der lästigen BEGINs wegoptimiert und
stattdessen wie in vielen Basic-Dialekten die ENDs durch ENDIF, ENDFOR,
ENDWHILE usw. ersetzt. Eigentlich finde ich das gar nicht einmal so
schlecht, da ich sowieso noch nie wusste, wo ich die BEGINs hinschreiben
soll (ans Ende der Kopfzeile von IF, WHILE etc., in eine neue Zeile ohne
zusätzliche Einrückung, in eine neue Zeile mit zusätzlicher Einrückung,
...). Wie man es auch macht: Es sieht immer irgendwie holprig aus.
Yalu X. schrieb:> da ich sowieso noch nie wusste, wo ich die BEGINs hinschreiben> soll
Auch Wirth hatte sich nach Pascal von diesem Algol-Erbe getrennt.
A. K. schrieb:> Auch Wirth hatte sich nach Pascal von diesem Algol-Erbe getrennt.
Selbst Algol hat diesen Wandel vollzogen, sogar schon 3 Jahre vor der
Einführung von Pascal: In Algol 68 gab es if...fi, for/while do...od
und case...esac.
So , ich habe noch mal etwas ausprobiert.
also mit Integer-Werten ist das kein Problem, die werden wieder
zurückgelesen.
Funktioniert mit Strings nicht.
Yalu X. schrieb:> Hast du eigentlich mal ausprobiert, ob deiner Compiler-Version auch die> ältere Syntax>> var> xdata txt2 : string[10];>> frisst? Vielleicht ist er ja abwärtskompatibel und zeigt bei dieser> Syntax den Bug nicht.
Gerade eben getan.
Meckert der Compiler. Geht nicht
Yalu X. schrieb:> Selbst Algol hat diesen Wandel vollzogen, sogar schon 3 Jahre vor der> Einführung von Pascal: In Algol 68 gab es if...fi, for/while do...od> und case...esac.
Ernsthaft? esac?
Ist das heute noch so?
A. K. schrieb:> Wenn das so richtig ist, dann muss ich Bernd zustimmen. Dann sollten die> mal das Kraut wechseln, dass sie rauchen. Das ist, aus syntaktischer> Systematik betrachtet, einfach Hühnerkacke.
Zustimm...
1
Var
2
S1:string[5];
3
xdata;
4
S2:string[5];
5
L1,L2:word;
6
7
Begin
8
S1:='1234';
9
S2:='1234';
10
L1:=strlen(s1);// res = ?
11
L2:=strlen(s2);// res = ?
12
end.
- Ein Semikolon ist doch auch in Pascal ein Kommandoende, oder?
- Mir stellt sich hier die Frage worauf sich so eine alleinstehendes
"xdata" überhaupt beziehen soll. Alles was davor kommt, nur die eine
Deklaration davor oder alles was danach kommt, oder nur die nächste
Deklaration? Logisch wäre auf nachfolgendes.
- Xdata; oder xdata;?
- Sowas komisches wie "x: =y" schiebe ich jetzt mal auf die
Forensoftware, oder?
1
var
2
txt2:string[10];
3
xdatatxt2:string[10];
4
5
Begin
6
...
Auch wenn mein Pascal mindestens 20 Jahre eingerostet ist, so sieht das
für mich syntaktisch richtiger aus als eine "xdata" irgendwo mittendrin
als alleinstehender Befehl.
Stefan H. schrieb:> Wie unschwer zu erkennen ist, sollte nur die Länge des Textes> festgestellt werden. Funktioniert im internen RAM , aber extern nicht.
Ich würde jetzt fast mal annehmen es ist genau umgekehrt?
Das hikhak mit dem Handbuch deutet ja irgendwie darauf hin das sie
selbst mal bemerkt hatten dass das was sie da zusammengestrickt hatten
totaler Käste ist. Sie haben es anscheinend nur nie hinbekommen das
Chaos vernünftig zu bereinigen sondern eher verschlimmert. Zumal die
Version für den 8051 anscheinend nicht mehr wirklich gepflegt wird...
Irgend W. schrieb:> Das hikhak mit dem Handbuch deutet ja irgendwie darauf hin das sie> selbst mal bemerkt hatten dass das was sie da zusammengestrickt hatten> totaler Käste ist.
Aber andersrum.
var xdata v: ...;
ist die alte Fassung und
var v: ...; xdata;
die aktuelle. Würde mich ja interessieren, wie das jeweils mit Pointern
funktioniert, wenn die nicht sowieso durchweg managed sind.
Irgend W. schrieb:> - Ein Semikolon ist doch auch in Pascal ein Kommandoende, oder?
Genau genommen ist es ein Statement-Separator. Weshalb
begin a := 1; b := 2 end
in Pascal ok ist, während es in C ein Terminator ist und
{ a = 1; b = 2 }
beim Compiler keine Gnade findet.
Yalu X. schrieb:> (wobei ich an dieser Deklaration auch beim zehnten Mal Hinschauen beim> besten Willen nichts C-ähnliches erkennen kann)
Diese Yoda-Grammatik (alles in umgekehrter Reihenfolge) hinzuschreiben
ist das herausstechende Hauptmerkmal von C und allen Sprachen die davon
infiziert wurden. Pascal hat das in erfrischender Weise nicht so gemacht
und lässt sich von links nach rechts und von oben nach unten lesen. Erst
in jüngerer Zeit mit jüngeren Sprachen scheint man diesbezüglich
allmählich wieder zur Vernunft zu kommen.
Also, wie ich die Sache sehe, hat auch keiner Erfahrung mit diesem
Problem.
Bleibt mir also nur weiter in Turbo51 zu programmieren, zu warten bist
im nächsten Jahrhundert mal ein Update kommt, oder das Geld einfach
unter "Lehrgeld" zu verbuchen. ;)
Noch ein kleiner Nachtrag.
Als Alternative für den Befehl strlen(), der ja hier nur im internen RAM
funktioniert, wurde mir folgende Funktion angeboten, die Stringwerte im
ext. RAM überprüft:
function strlen_xdata (str : ^xdata char) : byte;
var len : byte;
begin
len :=0;
while (str^ <> 0) do
begin
Inc(str);
Inc(len);
end;
result := len;
end;
Nützt mir aber nix, weil ich die Werte, wenn ich sie weiterverwenden
will in deninternen RAM kopieren müßte, und der dann voll ist.
Außerdem weiß ich nicht ganz genau was die hier machen wollen. Komische
Syntax, konnte auch mit der Hilfe im Programm nicht so richtig den Sinn
erschließen, habe mit Pointern noch nicht gearbeitet.
xdata varname : typname;
typname varname xdata
Bernd K. schrieb:> Yalu X. schrieb:>> (wobei ich an dieser Deklaration auch beim zehnten Mal Hinschauen beim>> besten Willen nichts C-ähnliches erkennen kann)>> Diese Yoda-Grammatik (alles in umgekehrter Reihenfolge) hinzuschreiben> ist das herausstechende Hauptmerkmal von C
Was ist in
1
xdata varname: typname;
verglichen mit normalem Pascal umgekehrt? Der Variablenname steht am
Anfang, der Typname am Ende (in C ist es andersherum).
Oder stört dich die Position des xdata? Wenn ja, wo sollte es deiner
Meinung nach stehen?
Nach dem Variablennamen (varname xdata: typname;)?
Vor dem Typnamen (varname: xdata typname;)?
Nach dem Typnamen (varname: typname xdata;)?
Oder gar außerhalb der eigentlichen Deklaration wie in der aktuellen
MikroPascal-Version (varname: typname; xdata;)?
Stefan H. schrieb:> Bleibt mir also nur weiter in Turbo51 zu programmieren, zu warten bist> im nächsten Jahrhundert mal ein Update kommt, oder das Geld einfach> unter "Lehrgeld" zu verbuchen. ;)
Welches Memory-Model verwendest du? Large? Wenn nicht, dann probier's
mal damit. Die Einstellung erfolgt im Dialog "Project Settings".
Yalu X. schrieb:> verglichen mit normalem Pascal umgekehrt? Der Variablenname steht am> Anfang, der Typname am Ende (in C ist es andersherum).
Mal die alte Syntax betrachtet:
Dessen Ansatz ist also:
var xdata i: integer;
für eine normale Variable.
Wie ist das bei Parametern, die per Adresse übergeben werden? Auf die
Schnelle fand ich nichts, logisch wäre
out xdata p: integer
Da nichts drüber rdrinsteht muss man aber vielleicht auf
function f (...) ...: large
ausweichen, was die ganze Funktion mit sämtlichen Daten beeinflusst.
Oder der Compiler arbeitet mit copy-in copy-out durch den Caller und das
Problem entfällt.
Bei expliziten Pointern wird es nun interessant. Die Doku definiert
einen Pointer auf Programspace als
const ptr: ^byte
Leider suggeriert diese Syntax, dass der Pointer selbst const sei, nicht
etwa das, worauf er zeigt. Das ist ziemlich übel.
Alternativen wären:
(1) var p: ^ xdata integer
mit Bindung von xdata an ^, als als Attribut vom Pointer. Das erinnert
aber an die verwirrenden Assoziativitäten der C Deklarationstechnik.
(2) var p: xdata ^ integer
wiederum mit Bindung von xdata an ^, was wohl die bessere Wahl wäre,
denn es bewahrt die links-nach-rechts Arbeitsweise von Pascal
Deklarationen.
(3) var p: ^ xdata integer
mit Bindung von xdata an den Basistyp, nicht an den Pointer. Dies wäre
dann von der Systematik her mit
var i: xdata integer
deutlich verträglicher als mit
var xdata i: integer
Ich würde aber eher eine offenere Syntax wie memory(xdata) statt xdata
verwenden, damit nicht jede Zielmaschine andere Schlüsselworte benötigt
und auch benutzerdefinierte Räume möglich werden.
Gibts eigentlich einen Link auf die Doku des neuen Compilers? Aus dem
oben präsentierten Link komme ich nicht in die Übersicht der Doku.
Bernd K. schrieb:> Diese Yoda-Grammatik (alles in umgekehrter Reihenfolge) hinzuschreiben> ist das herausstechende Hauptmerkmal von C und allen Sprachen die davon> infiziert wurden.
Du darfst deinen C-Hass auch gern stecken lassen, er hilft dem TE sicher
nicht weiter. Übrigens hatte FORTRAN lange vor der Erfindung von C und
Pascal diese Reihenfolge – sogar ALGOL 68, was man ja nun als nahezu
direkten Vorgänger von C und Pascal sehen kann.
A. K. schrieb:> Gibts eigentlich einen Link auf die Doku des neuen Compilers?
An der Stelle hatte ich dann gestern auch aufgehört, mich mit dem
Problem zu beschäftigen. Wenn's nichtmal die Doku öffentlich gibt, dann
ist mir das zu doof.
Yalu X. schrieb:> Oder gar außerhalb der eigentlichen Deklaration
Das ist nicht außerhalb der Deklaration sondern an deren Ende wo es im
Gesamtbild dieser Grammatik auch zu erwarten wäre.
https://www.freepascal.org/docs-html/ref/refse22.html#x53-710004.2
Zum Beispiel ist es auch nicht anders bei Prozedur- oder
Methodendeklarationen, dort stehen die Modifier (inline; cdecl;
external; virtual; override; reintroduce; etc...) auch am Ende,
abgesetzt mit einem Semikolon.
oder bei Variablen die bereits existierenden Modifier genauso am Ende
stehen wie zum Beispiel:
Foo: integer; external ’libc’ name ’foobar’;
Bar: integer; export name ’baz’;
Blub: integer; cvar;
Whatever: integer; xdata; ( fügt sich nahtlos ein )
> wie in der aktuellen> MikroPascal-Version (varname: typname; xdata;)?
Ja. So sähe das sauber aus, absolut symmetrisch zum Rest der Sprache und
kein Stilbruch. Es vor de Namen zu schreiben wäre ein hässlicher C-ismus
der so gar nicht ins sonstige Bild passt und komplett aus dem Rahmen
fällt.
Jörg W. schrieb:> Du darfst deinen C-Hass auch gern stecken lassen,
Oh, entschuldige Daß ich die heilige Kuh beleidigt habe indem ich DEN
Schwachpunkt ihrer Grammatik erwähnt habe, ich wußte nicht daß es
unschicklich ist die Tatsachen beim Namen zu nennen.
Auf sachliche Argumente magst du nicht eingehen? Ich hatte dir anhand
der Geschichte der Programmiersprachen gezeigt, dass dein C-Hass
komplett unbegründet ist, weil das bis zur Entwicklung von Pascal
offenbar jede der damaligen Sprachen so gemacht hat. Es ist also
überhaupt nicht die angebliche „Eigenmächtigkeit“ von C, auf die du es
immer wieder einengen magst. Es ist eher eine Eigenmächtigkeit von
Pascal, es herum gedreht zu haben – wobei ich das völlig wertfrei sehe.
Ich finde keine der beiden Reihenfolgen rundum überzeugender, jede hat
ihre problematischen Seiten.
Jörg W. schrieb:> dass dein C-Hass> komplett unbegründet ist
Ich weiß nicht von Welchem C-Hass Du immerfort fabulierst, vielleicht
nimmst Du Dir mal ne Tasse Kaffee und kommst wieder runter.
Ich habe lediglich die Frage beantwortet welcher Teil dieser
Schreibweise an C erinnert und warum das so ist. Und zwar ist es der
C-typische Yoda-Stil um den es da geht, der nicht zu Pascal passt.
Bernd K. schrieb:> Ich weiß nicht von Welchem C-Hass Du immerfort fabulierst
Wenn du es nichtmal mehr selbst bemerkst … "herausstechendes Merkmal",
"davon infiziert". Meinst du ernsthaft, dass das irgendwie auch nur den
Anschein von Objektivität hätte? Und nach wie vor willst du nicht auf
das Argument eingehen, dass das historisch eher ein "war schon immer so"
gewesen ist denn ein "hat C genau falsch herum eingeführt".
Jörg W. schrieb:> "hat C genau falsch herum eingeführt".
Es spielt doch keine Rolle wer damals als erster auf diese Idee gekommen
ist, jemand hat nach C gefragt und ich habe über C geantwortet! Mit C
müssen wir uns heute rumschlagen, und mit C# und mit Java, nicht mit
Algol oder Fortran!
Bernd K. schrieb:> jemand hat nach C gefragt
Nein. Du hast das erst ins Spiel gebracht.
> nicht mit Algol oder Fortran
FORTRAN ist nicht tot zu bekommen. ;-) Allerdings erfreuen sich dort die
Wrapper um die alten Algebra-Module (Matlab, numpy) dann auch
entsprechender Beliebtheit, die einem das Herumplagen mit dem
eigentlichen FORTRAN-Code ersparen. :)
abgesehen davon hat Mikroe kostenlose Updates auf Lebenszeit.
Das macht einigen Ärger wieder gut..wo ich woanders alle X Jahre 300€
oder so bezahlen dürfte, und dennoch mit Fehlern leben müsste
Gegeg J. schrieb:> abgesehen davon hat Mikroe kostenlose Updates auf Lebenszeit.
Wäre die Frage, warum der TE dann nicht updatet? Vielleicht hätte sich
ja sein Bug damit erledigt?
Bernd K. schrieb:> Jörg W. schrieb:>> "hat C genau falsch herum eingeführt".>> Es spielt doch keine Rolle wer damals als erster auf diese Idee gekommen> ist, jemand hat nach C gefragt und ich habe über C geantwortet! Mit C> müssen wir uns heute rumschlagen, und mit C# und mit Java, nicht mit> Algol oder Fortran!
Modernes FORTRAN hat wenig mit rumschlagen zu tun. Ich würd es jederzeit
gegenüber jedem Pascaldialekt vorziehen.
ich hatte gerade mal nachgesehen.ist auch immer noch so
"
You will love mikroPascal!
1-TIME PAYMENT, LIFETIME LICENSE
Pay once and never worry about it again. Once you buy the compiler you
are entitled to lifetime free upgrades. Upgrading the compiler takes
only a few minutes and a few clicks. We are constantly adding new
features to the compiler, you can keep track of what is happening on the
Software Roadmap page."
Gegeg J. schrieb:> Version 6.2.0 hab ich installiert...
Für 8051 oder für PIC?
Die eigentlich Frage war, ob der 51er Compiler ab und zu mal Fixes
kriegt. Kostenlose Updates nützen nichts, wenn es keine gibt.
ach ups..sorry..hatte jetzt für ARM und AVR geschaut...ob der 8051 noch
so gut gepflegt wird weiß ich nicht
Tatsächlich ist im 8051 Forum so gut wie nichts los..kann gut sein, das
die da dann auch kaum Zeit investieren
nd tatsächlich scheint die Version 3.5 aus 2013 aktuell zu sein...
Es gibt wohl immerhin noch ca 4-5 aktive Nutzer dieses Controller im
Mikroe Forum...da sollte sich Mikroe wirklich mal etwas bemühen;-)
A. K. schrieb:> Gibts eigentlich einen Link auf die Doku des neuen Compilers? Aus dem> oben präsentierten Link komme ich nicht in die Übersicht der Doku.
Eine Übersicht habe ich auch nicht gefunden. Man kann sich lediglich
über die Links-Rechts-Navigations-Buttons mühevoll durch alle Seiten
durchwühlen.
Man kann sich aber hier
https://www.mikroe.com/mikropascal-8051
ohne Registrierung eine Demoversion herunterladen (ca. 16MB), die u.a.
auch die Doku als CHM-Datei mit Inhaltsverzeichnis enthält. Die IDE mit
integriertem Debugger und Simulator läuft sogar unter Wine. Ob damit
auch geflasht werden kann, konnte ich nicht testen.
Ich wollte damit eigentlich meine Frage von oben selber beantworten:
Yalu X. schrieb:> Welches Memory-Model verwendest du? Large? Wenn nicht, dann probier's> mal damit. Die Einstellung erfolgt im Dialog "Project Settings".
Laut Doku werden im Large-Modell alle Variablen defaultmäßig im XDATA
abgelegt. Meine Erwartung wäre gewesen, dass die Bibliotheken in drei
Varianten (small, compact und large) vorliegen und somit bei Verwendung
des Large-Models automatisch eine Large-Version von strlen und Konsorten
zur Anwendung kommt. Es gibt zwar von jeder Bibliothek nur eine Datei,
aber vielleicht enthält diese Datei ja alle drei Modelle.
Als µC haben ich den AT89C51ID2 mit integriertem 2kB XDATA-RAM
ausgewählt. Damit konnte ich Stefans Problem im Simulator reproduzieren,
allerdings tritt das Problem in allen drei Speichermodellen auf. Nur
die vom Support bereitgestellte strlen_xdata-Funktion lieferte die
richtige Stringlänge, und das in allen drei Modellen.
Lasse ich das "xdata" in der Variablendeklaration weg, dann werden die
Variablen – unabhängig vom eingestellten Speichermodell – in DATA
abgelegt. Damit funktioniert zwar strlen, aber die Variablen dürfen in
Summe maximal 128 Bytes belegen, sonst meckert der Linker.
Irgendwie hatte ich das Gefühl, dass die Einstellung des Speichermodells
keinerlei Einfluss auf den erzeugten Code hat, was sich bestätigte, als
ich die erzeugten Assembler-, Listing- und Binärdateien verglich: Bis
auf das teilweise enthaltene Build-Datum waren sie für alle Modelle
exakt identisch, obwohl die IDE den Compiler jeweils mit der korrekten
-E-Option (-ES, -EC oder -EL, je nach Modell) aufruft.
Vorläufiges Fazit:
Variablen, die in XDATA liegen, können nicht als VAR-Argumente oder per
Pointer an Bibliotheksfunktionen übergeben werden. Da gerade größere
Variablen wie Strings und andere Arrays typischerweise call-by-reference
übergeben werden und oft aus Platzgründen nur in XDATA abgelegt werden
können, ist somit ein Großteil der Bibliotheksfunktionen (neben der
String-Bibliothek betrifft dies auch die meisten I/O-Bibliotheken)
weitgehend nutzlos. Man kann sich zu diesen Funktionen allenfalls selber
Pendants mit XDATA-Argumenten schreiben, was aber viel Arbeit und wenig
Spaß bedeutet.
Im Changelog der Version 3.5.0 steht u.a.:
1
* Fixed: Problems with large model.
Demnach scheint das Large-Modell nicht nur Zierde oder ein zukünftiges
Feature zu sein. Vielleicht bin ich ja nur zu dumm, es zu aktivieren :)
Oder die Demoversion auf das Small-Modell beschränkt. Nur hätte ich dann
gerne irgendwo einen Hinweis darauf gelesen. In ein paar Threads im
MikroE-Forum wird eine Limitierung der Codegröße auf 2kB erwähnt, von
einer Einschränkung der nutzbaren Speichermodelle ist aber nirgends die
Rede.
Wenn es dennoch an der Demoversion liegt, sollte Stefan mit seiner
gekauften Version ja erfolgreicher sein.
Selbst wenn es gelingen sollte, für diese und alle anderen Probleme (das
MikroE-Forum ist voll davon) Workarounds zu finden, sollte man immer im
Hinterkopf behalten, dass die Entwicklung der 8051-IDE von MikroE
bereits 2013 (V3.6.0), die der 8051-Compiler (C, Pascal und Basic) sogar
schon 2011 (V3.5.0) stehengeblieben ist. Einzig für ARM, AVR und dsPIC
scheinen die Tools noch gepflegt zu werden. Die Versionsnummern der
aktuellsten davon beginnen einer 7. Auf diesen drei Plattformen gibt es
auch kein XDATA, weswegen das vorliegende Problem dort ohne Belang ist.
Womit wohl auch diese Frage beantwortet wäre:
Jörg W. schrieb:> Wäre die Frage, warum der TE dann nicht updatet?
Vielleicht sollte er auf eine andere µC-Familie updaten ;-)
Yalu X. schrieb:> Womit wohl auch diese Frage beantwortet wäre:>> Jörg W. schrieb:>> Wäre die Frage, warum der TE dann nicht updatet?
Ja, allerdings. :/
Yalu X. schrieb:> Welches Memory-Model verwendest du? Large? Wenn nicht, dann probier's> mal damit. Die Einstellung erfolgt im Dialog "Project Settings".
Also ich verwende das "Large"-Model.
Habe aber auch keinen Unterschied bemerkt, wie einer der Diskutanten
schon schrieb.
Was ich wirklich sehr komisch finde, das integer und byte Variablen ohne
Probleme im Xdata unterzubringen sind und auch dort weiter verwendet
werden können. Nur string und warscheinlich auch char (nicht getestet)
verweigern den Zugriff.
Sowas muß man doch vor der Vermarktung schon mal probiert haben.
Naja wie dem auch sei, danke dafür das das außer mir noch jemand
getestet hat , und nicht nur ein Fehler ist, der mir wiederfahren ist.
Ich werde nun wieder zu Turbo51 zurückkehren.
Die Bibliotheken sind zwar nicht ganz so umfangreich, aber dafür
funktioniert das Programm wenigstens ohne Fehler.
Stefan H. schrieb:> Was ich wirklich sehr komisch finde, das integer und byte Variablen ohne> Probleme im Xdata unterzubringen sind und auch dort weiter verwendet> werden können.
Das ist nicht eine Frage des Datentyps, sondern der Art und Weise, wie
das Argument an die Funktion übergeben wird. In Pascal kann ein Argument
als Wert (Call by Value) oder als Referenz (Call by Reference) übergeben
werden.
Call by Value:
- Die Deklaration im Funktionskopf erfolgt ohne VAR.
- Der Wert der Variable wird bei der Übergabe kopiert.
- Änderungen des Arguments innerhalb der Funktion wirken sich nicht auf
die Variable außerhalb aus, da nur die Kopie bearbeitet wird.
- Die übergebene Kopie liegt im DATA-Bereich oder in einem Register, so
dass die Funktion nichts davon mitbekommt, in welchem Speicherbereich
(DATA, IDATA oder XDATA) die Originalvariable liegt
Call by Reference:
- Die Deklaration im Funktionskopf erfolgt mit VAR.
- Es wird keine Kopie, sondern die Adresse der Variable übergeben.
- Änderungen des Arguments innerhalb der Funktion wirken sich direkt auf
die Variable außerhalb aus.
- Für die Übergabe einer DATA- oder IDATA-Variable reicht eine
8-Bit-Adresse aus, bei einer XDATA-Variable muss eine 16-Bit-Adresse
verwendet werden. Der MikroE-Compiler scheint fälschlicherweise immer
8-Bit-Adressen zu verwenden.
- Für den Zugriff auf die Variable über eine XDATA-Adresse muss der
Compiler anderen Code generieren als bei einer DATA-Adresse. Der
MikroE-Compiler scheint fälschlicherweise immer nur Code für
DATA-Zugriffe zu generieren. Damit wird nicht auf die XDATA-Variable
zugegriffen, sondern auf einen Teil des DATA-Speichers, was zu
seltsamen Effekten führt.
In MikroPascal können zusammengesetzte Datentypen (String, Array und
Record) grundsätzlich nur als Referenz übergeben werden. Damit sind von
dem Problem vermutlich alle Funktionen/Prozeduren betroffen, die
Strings, Arrays oder Records als Argumente enthalten. Auch Argumente mit
einfachen Datentypen (Integer, Byte, Char usw.) funktionieren nicht,
wenn sie als VAR deklariert sind. Man kann Call-by-Reference allenfalls
dadurch simulieren, dass man explizit einen Pointer auf die Variable
übergibt, wie folgendes Beispiel verdeutlicht:
1
program Test;
2
3
var
4
n: integer; xdata;
5
6
procedure testproc1(var arg: integer; xdata);
7
begin
8
arg := 123
9
end;
10
11
procedure testproc2(arg: ^xdata integer);
12
begin
13
arg^ := 123
14
end;
15
16
begin
17
testproc1(n); // n bleibt unverändert -> falsch
18
testproc2(@n) // n ist jetzt 123 -> richtig
19
end.
Durch den Aufruf von testproc1 oder testproc2 sollte n mit dem Wert 123
überschrieben werden. Das funktioniert aber aus den o.g. Gründen nur bei
testproc2.
Eigentlich sollte MikroE diese alten, erwiesenermaßen grob fehlerhaften
8051-Versionen entweder ordentlich überarbeiten oder komplett vom Markt
nehmen. Ein halbfertiges Produkt zu verkaufen ist in Ordnung, wenn der
Kunde darüber in Kenntnis gesetzt wird und in angemessener Zeit mit
einem Update rechnen kann. Hier ist aber weder das eine noch das andere
gegeben.
Yalu X. schrieb:> Damit wird nicht auf die XDATA-Variable> zugegriffen, sondern auf einen Teil des DATA-Speichers, was zu> seltsamen Effekten führt.
Hier ist ein Beispiel, das das fehlerhafte Überschreiben von DATA
verdeutlicht:
1
program Test;
2
3
var
4
a: integer;
5
n0, n1, n2, n3, n4: integer; xdata;
6
7
procedure testproc(var arg: integer; xdata);
8
begin
9
arg := 3333
10
end;
11
12
begin
13
a := 1111;
14
n0 := 0; n1 := 2222; n2 := 0; n3 := 0; n4 := 0;
15
testproc(n1);
16
end.
Der Aufruf von testproc(n1) sollte a unverändert lassen und n1 in
3333 ändern. Stattdessen wird a mit 3333 überschrieben, während n1
unverändert bleibt.
Ein Compiler der solche Fehler macht ist m. E. nicht zu gebrauchen. Ich
würde mir in jedem Fall turbo51 ansehen. Der Autor behauptet vom
Sprachumfang TP6 kompatibel zu sein. Ich hatte bisher mit dem Compiler
auch keine Probleme lauffähige Programme zu erzeugen. Was ich sowieso
komisch finde ist diese strlen Funktion. Das gibt's in Pascal eigentlich
nicht man fragt einfach Str[0] ab um die Länge zu bekommen.
Thomas
Thomas Z. schrieb:> Was ich sowieso komisch finde ist diese strlen Funktion. Das gibt's in> Pascal eigentlich nicht man fragt einfach Str[0] ab um die Länge zu> bekommen.
Dieser Compiler vereinigt die Nachteile von Pascal und C und fügt noch
ein paar weitere hinzu, s. auch hier:
Beitrag "Re: Lazarus Pascal / Delphi /FreePascal aktiver als viele denken? EADS, Sony etc"
Da wäre mir ein ordentlich implementiertes Basic fast noch lieber (wobei
es da für Mikrocontroller auch nichts Gescheites gibt).
Thomas Z. schrieb:> Ein Compiler der solche Fehler macht ist m. E. nicht zu gebrauchen. Ich> würde mir in jedem Fall turbo51 ansehen. Der Autor behauptet vom> Sprachumfang TP6 kompatibel zu sein. Ich hatte bisher mit dem Compiler> auch keine Probleme lauffähige Programme zu erzeugen.
Ja, den Turbo51 hatte ich bisher genutzt. Aber wie das immer so ist, die
Bedieneroberfläche fand ich etwas ansprechender und die dazugehörige
Bibliothek.
Naja, und da bin ich, wollte ich eben umsteigen auch das andere Dings
da.
Hätte lieber in der Demoversion weiter testen sollen.
Aber wer ahnt denn das solche gravierenden Fehler in dem Programm sind.
Das sind ja nicht nur kleine Dinge in einer Bibliothek die mal nicht
funktionieren, das ist ja schon Systemrelevant.
Übrigens geht ein spezieller Dank an Yalu.
Das ist ja eine richtige Abhandlung die er über diesen Fehler
geschrieben hat. So tief stecke ich leider nicht in dieser Materie.
Sehr gute Arbeit.
Allenfalls sollte man sich ueberlegen, ob in diesem Pascal die Strings
der Turbopascal konvention folgen, dh mit der Laenge des Strings im
0.Byte des Arrays, oder dem unsaeglichen Ansatz von C mit der terminalen
Null.
Joggel E. schrieb:> Allenfalls sollte man sich ueberlegen
Was sollte man sich denn dabei „überlegen“?
Dass es Null-terminierte Strings sind, wurde schon genannt, da gibt es
nichts zu „überlegen“. Irgendwelche Attribute dafür kannst du dir gern
klemmen, oder möchtest du, dass jemand die Limitierung von Strings auf
255 Zeichen auch irgendwie unpassend tituliert?
Hat aber alles mit dem eigentlichen (und m.E. viel wesentlicheren)
Problem des TEs nichts zu tun.
Oder wolltest du nur den langsam verrottenden Thread mal wieder beleben
mit einer kleinen Provokation?
Stefan H. schrieb:> Hätte lieber in der Demoversion weiter testen sollen.
Nimm mal Kontakt mit MikroE auf und schildere dein Problem (im Forum
oder mail).
mache selber viel mit den Compilern, sind teilw. richtig gut. Die 8051
und Atmel Versioen würde ich aber nicht nutzen.
Toby P. schrieb:> mache selber viel mit den Compilern, sind teilw. richtig gut. Die 8051> und Atmel Versioen würde ich aber nicht nutzen.
Sind das alles unterschiedliche Compiler oder haben die unterschiedliche
Front- und Backends für die verschiedenen Sprachen und Targets?
mh schrieb:> Sind das alles unterschiedliche Compiler oder haben die unterschiedliche> Front- und Backends für die verschiedenen Sprachen und Targets?
Die Oberfläche ist überall sehr ähnlich, auch die libs. MikroE bemüht
sich da wohl um einen internen Standard. Die Compiler sind natürlich
nicht die gleichen.
Da wo es sich nicht lohnt machen die aber imo sehr wenig. Atmel und 8051
haben einfach zu viele teilw. kostenlose Mitbewerber.
Bei Arm und Pic haben Sie aber imo sehr gute Toolchains gebaut. Die sind
schnell installiert und laufen super.
Toby P. schrieb:> mh schrieb:>> Sind das alles unterschiedliche Compiler oder haben die unterschiedliche>> Front- und Backends für die verschiedenen Sprachen und Targets?>> Die Oberfläche ist überall sehr ähnlich, auch die libs. MikroE bemüht> sich da wohl um einen internen Standard. Die Compiler sind natürlich> nicht die gleichen.
Es geht mir rein um den Compiler. Weiß jemand etwas genaueres über die
Compiler selbst?