%% -*- coding:utf-8; -*-
\renewcommand{\reftextbefore}{auf der vorherigen Seite}
\renewcommand{\reftextfacebefore}{auf der gegenüberliegenden Seite}
\renewcommand{\reftextafter}{auf der nächsten Seite}
\renewcommand{\reftextfaceafter}{auf der gegenüberliegenden Seite}
\renewcommand{\figurename}{Bild}

\begin{document}

\title{Forth auf dem Ben NanoNote}

\author{David Kühling}

\maketitle

In der 2+3-Ausgabe der Vierten Dimension berichtete Carsten Strotmann über den
OpenMoko-Wikireader, ein portables Gerät mit Open-Source-lizenzierten
Bauplänen und Software, das ein Forth enthält.

Nun möchte ich euch in diesem Artikel den großen Bruder des Wikireaders
vorstellen: den Ben NanoNote.  Gebaut wird er von Qi Hardware, einer Firma die
von ehemaligen OpenMoko-Mitarbeitern gegründet wurde.  Wie auch OpenMoko hat
sich Qi Hardware der Entwicklung von Open-Source-lizenzierter Hardware
verschrieben, und seit der Firmware-Version vom 17.$\,$11.$\,$2010 enthält der
NanoNote nun auch von Hause aus mit gForth ein vollwertiges Forth-System.

\begin{figure*}[b]
\begin{center}
\includegraphics[width=0.7\textwidth]{2010-04/nanonote.eps}
\caption{\label{Nanonote:Bild}Der Ben NanoNote im Größenvergleich mit einem
  handelsüblichen Bleistift}
\end{center}
\end{figure*}

\begin{multicols}{2}

\subsection{Eine Kreuzung aus PDA und Netbook}

Der NanoNote entspricht in der Bauweise einem stark geschrumpften Netbook.
Die Daumen-Tastatur hat ein Qwerty-Layout, bei dem die oberste Tastenreihe mit
Ziffern fehlt.  Ersetzt wird diese durch Mehrfachbelegungen der anderen
Tastenreihen.  Es gibt tatsächlich alle Sonderzeichen, die sich ein
Programmierer wünscht.

Entsprechend geschrumpft ist auch das 3-Zoll-Display.  Es bietet 320x240 Pixel
mit 24-Bit-Farbwerten.  Der 6x10-Font in der aktuellen Firmware stellt 53x24
Zeichen dar, nicht ganz ein Forth-Screen, aber doch völlig ausreichend zum
Bearbeiten von Programmen.  

Ein Mono-Lautsprecher ist eingebaut, ebenfalls ein Mikrofon.  Ein 
3.5-mm-Klinkenstecker erlaubt auch Tonausgabe in Stereo.  

Gespart wurde bei den Anschlussmöglichkeiten von Peripheriegeräten.  Lediglich
eine USB-Mini-Buchse zum Anschluss an einen PC ist vorhanden, die auch auch
zum Aufladen des Akkus dient.  Eine USB-Schnittstelle im ``Host''-Modus zum
Anschluss von USB-Geräten wird erst in einer Folgeversion des NanoNote
vorhanden sein.  Die 2GB an fest eingebautem Flash-Speicher im NanoNote können
mittels preiswerter Micro-SD Karten um bis zu 16GB aufgestockt werden.

