Forum: Projekte & Code Portables C-Forth mit Ports für ARM/m68k/SH3


von ansel (Gast)


Lesenswert?

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

von ./. (Gast)


Lesenswert?

> einem Router (Hitachi SH3)

welche CPU aus der SH3-Serie ist es denn?

von Andreas S. (ansel)


Lesenswert?

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

von ./. (Gast)


Lesenswert?

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?

von chris_ (Gast)


Lesenswert?

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_

von chris_ (Gast)


Lesenswert?

Schritt für Schritt wird es klarer ... ich kannte M4 nicht:

http://www.seindal.dk/rene/gnu/whatis.htm

welches Du wohl verwendest ...

von Andreas S. (ansel)


Lesenswert?

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

von Andreas S. (ansel)


Lesenswert?

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

von chris_ (Gast)


Lesenswert?

Danke für die Antwort.

Auf meinem Ubuntu 14.04 64 bit ist GIT installiert. Ich habe mal 
folgendes gemacht:

1. stubforth von GitHub herunterladen

 git clone https://github.com/anse1/stubforth.git

2. Den Branch für 64 bit Linux auswählen

 git checkout x86_64/linux

3. kompileren

 make

Aber leider erhalte ich:

christoph@BigTowerQuadCore:~/Entwicklung/c/stubforth/stubforth$ make
echo -n \#define REVISION \"  > .rev.h
echo -n $(git describe --always --dirty) >> .rev.h
echo -n '"' >> .rev.h
gcc -O2 -ffreestanding -nostdlib -Wl,-emain -static -o stubforth.o -c 
stubforth.c
gcc -O2 -ffreestanding -nostdlib -Wl,-emain -static -o stubforth 
stubforth.o
/usr/bin/ld: warning: cannot find entry symbol main; defaulting to 
000000000040010c

von Andreas S. (ansel)


Lesenswert?

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

von chris_ (Gast)


Lesenswert?

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

von Andreas S. (ansel)


Lesenswert?

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

von Andreas S. (ansel)


Lesenswert?

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

von chris_ (Gast)


Lesenswert?

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

von ansel (Gast)


Lesenswert?

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

von chris_ (Gast)


Lesenswert?

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

von ansel (Gast)


Lesenswert?

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
2
: loop postpone r> postpone 1+ postpone >r postpone repeat postpone 2r> postpone 2drop ; immediate
3
: i 2r@ drop ;
4
: cr lf ; \ uups, CR kennt stubforth auch nicht...
5
sync \ persistent machen

Damit läuft dann das Beispiel minus Großschreibung.

LOOP+ und J zu implementieren überlasse ich mal als Übungsaufgabe :-)

Gruß
Andreas

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.