Hab' gerade mein Forth zusammen mit einer GPLv3-Lizenz auf github
gekippt:
https://github.com/anse1/stubforth
Schwerpunkte waren Portabilität, Erweiterbarkeit und Integration mit
C-Code. Wenn GCC die Zielarchitektur unterstützt, ist zum Portieren
lediglich das Erstellen eines Linker-Skriptes und das Schreiben von
getchar/putchar und etwas Startup-Assembler nötig. Auf den
existierenden Ports bin ich meist noch etwas weiter gegangen, weil ich
Interrupt-Handler in Forth schreiben und laufende Forth-Programme mit
einem line break unterbrechen können wollte. (Im Stellaris Launchpad in
meinem RepRap steckt z.B. ein Forth-Temperaturregler im ADC-Handler)
Im Einsatz hab' ich es auf diversen ARM-Eval-Boards (STM32F4discovery,
Stellaris Launchpad/Evalbot), einem Router (Hitachi SH3),
m68k-PDA-Schrott (Vivonic) und MSP430. Für letzteren greife ich aber
selbst lieber zu Camelforth.
Auf ausgewachsenen Rechnern läuft es auch, was das Erweitern und Testen
von Plattformunabhängigen Code recht komfortabel macht.
Details siehe README und Code.
Gruß
Andreas
> welche CPU aus der SH3-Serie ist es denn?
Ist eine HD6417708R. Mitgeliefert(es/er) Linker-Skript/Startup-Code ist
allerdings spezifisch für den Lancom-Bootloader (Details im README).
Danke fuer die Info.
Ich hab hier noch ein SH3-Board mit einem HD6417709A aka SH7709A.
Das im Moment einen Monitor in seinem Flash.
Welchen GCC in welcher Umgebung benutzt Du zum kompilieren?
Hallo Andreas,
meiner Meinung nach fehlt noch eine Step by Step Anleitung, wie Dein
Forth zu kompilieren und zu installieren ist.
Kannst Du ein Beispiel für ein STM32F4 Discovery machen?
Gruß,
chris_
> Ich hab hier noch ein SH3-Board mit einem HD6417709A aka SH7709A.> Das im Moment einen Monitor in seinem Flash.
Hört sich nach einem idealen Target an. Gerade um unbekannte Systeme
kennen zu lernen, und interaktiv und automatisiert in MMIO-Registern
herumzustochern finde ich Forth ungeschlagen.
> Welchen GCC in welcher Umgebung benutzt Du zum kompilieren?
Ich hab' damals einfach einen cross-gcc und cross-binutils für sh-elf
aus den offiziellen Quellen auf meinem GNU-System gebaut. Konkrete
Version sollte nebensächlich sein, nur zu alt sollten sie nicht sein, da
GCC auf SH3 mal einen Bug hatte (Die wegen SH3s delayed branch
u.U. nötige NOP-Instruktion wurde in Interrupthandlern nicht erzeugt).
tengen:~/src/stubforth$ sh-elf-as --version
GNU assembler (GNU Binutils) 2.23.2
tengen:~/src/stubforth$ sh-elf-gcc --version
sh-elf-gcc (GCC) 4.8.2 20130914 (prerelease)
> Kannst Du ein Beispiel für ein STM32F4 Discovery machen?
Auf einem GNU/Linux-System mit installiertem GNU m4, arm-gcc und
-binutils sollte
git checkout arm/stm32
make
ein stubforth.elf liefern, welches man mit dem lieblingstool in den
Flash des stm32f4-Boards schreiben kann.
Das stubforth meldet sich dann auf UART2.
> Schritt für Schritt wird es klarer ... ich kannte M4 nicht:
Ich hatte leider keine Möglichkeit gefunden, statisch das
Forth-Wörterbuch ähnlich elegant (beispiel im README) mit dem
C-Präprozessor aufzubauen, daher hab' ich zu m4 als Präprozessor
gegriffen. Ist unter unixartigen Systemen weit verbreitet.
chris_ schrieb:> Aber leider erhalte ich:
[...]
> /usr/bin/ld: warning: cannot find entry symbol main; defaulting to
000000000040010c
Konnte ich im Moment mit meinem Debian Jessie nicht reproduzieren - ich
werde mir mal bei Gelegenheit eine Ubuntu-VM basteln, und versuchen, das
nachzustellen.
Du verwendest hier aber auch gerade einen der abenteuerlichen Zweige:
x86_64/linux redet direkt mit dem Kernel, statt mit der libc.
Da du bereits ein gehostete C-Umgebung hast, sollte der master- bzw.
posix-Zweig etwas robuster für deine Zwecke sein.
Gruß
Andreas
Ok, ich probiers:
christoph@BigTowerQuadCore:~/Entwicklung/c/stubforth/stubforth$ git
checkout posix
Branch posix konfiguriert zum Folgen von Remote-Branch posix von origin.
Gewechselt zu einem neuen Branch 'posix'
christoph@BigTowerQuadCore:~/Entwicklung/c/stubforth/stubforth$ make
....
gcc -O2 -g -Wall -Wcast-align -ldl -o stubforth stubforth.o
stubforth.o: In Funktion `vm':
/home/christoph/Entwicklung/c/stubforth/stubforth/platform.m4:18: Nicht
definierter Verweis auf `dlerror'
...
/home/christoph/Entwicklung/c/stubforth/stubforth/platform.m4:12: Nicht
definierter Verweis auf `dlerror'
collect2: error: ld returned 1 exit status
make: *** [stubforth] Fehler 1
christoph@BigTowerQuadCore:~/Entwicklung/c/stubforth/stubforth$ ^C
Hallo chris_,
chris_ schrieb:> /home/christoph/Entwicklung/c/stubforth/stubforth/platform.m4:18: Nicht> definierter Verweis auf `dlerror'
kann ich auf meinem Debian Jessie ebenfalls nicht reproduzieren.
Ich werd' mir morgen ein Ubuntu 14 besorgen (hab' heute kein anständiges
Internet).
Ich hab' aber mal spekulativ die Linkerflags umgestellt; mit etwas Glück
tut es deinerseits nach einem "git pull ; make".
Btw, dlopen & co wird im master-Zweig nicht verwendet, da kann dieses
Problem schonmal nicht mehr auftreten.
Gruß
Andreas
Hallo chris_,
chris_ schrieb:> /home/christoph/Entwicklung/c/stubforth/stubforth/platform.m4:12: Nicht> definierter Verweis auf `dlerror'
hab' mittlerweile eine Ubuntu-VM, und kann bestätigen, dass die letzte
Änderung (d063437) das Problem mit dem posix-Zweig beseitigt hat.
Gruß
Andreas
Ok, ich habe das repository mit
git pull
"geupdated". Es lässt sich jetzt kompilieren.
Wenn ich es aber mit
./stubforth
laufen lassen will, erhalte ich folgendes:
opening dataspace read-write: No such file or directory
try dd if=/dev/zero of=$HOME/.stubforth count=10k
Hallo chris_,
erstmal sorry für die schrecklich undokumentierte Natur des ganzen.
chris_ schrieb:> try dd if=/dev/zero of=$HOME/.stubforth count=10k
Der POSIX-Zweig hat das Feature, dass Wörterbuch und dataspace mittels
mmap persistiert werden. Das vorgeschlagene dd-Kommando legt einen
leeren dataspace an.
,----
| ex:~/src/stubforth$ dd if=/dev/zero of=$HOME/.stubforth count=10k
| 10240+0 records in
| 10240+0 records out
| 5242880 bytes (5,2 MB) copied, 0,0323279 s, 162 MB/s
`----
Während der Sitzung kann man dann mittels "sync" den Zustand auf Platte
schreiben. Hier ist ein Beispiel, wie man z.B. den Forth-Code in
user.4th dort rein bekommt (Enthält z.B. einen disassembler (Wort
"see")):
,----
| ex:~/src/stubforth$ ./stubforth
| stubforth d063437
| see if \ disassembler ist nicht im statisch einkompilierten Wörterbuch
| abort: invalid numeric argument
| ex:~/src/stubforth$ ( cat user.4th ; echo sync ) | ./stubforth
| stubforth d063437
| ex:~/src/stubforth$ ./stubforth
| stubforth d063437
| see if
| .code: &&enter
| .immediate: -1
| .data:
| 804bc10 lit
| 804bc14 0branch
| 804bc18 ,
| 804bc1c here
| 804bc20 0
| 804bc24 ,
| 804bc28 exit
`----
Gruß
Andreas
Hallo Andreas,
jetzt läuft es bei mir. Vielleicht wäre eine Textdatei als
Systemspeicher einfacher zu nutzen, weil man diese nicht mit dd anlegen
müsste.
Ich vermisse etwas ein do .. loop für das Standardbeispiel:
: TEST 10 0 DO CR ." Hello " LOOP ;
von
http://www.forth.com/starting-forth/sf6/sf6.html
Hallo chris_,
ich hab' Worte bisher immer nur nach Bedarf implementiert... stubforth
kommt daher im Moment nur mit begin...while...repeat, begin...until und
begin...again-Schleifen.
Das schöne an Forth ist aber, dass man durch neue Worte quasi die
Sprache selbst erweitert. z.B. kann man DO...LOOP unter Verwendung der
oben genannten Standardkonform implementieren:
1
: do postpone swap postpone 2>r postpone begin postpone 2r@ postpone > postpone while ; immediate