126g bringt das Ganze, samt Lithium-Ionen Batterie, auf die Waage.  Leichter
als so manches Mobiltelefon.  Beziehen kann man den NanoNote in Deutschland
über \href{http://pulster.de}{\texttt{pulster.de}}, für 119 {\euro} plus
Versand.  Etwas günstiger erhält man ihn aus dem Ausland über
\href{http://hackable-devices.org}{\texttt{hackable-devices.org}} oder über
\href{http://tuxbrain.com}{\texttt{tuxbrain.com}}, ab einer gewissen Stückzahl
amortisieren sich dann die höheren Versandkosten.

\section{Technische Details}

Im NanoNote arbeitet ein Ingenic Xburst System-On-Chip, mit einer
MIPS32-kompatiblen CPU, getaktet auf 336 MHz, angebunden an 32 MB SD-RAM.  Die
CPU kommt ohne Fließkomma-Einheit daher, dafür ist aber eine spärlich
dokumentierte Vektor-Einheit für Multimedia-Zwecke vorhanden, die man mit
moderatem Aufwand im gForth-Assembler unterstützen könnte.

\section{Software}

Die Firmware, mit der der NanoNote ausgeliefert wird, basiert auf
OpenWRT-Linux.  Aktuelle Firmware-Versionen präsentieren nach dem Booten einen
einfachen grafischen Programmstarter.  Aber wie bei Desktop-Linuxen, kann man
mittels Strg+Alt+F2 auf eine Text-Konsole umschalten.  Stört einen die kleine
Schriftgröße der Linux-Konsole, startet man das Programm \verb|fbterm|, ein
Terminal im Terminal, das moderne Grafikbibliotheken für die
Schrift-Darstellung benutzt.  Eine Eigenheit der Linux-Text-Konsole beim
NanoNote ist, dass sie Text nicht farbig darstellen kann.  Auch dabei schafft
aber die Verwendung von \verb|fbterm| Abhilfe.

\section{Inbetriebnahme}

Zunächst bekommt der Benutzer ``root'' ein Passwort.  Um dieses zu setzen,
wechselt man per Strg+Alt+F2 auf die Konsole, und gibt ein:
\begin{verbatim}
$ passwd
\end{verbatim}
gefolgt von dem zu setzenden Passwort.  


Verbindet man den NanoNote per mitgeliefertem USB-Kabel mit einem PC, meldet
sich dieser als Netzwerkgerät an.  Jedenfalls, falls der PC unter Linux läuft,
wovon ich im Folgenden ausgehe.  Nun gibt man der PC-Seite der USB—Verbindung
die IP Adresse 192.168.254.100:
\begin{verbatim}
$ ifconfig usb0 192.168.254.100
\end{verbatim}
Und kann dann den NanoNote unter der Adresse 192.168.254.101 erreichen:
\begin{verbatim}
$ ping 192.168.254.101
\end{verbatim}
Per SSH kann man sich jetzt über Netzwerk anmelden:
\begin{verbatim}
$ ssh root@192.168.254.101
\end{verbatim}
Oder Dateien zum NanoNote kopieren
\begin{verbatim}
$ scp *.fs root@192.168.254.101:
\end{verbatim}

Wir loggen uns noch einmal auf dem NanoNote ein und starten \verb|gforth|.
Schlägt das Kommando fehl, läuft der NanoNote wohl unter einer zu alten
Firmwareversion.  Der Kasten ``Aktualisierung der Firmware'' erläutert kurz,
wie man das behebt.  Wer gForth-Quelltexte direkt auf dem NanoNote editieren
möchte, hat eine reichhaltige Auswahl an Editoren zur Verfügung: joe, jstar,
jpico, jmacs und vi, um nur einige zu nennen.

\newsavebox{\firmwareBox}
\begin{lrbox}{\firmwareBox}
\begin{minipage}{0.98\textwidth}
\begin{multicols}{2}
\section{Aktualisierung der Firmware}
Zunächst benötigen wir auf dem Host-PC die \verb|xburst-tools| zum Hochladen
der Firmware.  Fertige Ubuntu/Debian Pakete findet man hier
\cite{xburst-tools}, ebenso Tar-Files für andere Linux-Varianten.

Danach startet man den Nanonote im USB-Modus durch Drücken der Taste ``u''
beim Startvorgang (am sichersten ist es, Power+``u'' gleichzeitig einige
Sekunden gedrückt zu halten).  Der Bildschirm sollte daraufhin schwarz
bleiben, der normale Boot-Vorgang findet nicht statt.

Zum Herunterladen der neusten Firmware aus dem Netz und dem darauf folgenden
Hochladen auf den Nanonote verwendet man am besten das Shell-Skript
\verb|reflash_ben.sh|:

\begin{verbatim}
$ wget http://downloads.qi-hardware.com/\
  software/images/NanoNote/Ben/reflash_ben.sh
$ chmod +x reflash_ben.sh
$ ./reflash_ben.sh latest
\end{verbatim}

Um genau dieselbe Firmware-Version zu verwenden, die diesem Artikel zugrunde
liegt, ersetze man \verb|latest| durch \verb|2010-11-17|.  Nun benötigt man
noch einige Geduld, bis der Schreibvorgang abgeschlossen ist.

\paragraph{Warnhinweise:} Der USB—Modus des NanoNote ist nicht sehr
fehlertolerant, weswegen man für eine sichere USB-Verbindung sorgen muss.  Es
sollte kein USB—Hub verwendet werden und man sollte das hochwertige USB-Kabel
benutzen, mit dem der NanoNote ausgeliefert wurde.  Standardmäßig schreibt das
\verb|reflash_ben.sh| Skript auch den Boot-Loader neu.  Falls dabei etwas
schiefgeht, ist der NanoNote danach zunächst nicht mehr boot-fähig,
nichteinmal den USB—Modus kann man mehr aktivieren.  Ich empfehle daher,
\verb|reflash_ben.sh| so zu modifizieren, dass der Boot-Loader nicht
geschrieben wird.  Das erreicht man durch folgendes Kommando:

\begin{verbatim}
$ sed -ie 's/B="TRUE"/B="FALSE"/g' \
   reflash_ben.sh
\end{verbatim}

Zu weiteren Details zur Firmware-Aktualisierung sei auf \cite{software-image}
verwiesen.  Bei Problemen lohnt es sich auch immer, auf der 
NanoNote-Mailingliste \cite{mailinglist} nachzufragen.
\end{multicols}
\end{minipage}
\end{lrbox}

\begin{figure*}[t]
\begin{center}
\framebox{\usebox{\firmwareBox}}
\end{center}
\end{figure*}

\section{Programmieren in Forth}

Einfache Programme kann man nun nativ auf dem NanoNote verfassen und mittels
gForth ausführen.  Forth-Skripte erhält man, in dem man die Programme mit

\begin{verbatim}
#!/usr/bin/gforth
\end{verbatim}

beginnt, und diese dann mittels \verb|chmod +x| ausführbar macht.  Man ist
aber zunächst begrenzt auf den Funktionsumfang der in gForth enthaltenen
Wörter.  Insbesondere hat man keine einfache Möglichkeit, Grafik auszugeben,
das macht das ganze etwas langweilig.

Für interessantere Funktionalität benötigt man Zugriff auf die installierten
Systembibliotheken.  gForth enthält zwar eine Schnittstelle zu in C
geschriebenen Bibliotheken, jedoch benötigt diese zur Laufzeit einen
C-Compiler.  Der NanoNote enthält jedoch keinen C-Compiler in der
Standard-Firmware.

Das Ganze ist nicht so schlimm, wie es scheint.  gForth bietet nämlich dennoch
die Wörter \verb|OPEN-LIB| und \verb|LIB-SYM|, mittels derer man Bibliotheken
laden kann und die Adressen der enthaltenen Funktionen ermittelt.  Ein
Beispiel:

\begin{verbatim}
s" libc.so.0" open-lib CONSTANT libc
s" sleep" libc lib-sym CONSTANT 'sleep
'sleep HEX . DECIMAL
-> 2AB8EA60  ok
\end{verbatim}

Es fehlt dann lediglich ein Weg, diese Funktionen auch auszuführen.  Diesen
Mangel beheben wir, indem wir mit dem in gForth enthaltenen MIPS-Assembler
ein Wort zum Aufruf von C-Funktionen ergänzen.  Zum Verständnis folgt aber
zunächst ein Abstecher zum gForth-Assembler für MIPS.

\section{CODE für MIPS}
Die MIPS-CPU hat einen extrem einfachen Befehlssatz.  Die meisten CPU-Befehle
haben jeweils 3 Register als Operanden.  Der erste Operand ist das Ziel,
gefolgt von zwei Quelloperanden.  Einige Befehle benutzen statt einem Register
eine konstante 16-Bit Zahl als zweiten Quelloperanden.  In gForth werden
sowohl Register als auch konstante Operanden ohne weiteren syntaktischen
Zuckerguss als Zahlen notiert.  Ob es sich um eine Konstante oder aber um ein
Register handelt, entscheidet sich einzig und allein nach dem Namen des
CPU-Befehls.  Register 0 ist ein Dummy und liefert immer den Wert 0
bzw. verwirft alle Werte die hineingeschrieben werden.

Der Befehl \verb|1 2 3 addu,| addiert Register 2 und 3 und speichert das
Resultat in Register 1.  Der Befehl \verb|1 2 123 addiu,| addiert die
Konstante 123 zum Register 2 und legt das Resultat in Register 1 ab.

Laden und Speichern erfolgt über die Befehle \verb|lw,| bzw \verb|sw,|, die
nur einen Adressmodus kennen: der letzte Operand ist ein Register, das die
Adresse enthält, der vorletzte Operand ist eine 16-Bit-Konstante, die zur
Adresse hinzuaddiert wird.  Der erste Operand ist für \verb|lw,| das Ziel,
für \verb|sw,| die Quelle der Operation.

Sprungbefehle wie \verb|jr,| haben die Eigenart, dass der nachfolgende Befehl
erst noch ausgeführt wird, bevor tatsächlich gesprungen wird.  

Grob vereinfacht gesagt, benutzt gForth einen Fadencodeinterpreter für die
Ausführung von Forth-Code,  und so sehen Assemblerdefinitionen so aus,
wie man das auch aus anderen klassischen Forth-Systemen kennt: Argumente vom
Stack holen, Rückgabewerte auf den Stack legen, danach der Programmcode für
NEXT.

Hier z.$\,$B.\ eine \verb|CODE|-Definition von \verb|+| (funktioniert in
\verb|gforth-fast|)
\begin{verbatim}
CODE +  ( n1 n2 -- n3 )
 2   4 17  lw,      \ lade [SP+4] nach R2
 17  17  4  addiu,  \ Stackpointer inkrement
 21  2  21  addu,   \ addiere [SP+4] zum TOS
 22  0 16  lw,      \ NEXT: Lade IP
 22  jr,            \ .. springe zu [IP]
 16  16  4  addiu,  \ .. inkrementiere IP um 4
END-CODE
\end{verbatim}
Die schlechte Nachricht ist jedoch, dass gForth in C geschrieben ist, damit
die Zuordnung der Forth—Register zu Maschinenregistern automatisch vom
C-Compiler vorgenommen wurde und je nach Version variiert.  Das eben gegebene
Beispiel für \verb|+| funktioniert deswegen nur mit \verb|gforth-fast|, und
nicht mit \verb|gforth|.  Auch wird es eventuell nicht in neueren gForth
Versionen funktionieren.

Seit Neustem gibt es in gForth deswegen eine alternative Möglichkeit,
Maschinencodedefinitionen zu schreiben, die mit einer standardisierten
Registerbelegung aufgerufen werden.  Benutzt wird dabei die Konvention für
Funktionsaufrufe des C-Compilers.  Das heißt, der Maschinencode, den man
schreibt, entspricht einer C-Funktion mit dem Prototypen
\begin{verbatim}
 void *funktion(void *sp);
\end{verbatim}
Der Forth-Stackpointer geht als Argument herein; zurückgeliefert wird der neue
Wert des Stackpointers\footnote{Das ist nur die halbe Wahrheit.  In
  Wirklichkeit ist der Funktions-Prototyp
  \texttt{void *funktion(void *sp, double **fp);} und ermöglicht damit auch
  Zugriff auf den Fließkommazahlenstack.  Da uns Fließkomma aber hier nicht
  interessiert, wollen wir uns von derartigen Details nicht ablenken lassen.}.

Definitionen dieser Art werden mit \verb|ABI-CODE| statt \verb|CODE|
eingeleitet.  Dazu muss man jetzt nur noch wissen, dass bei
C-Funktionsaufrufen auf MIPS-CPUs, die ersten 4 Argumente in Registern 4--7
übergeben werden und für Rückgabewerte die Register 2--3 dienen.  Als
temporäre Register, die nicht gesondert gesichert werden müssen, sind Register
8--15 ausgewiesen.  Die Rücksprungadresse nach Funktionsaufrufen liegt in
Register 31, Register 29 enthält den C-Stackpointer.

Eine portable Definition für \verb|+| sieht somit wie folgt aus:
\begin{verbatim}
ABI-CODE +  ( n1 n2 -- n3 )
 8  4 4  lw,     \ lade [SP+4] nach R8
 9  0 4  lw,     \ lade [SP] nach R9
 8  8  9  addu,  \ R8 = R8+R9
 8  4 4  sw,     \ Resultat in [SP+4] speichern
 31  jr,         \ Funktions-Return
 2  4  4  addiu, \ SP+4 als neuer SP zurück
END-CODE
\end{verbatim}

\section{Aufruf von Bibliotheksfunktionen}
Nun können wir versuchen, mit einem einfachen Maschinencode-Wort eine Brücke
zu Bibliotheksfunktionen zu bauen.  Als ersten Versuch rufen wir die Funktion
\verb|sleep| auf.  Ein Argument wird übergeben: die Zeit, die
\verb|sleep| schlafen soll.  Auf der Forth-Seite übergeben wir dieses Argument
und dazu noch die Adresse der Funktion über den Forth-Stack.  Das Argument
laden wir in Register 4, die Adresse gehört in Register 25, bevor wir die
Funktion anspringen.  Register 25 zu verwenden, ist wichtig, da
Bibliotheksfunktionen aus positionsunabhängigen Maschinencode bestehen, der
unter der Annahme kompiliert wurde, dass die Adresse der aktuellen Funktion
immer in Register 25 vorzufinden ist.

Unser Brückenwort sieht also so aus:
\begin{verbatim}
ABI-CODE call1   ( x fn-addr -- )
 29  29  -8  addiu,  
 31   0 29  sw,  \ Rücksprungadresse sichern
 4    4 29  sw,  \ Forth-SP sichern
 25  0 4  lw,   \ lade [SP] nach R25
 4   4 4  lw,   \ lade [SP+4] nach R4
 31  25  jalr,  \ Funktionsaufruf
 nop,
 31   0 29  lw,  \ widerherstellen R31, R4
 4    4 29  lw,  
 29  29 8  addiu,
 31  jr,         \ Funktions-Return
 2    4  8 addiu,  \ SP+8 zurück
END-CODE
\end{verbatim}

Wir testen, ob es funktioniert:
\begin{verbatim}
10 'sleep call1
\end{verbatim}
tatsächlich: die Ausführung benötigt genau 10 Sekunden.

Das Ganze lässt sich auf Funktionen mit Rückgabewerten und beliebig vielen
Argumenten verallgemeinern.  Listing \verb|funcall.fs| enthält den
entsprechenden Code für mehrere Brückenwörter, die verschiedene
Argumentanzahlen unterstützen.  Nun können wir z.B. vereinfacht schreiben:
\begin{verbatim}
s" printf" libc lib-sym CONSTANT 'printf
s\" Hello World %i\0" DROP 123 
'printf void(2xint)
-> Hello World 123 ok
\end{verbatim}
Wir benutzen hierbei \verb|S\"..\0" DROP| statt \verb|S""|, da C
Null-terminierte Strings erwartet.

\section{Ein bisschen Zuckerguss}
Um nicht für jede C-Funktion die Adresse erst mit \verb|LIB-SYM| zu ermitteln,
dann für jeden Aufruf das richtige Brückenwort \verb|void(int)| etc.  benutzen
zu müssen, schaffen wir uns eine Reihe von import-Wörtern.

Diese ermitteln die Adresse für eine C-Funktion, und definieren ein Forth-Wort
gleichen Namens, das den Aufruf per Brückenwort übernimmt.  Der entsprechende
Code findet sich im Listing \verb|import.fs|.  Wir können jetzt ganz kompakt
schreiben:
\begin{verbatim}
s" libc.so.0" open-lib current-lib !
void(int): sleep
void(2xint): printf
1 sleep
-> ok
s\" hello world %i\0" DROP 123 printf
-> hello world 123 ok
\end{verbatim}

\section{Handwerkszeug}
Jetzt importieren wir die grundlegenden Linux-Systemfunktionen, die notwendig
sind, um auf das Grafik-Gerät zuzugreifen.  Wir benötigen \verb|fileno|, das
zu einem mit \verb|OPEN-FILE| generierten Dateihandle den zugehörigen 
Linux-Dateideskriptor ermittelt.  Außerdem benutzen wir \verb|mmap| zum Einblenden
von Gerätespeicher in den gForth-Prozess, und \verb|ioctl| um mit 
Linux-Gerätetreibern zu reden.
\begin{verbatim}
s" libc.so.0" open-lib current-lib !
int(int): fileno  ( fid -- fd )
int(3xint): ioctl  ( fd n1 x1 -- n2 )
int(6xint): mmap ( n1 fd a1 n2 x1 x2 -- a2 )
\end{verbatim}

Dies und ein paar weitere Konstanten für die Nutzung von \verb|mmap| finden sich
im Listing von \verb|linux.fs|

\section{Es wird grafisch}
\begin{figure*}[bt]
\begin{center}
\includegraphics[width=0.7\textwidth]{2010-04/mandelbr.eps}
\caption{\label{Nanonote:Apfelmann}Wir zaubern mit gForth ein Apfelmännchen auf den Nanonote-Bildschirm}
\end{center}
\end{figure*}

Das Fundament ist gelegt.  Jetzt können wir auf die Linux-Grafik-Gerätedatei
\verb|/dev/fb0| zugreifen.  Das ist sogar noch einfacher als es klingt.  Blenden wir mit \verb|mmap| den
zu \verb|/dev/fb0| gehörenden Speicher in unseren Prozess ein, erhalten wir
Zugriff auf den Videospeicher:
\begin{verbatim}
 s" /dev/fb0" R/W OPEN-FILE THROW fileno 
 CONSTANT fb
 0   fb   0   320 240 * 4 * 
 PROT_READ PROT_WRITE OR  MAP_SHARED 
 mmap  CONSTANT video-mem
\end{verbatim}
\verb|video-mem| zeigt jetzt auf den Anfang des Grafikspeichers.  4 Byte pro
Pixel: ein ungenutztes Byte, dann rot, grün, blau.  320x240 Pixel, von links
nach rechts und oben nach unten.  Um den Bildschirm rot zu färben, geben wir
ein:
\begin{verbatim}
: makered  ( -- )
   320 240 * 4 * 0 DO  
      $FF0000 video-mem I + ! 
   4 +LOOP ;   makred
\end{verbatim}
Es wird jedoch nicht alles Rot.  Der Textcursor blinkt weiterhin und
hinterlässt ein schwarzes Kästchen.  Ein Aufruf von \verb|ioctl| sagt dem
Linux-Kernel, dass unsere Konsole im Grafikmodus laufen soll, und deaktiviert
den störenden Cursor:
\begin{verbatim}
 s" /dev/tty" R/W OPEN-FILE THROW fileno 
 CONSTANT console
 console KDSETMODE KD_GRAPHICS ioctl  DROP
\end{verbatim}
Die vollständigen Grafikroutinen finden sich im Listing \verb|grafik.fs|.
Falls wir per SSH-Login arbeiten, ersetzen wir \verb|/dev/tty| mit
\verb|/dev/tty2| und drücken auf der NanoNote-Tastatur Ctrl+Alt+F2 um die
zweite Konsole sichtbar zu machen.

\section{Ein Apfelmännchen}
Um die Grafik in Aktion zu erleben, wollen wir nun mit gForth ein
Apfelmännchen (das Mandelbrot-Fraktal) auf den Bildschirm zaubern.  Wie
erwähnt, besitzt der NanoNote keine Fließkommaeinheit, und die Verwendung der
Softwareemulation würde unser Programm extrem verlangsamen.

Stattdessen verwenden wir eine einfache Festkommaarithmetik.  Wir benutzen
dafür die 32-Bit Ganzzahlen von gForth, und rechnen so, als wäre in der Mitte
das Komma gesetzt.  Addition und Subtraktion funktionieren dann weiter wie
gewohnt.  Lediglich nach einer Multiplikation müssen wir das Komma um 16
Binärstellen korrigieren.  Die Festkommamultiplikation sieht also so aus:
\begin{verbatim}
: fix*  ( fix1 fix2 -- fix3 )
   M* 16 lshift swap 16 rshift or ;
\end{verbatim}
Das gesamte Apfelmännchen-Programm findet sich im Listing \verb|mandelbr.fs|.
Um das Ganze mit maximaler Geschwindigkeit darzustellen, nutzt man folgendes
Kommando:
\begin{verbatim}
gforth-fast --dynamic ./mandelbr.fs
\end{verbatim}
Das Ganze dauert nur 3 Sekunden, und hinterlässt ein Apfelmännchen samt
blau-rot schimmernder Kontur auf dem Bildschirm.  \figurename
\vref{Nanonote:Apfelmann} lässt erahnen, wie das in Natura aussieht.

\section{Der Hardware an den Kragen}
Ganz nebenbei haben wir uns mit den grafischen Spielereien auch die Grundlage
für ernsthaftere Hardware-Basteleien mit dem NanoNote geschaffen.  Unten im
Batteriefach liegen ein paar Lötpunkte für I/O Leitungen, die direkt an der
CPU hängen.  Auch die Leitungen des Micro-SD Ports entspringen direkt der
CPU und lassen sich zu generischen I/O Leitungen umfunktionieren.

Dazu benötigen wir Zugriff auf die entsprechenden Steuerregister der CPU, die
alle auf \textit{physikalischen} Speicheradressen liegen.  Unter Linux sehen
wir aus gForth heraus zunächst aber nur \textit{logische} Adressen, mit
\verb|@| und \verb|!| kommen wir also so einfach nicht weiter.

Der Trick ist, dass wir per \verb|mmap| unter Verwendung der speziellen
Gerätedatei \verb|/dev/mem| dennoch beliebige physikalische Adressbereiche in
den gForth Speicherbereich einblenden können.  Ein Blick ins Datenblatt
\cite{jzdatasheet} offenbart, dass die für uns interessanten Register zur
Steuerung der I/O Leitungen bei Adresse $10010000_h$ beginnen.  An die Arbeit:
\begin{verbatim}
 s" /dev/mem" R/W OPEN-FILE THROW fileno 
 CONSTANT mem
 $10010000   mem  0  4096   
 PROT_READ PROT_WRITE OR   MAP_SHARED
 mmap CONSTANT gpio-base
\end{verbatim}
Die Adressen ab \verb|gpio-base| referenzieren jetzt den gefragten
physikalischen Speicher.  Zum Test lesen wir den Status der I/O Pins, an der
die Tastatur hängt.  Laut Schaltplänen \cite{nanonotebp,nanonotegpio} liegen
diese an Port D, an Adresse $\verb|gpio-base|+300_h$:
\begin{verbatim}
 : test  BEGIN 
    gpio-base $300 + @ hex. 10 ms 
   AGAIN ;   test  \ Abbruch mit Ctrl+C
\end{verbatim}
Drücken wir ein paar Tasten, können wir beobachten, wie der Pin-Status sich
entsprechend ändert.

Etwas komplizierter ist es, den Pegel von Pins aktiv zu setzen.  Dafür müssen so
einige Hardware-Register gesetzt werden.  Fertige Routinen finden sich im
Listing \verb|gpio.fs|.  Testweise erwecken wir damit den eingebauten Buzzer
zum Leben, der mit Pin 27 an Port D angesteuert wird (übrigens nicht zu
verwechseln mit dem ebenfalls vorhandenen Lautsprecher):
\begin{verbatim}
 io-init
 27 #output port-D io-direction
 : click  27 port-D io-0pin! ;
 : clack  27 port-D io-1pin! ;
 : buzz  BEGIN click 1 ms clack 1 ms AGAIN ;
 buzz   \ Abbruch mit Ctrl+C
\end{verbatim}

Das Ganze erinnert an die Verwendung des PC-Parallelports zur
Hardwaresteuerung.  Allerdings verwenden die I/O-Pins des NanoNote 3-V-Pegel,
und sind um mehrere Größenordnungen schneller als ein Parallelport.  Auf der
Mailingliste \cite{mailinglist} gibt es Berichte, nach denen bitweise mehrere
MBit/s zu externer Hardware übertragen wurden.  Wer weiß, was man so mit
gForth noch alles zusammengebaut bekommt.
  
\end{multicols}

\renewcommand*{\refname}{Links}
\begin{thebibliography}{5}%
\renewcommand{\figurename}{Listing}%
\bibitem{xburst-tools}\textsl{Xburst-Tools zum Brennen der Firmware}, 
\url{http://projects.qi-hardware.com/index.php/p/xburst-tools/downloads/}
%
\bibitem{software-image}\textsl{Informationen zur Firmware und zum Firmware Upgrade},
\url{http://en.qi-hardware.com/wiki/Official_Software_Image}
%
\bibitem{mailinglist}\textsl{Mailingliste zur Diskussion über den NanoNote},
\url{http://lists.en.qi-hardware.com/mailman/listinfo/discussion}
%
\bibitem{jzdatasheet}\textsl{Vollständige Dokumentation des System-On-Chip im Nanonote},
\url{http://www.gmun.unal.edu.co/cicamargoba/embebidos/Jz4725_pm.pdf}
%
\bibitem{nanonotebp}\textsl{Schaltpläne des NanoNote (korrekterweise:
  Schaltpläne der noch nicht gebauten nächsten Hardwarerevision)}
\url{http://downloads.qi-hardware.com/hardware/qi_avt2/v1.0/orcad_sch/qi_avt2_v1.0.pdf}
%
\bibitem{nanonotegpio}\textsl{Belegung der I/O Leitungen im NanoNote}
\url{http://en.qi-hardware.com/wiki/Hardware/Ben#GPIO_pins}
%
\end{thebibliography}

%\newpage

\section{Bibliotheksfunktionen aufrufen --- \texttt{funcall.fs}}
\begin{small}
\begin{quote}
\listinginput[1]{1}{2010-04/funcall.fs}
\end{quote}
\end{small}

\section{Bibliotheksfunktionen nach Forth importieren --- \texttt{import.fs}}
\begin{small}
\begin{quote}
\listinginput[1]{1}{2010-04/import.fs}
\end{quote}
\end{small}

\section{Import von Linux Systemfunktionen --- \texttt{linux.fs}}
\begin{small}
\begin{quote}
\listinginput[1]{1}{2010-04/linux.fs}
\end{quote}
\end{small}

\section{Zugriff auf den Grafikspeicher --- \texttt{grafik.fs}}
\begin{small}
\begin{quote}
\listinginput[1]{1}{2010-04/grafik.fs}
\end{quote}
\end{small}

\section{Zeichnen eines Apfelmännchens --- \texttt{mandelbr.fs}}
\begin{small}
\begin{quote}
\listinginput[1]{1}{2010-04/mandelbr.fs}
\end{quote}
\end{small}

\section{Zugriff auf die I/O Ports --- \texttt{gpio.fs}}
\begin{small}
\begin{quote}
\listinginput[1]{1}{2010-04/gpio.fs}
\end{quote}
\end{small}
\end{document}

% Local Variables:
% ispell-local-dictionary : "de-neu"
% compile-command: "make -C .."
% coding : utf-8
% End:

