## c't-Projekte - Mailinglisten

[Voriger (Datum)] [Nächster (Datum)] [Voriger (Thread)] [Nächster (Thread)]
[Nach Datum][Nach Thread]

### Re: [ct-bot] Basic-Interpreter (für c't - Bot)

Absender: Uwe Berger
Datum: Do, 02.12.2010 22:03:54
In-reply-to: <BDD47587-412D-4D50-AC42-4B488A95575E@xxxxxxxxxxxxxxx>
References: <1ac236efdb2ae353dba0652e0009d0d7.squirrel@xxxxxxxxxxxxxxxxxxx> <BDD47587-412D-4D50-AC42-4B488A95575E@xxxxxxxxxxxxxxx>

    MoinMoin,

    Timo Sandmann schrieb:

> `Das byte-weise Einlesen ist sicherlich für Mikrocontroller mit wenig RAM sehr vorteilhaft.` `Beim ct-Bot ist zwar standardmäßig auch nur ein ATmega32 vorhanden, da der Codeumfang aber inzwischen`

`> deutlich angewachsen ist, braucht man im Prinzip mindestens einen` `ATmega644(P) (oder ATmega1284P).`

> `Von daher müssen wir nicht ganz so knauserig mit dem RAM sein, insbesondere, wenn man dadurch Vorteile bekommt.`

    >

`naja, auch 4kB bzw.16 kB SRAM sind nicht unendlich viel. Selbst ein` `kurzes Basic-Programm könnte leicht diesen RAM dynamisch "zumüllen", je` `nach der Komplexität eines Ausdrucks (gerade hier wird intensiv mit` `Rekursionen gearbeitet). ... und es gibt bestimmt auch Dinge die ihr` `programmieren wollt und SRAM verbrauchen.`

`> Viel wichtiger ist beim ct-Bot, dass die Hauptschleife alle 10 ms` `durchlaufen wird, damit z.B. die Abgrundsensoren noch rechtzeitig` `> ausgewertet werden und den Bot _vor_ der Tischkante stoppen können.` `Je mehr von den 10 ms eines Zyklus noch übrig bleiben,` `> desto besser, weil dann Hintergrund-Threads länger laufen können, um` `u.a. eine Karte der Umgebung auf die SD-Karte zu schreiben.` `> Das ist natürlich sehr ct-Bot spezifisch, spielt für "uns" aber eine` `wichtige Rolle, weil neue Features bereits Vorhandene nicht` `> unbrauchbar machen sollen. Wir stellen also sozusagen gewisse` `Performanz-Anforderungen an die Bot-Verhalten.`

    >

`10ms sind fast eine Ewigkeit, aber das Anliegen ist mir schon` `verständlich. Wenn der Basic-Interpreter vernünftig, und so wie gedacht` `eingebaut wird, wird nach jeder Programmzeile die Kontrolle wieder an` `das "Hauptprogramm" übergeben.`

`Frage, gerade diese wichtigen Funktionen, wie Sensorzustandwechsel, sind` `nicht in Interrupt-Routinen verpackt?`

> `Aus diesem Grund ist es auf dem ct-Bot besser einen RAM-Puffer für eine ganze Basic-Zeile zu opfern und dafür die Kosten eines`

`> oder mehrerer Funktionsaufrufe pro Zeichen des Basic-Programms` `einzusparen. Hinzu kommt, dass man spätestens für einen` `> Aufruf von atoi(), strcmp() usw. Teile der Daten sowieso wieder` `puffern muss.`

>     Wie gesagt, dass soll nicht bedeuten, dass ein entsprechendes Vorgehen allgemein für den Basic-Interpreter nicht sinnvoll sein könnte.

    >

`sagen wir es mal so, gerade sinnvoll implementierte Routinen zum` `Schreiben/Lesen von SD-Karten sollten intern einen Bufferspeicher` `verwenden, auf den in der Regel ein Block (meist 512 Byte bei FATxx) von` `der Karte eingelesen wird und sämtliche Zugriffsroutinen (Lesen,` `Schreiben, Positionieren) arbeiten auf diesem Buffer. Warum sollte dann` `also noch ein weiterer Buffer vorhanden sein, wir arbeiten doch schon im` `RAM... Ich gehe davon aus, dass es auch einen solchen internen` `Bufferbereich in euren SD-Karten-Routinen gibt. Auch` `Filezugriffsroutinen aus der libc arbeiten auch mit solchen internen` `Buffern, sonst würden die Schreib-/Leseköpfe einer Festplatte nicht zur` `Ruhe kommen.`

`Mit der Bemerkung zu atoi und strcmp hast du natürlich recht. Aus diesem` `Grund ist ersteres ganz aus dem Code verschwunden (Zahlen werden jetzt` `von Hand und sind wahrscheinlich Maschinencode-sparender umgesetzt).` `strcmp existiert natürlich noch, da eine eine eigene Implementierung` `nicht so effektiv wäre, und da gibt es noch einen kleinen Buffer (;-)),` `der so groß, wie die maximale Befehlswortlänge ist (tokenizer.c; Routine` `get_next_token()).`

`Achso, mit dem Zeilenbuffer wird auch wieder eine künstliche` `Beschränkung geschaffen, die max. Basic-Zeilenlänge ist begrenzt (ich` `gehe davon aus, dass kein malloc verwendet wird)...`

> >     Dreh- und Angelpunkt ist dabei eine Schnittstelle die als Defines
> >     realisiert ist und in den Dateien tokenizer_access.* zu finden ist. Die
> >     dortigen Defines sind von der Sache her einfach nur umzudefinieren, je
> >     nach seinem eigenen internen Routinen für die Mediumzugriffe. Ich denke
> >     der Quelltext dort ist ausreichend kommentiert in der Doku im Archiv
> >     (Kapitel 5) gibt es eine ausführlichere Beschreibung. Desweiteren sind 3
> >     Beispiele für unterschiedliche Speichermedien ausgeführt:
> >     * Zugriff wie in den bisherigen Versionen über einen Speicherbereich im RAM
> >     * Basic-Programm im PROGMEM des AVR
> >     * Basic-Programm in einer Datei und Zugriffe über fread(), fseek()...,
> >     allerdings libc und für eine Linux-Plattform.

> >     Zum Aufzeigen der Funktionsweise sollte es aber reichen, gerade das
> >     3.Beispiel dürfte am interessantesten sein...

> `Variante 2) und 3) sind auf dem ct-Bot nicht sinnvoll (Programme sollen zur Laufzeit zum Bot übertragen und dort auf SD-Karte`

`> gespeichert werden können, keine libc mit fread() usw.). Ich habe die` `Version des Interpreters, die ich von Frank bekommen hatte`

    > (da gab es nur Variante 1), wie folgt angepasst:

`bei den 3 Varianten handelt es sich, wie auch einleitend bemerkt, um` `BEISPIELE, die ich zum Testen verwendet habe. Sie sollen nur aufzeigen,` `wie diese Defines in tokenizer_access.* gemeint sind! Aber gerade das` `3.Beispiel zeigt, dass man diese Defines auch mit eigenen Funktionen` `bestückn kann. fread, fseek sind durch die Routinen zu ersetzen, die die` `gleiche bzw. ähnliche Funktionalität für eure SD-Karten-Zugriffe haben.` `Mir ist schon klar, dass es keine libc für den Bot gibt!`

`(Nebenbei, da ich es leid war, ständig meinen mega16 zu flashen, gibt es` `die Linux-Versionen des Interpreters und ist auch dann letztendlich der` `Antrieb dafür, dass er plattformunabhängig ist und bleibt.` `Wahrscheinlich analog eurem Simulator....)`

>     - Alle Änderungen, die ich am Interpreter-Code gemacht habe, sind mit einem Kommentar "ct-Bot Anpassung" versehen.

>     - Man kann eine Funktion registrieren, die (falls registriert) aufgerufen wird, bevor der Basic-Interpreter eine neue Zeile einliest:
>      http://www.heise.de/ct/projekte/machmit/ctbot/browser/devel/ct-Bot/bot-logic/ubasic_tokenizer.c#L246

> `- Das Basic-Verhalten des Bots registriert eine Funktion (der Code befindet sich somit nicht innerhalb des Basic-Interpreter-Codes),`

`> die einen RAM-Puffer mit der nächsten Zeile des Programms, das von` `der SD-Karte eingelesen wird, füllt.`

    >

`wahrscheinlich könnte man dies auch in die Defines in tokenizer_access.*` `verpacken, es muss ja nicht unbedingt p++, *p, fread, fseek o.ä.` `drinstehen. Es zählt nur das Ergebnis des jeweiligen Defines, dahinter` `könnte sich auch eine ausgeklügelte Speicherverwaltung verbergen,` `solange die "Schnittstellen-Defintionen" eingehalten werden.`

>     - Die Keyword-, Call- und CVar-Tabellen habe ich ins Flash verschoben, um RAM zu sparen.

    >

`hatte ich mir bis jetzt geschenkt, da es sich nicht lohnte` `(Speicherverbrauch klein) und Stichwort Plattformunabhängigkeit, ich` `hätte auch dort einen Define-Konstrukt einbauen müssen..., naja, kommt` `vielleicht doch noch.`

> `- Die Suche in der Call- und CVar-Tabelle hatte einen Bug: Es wurde erst strcmp() aufgerufen und anschließend der`

`> Parameter auf ungleich NULL geprüft. Da strcmp() gemäß C-Standard` `selbst nicht auf NULL prüfen muss (und das` `> je nach Plattform auch nicht tut), kam es hier zum Programm-Absturz.` `Ich habe den Check auf NULL vor den strcmp()-Aufruf`

    > verschoben.

    aha, schaue ich mir mal an und werde ich u.U. in meinen Code übernehmen.

> >     In der neuesten Version gibt es auch noch ein paar kleine Verbesserungen
> >     beim Basic-Syntax. Ich verweise mal auf das EBNF ganz hinten in der Doku,
> >     welches den vollständigen realisierten Syntax widerspiegelt.

>     Dazu kann ich leider nichts sagen, da ich weder die EBNF noch den kompletten Umfang der alten Version kenne.

`bis auf DIM (Felder), DATA (konstante Daten) und INPUT entspricht der` `zur Verfügung stehende Basic-Syntax dem damals sehr weit verbreiteten` `TinyBasic. Zum Testen habe ich ein paar alte Programme im Netz` `gesucht/gefunden und erfolgreich durch meinen Interpreter gejagt. Wobei` `ich aber gerade darüber nachdenke das angesprochene Fehlende auch noch` `einzubauen...`

> >     Für Fragen stehe ich gern zur Verfügung, sage aber gleich, dass ich keine
> >     spezielle Anpassungen für den c't-Bot einbauen werde (es sei denn, die
> >     sind auch für andere Plattformen interessant).

> `Klar, es wäre sicher auch nicht sinnvoll, ct-Bot-spezifischen Code in das allgemeine Projekt zu integrieren.` `Ich habe die Anpassung für das zeilenweise Einlesen des Programms so allgemein wie möglich gehalten, um die Änderungen am Basic-Code zu minimieren. Grundsätzlich würde ich sagen, dass diese Erweiterung auch für andere Plattformen interessant ist. Meiner Meinung nach ist eine Zeile die kleinste, sinnvolle Einheit (entsprechende RAM-Größe vorausgesetzt).` `Wenn Du das in den Basic-Interpreter einbauen möchtest, würden wir vom ct-Bot-Projekt neue Versionen leichter integrieren können, wenn nicht, ist das aber auch nicht weiter tragisch - die paar Codezeilen können wir auch leicht wieder in eine neue Version einbauen.` ``

    siehe weiter oben meine Anmerkung zu dem Thema...

> >     Speziell meine ich dabei
> >     z.B. die PRINT-Anweisung, da gab es schon heftige Diskussionen mit
> >     Frank...:-).

>     Also da würde ich das PRINTF-Makro einfach auf "vsnprintf(mein_puffer, ...); ++last_print_line;" definieren und dann kann das Basic-Verhalten im Bot-Code mit der Ausgabe anstellen, was es möchte, sobald sich last_print_line geändert hat. Ich denke, da braucht man keine besondere Anpassung im Basic-Interpreter. Weiter habe ich mich mit dem Thema aber nicht beschäftigt.

`richtig, dafür gibt es ja das Makro, Frank wollte es am Anfang nur nicht` `einsehen...`

    Grüße Uwe

- Antworten:
  - Re: [ct-bot] Basic-Interpreter (für c't - Bot)
    - From: Timo Sandmann
  - Re: [ct-bot] Basic-Interpreter (für c't-Bot)
    - From: Timo Sandmann

- Referenzen:
  - [ct-bot] Basic-Interpreter (für c't - Bot)
    - From: Uwe Berger
  - Re: [ct-bot] Basic-Interpreter (für c't - Bot)
    - From: Timo Sandmann

- Voriger (Datum): Re: [ct-bot] Basic-Interpreter (für c't - Bot), Timo Sandmann
- Nächster (Datum): Re: [ct-bot] Basic-Interpreter (für c't - Bot), Timo Sandmann
- Voriger (Thread): Re: [ct-bot] Basic-Interpreter (für c't - Bot), Timo Sandmann
- Nächster (Thread): Re: [ct-bot] Basic-Interpreter (für c't - Bot), Timo Sandmann
- Indizes:
  - Datum
  - Thread