% Content-encoding: UTF-8 \documentclass[ngerman]{article} \usepackage[utf8]{inputenc} \usepackage{multicol} % \usepackage{babel} \usepackage{xspace} \setcounter{secnumdepth}{0} \setcounter{tocdepth}{0} \usepackage{german} %\newcommand{\code}[1]{\texttt{#1}} %\newcommand{\ret}{\textsf{$<$ret$>$}\xspace} %\newcommand{\ret}{$\hookleftarrow$\xspace} \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{\reftextfaraway}[1]{auf Seite \pageref{#1}} \renewcommand{\figurename}{Bild} \title{CamelForth im FRAM des TI–MSP430FR5739} \ifx\shorttitle\undefined\else \shorttitle{CF430FR V0.2} \fi \author{M. Kalus} \begin{document} \maketitle Neulich teilte mir Dirk Brühl, unser Forthfreund in den USA, mit, dass es von Texas Instruments (TI) eine MCU gäbe, die FRAM statt flash als permanenten Speicher hat. Und dass dieses FRAM genau wie SRAM gelesen und geschrieben werden kann. Und dass diese MSP430--Prozessor--Familie einen zusammenhängenden Adressbereich hat. RAM, aber nicht-flüchtig? Klingt nach einer idealen Forth--MCU. Umfragen ergaben, dass noch kein Forth dafür vorhanden war. Aber es gab ein kleines kompaktes Forth für die MSP430--Familie, das CamelForth/430 aus 2009 von Bradford J. Rodriguez für das Tini430--board mit dem MSP430F1611--Chip, es legt den Forthkern im \emph{flash} an, compilierte neue Forth--Worte jedoch ins RAM. Das müsste doch einfach auf das \emph{FRAM} zu portieren sein, dachte ich. Zumal TI ein feines preiswertes FRAM--Experimentierboard beigesteuert hat, das MSP-EXP430FR5739, um alles auszuprobieren. \bigskip \begin{multicols}{2} Dieses Platinchen steckt man einfach an ein USB--Kabel zum PC und alles klappt - die Stromversorgung, die serielle Schnittstelle zum Terminal und die Programmierschnittstelle. Alle drei wurden über den einen USB--Anschluss realisiert, eine mustergültige Lösung, die TI hier vorführt. Die Forth--Gesellschaft hat inzwischen 3 Exemplare des MSP-EXP430FR5739 in den Verleih genommen. Wer damit also spielen möchte, kann dies praktisch kostenlos tun. Viel Vergnügen damit. \begin{figure} \begin{center} \includegraphics[width=\textwidth]{2012-01/fr-bild1} \caption{\label{fr-bild1}MSP-EXP430FR5739} \end{center} \end{figure} \section{CamelForth/430} Dieses kleine Forth kommt aufgeräumt in 5 Dateien daher. Die CPU und Forth--Modell--abhängigen Worte sind in der Datei \emph{deps430FR5739.s43} versammelt, und in \emph{core430FR5739.s43} stehen die Low--Level--Routinen. Die übrigen ANS--kompatiblen Forth--Worte findet man in \emph{hilvl430FR5739.s43} und die Initialisierung der MCU und des Forth selbst ist im File \emph{init430FR5739.s43} niedergelegt, also das, was nach reset als erstes durchlaufen wird. Die Interruptvektoren sind übersichtlich in \emph{vecs430FR5739.s43} versammelt, auch der \emph{reset}--Vektor wird dort gesetzt. Rodriguez benutzte die IAR Systems MSP430 Workbench, \glqq{}Kickstart\grqq{} genannt, für das CamelForth/430. Sein Projekt wurde wie es war probeweise im IAR compiliert, was auf Anhieb fehlerfrei ging. Sodann wurde das Demoprogramm von TI als Projekt in die IAR geladen, um die Verbindung zum MSP-EXP430FR5739 zu erproben. Auch das funktionierte sofort einwandfrei über den USB. Das Demopropgram erwies sich dann als eine wichtige Quelle für die forthige Initialisierung der MCU. \section{Speicher im MSP430FR5739 im Vergleich zum MSP430F1611} Wir bekommen derzeit 16KB FRAM im MSP430FR5739. CamelForth brauchte davon 6KB, passt also erstmal dort hinein. \begin{small} \begin{alltt} ; MEMORY MAP of the \emph{MSP430FR5739} ; 0000-0FFF = peripherals (4 KB) ; 1000-17FF = bootstrap loader BSL0..3 (ROM 4x512 B) ; 1800-187F = info B (FRAM 128 B) ; 1880-18FF = info A (FRAM 128 B) ; 1900-19FF = N/A (mirrored into info space) ; 1A00-1A7F = device descriptor info (FRAM 128 B) ; 1A80-1BFF = unused (385 B) ; 1C00-1FFF = RAM (SRAM 1 KB) ; 2000-C1FF = unused (41472 B) ; C200-FF7F = code memory (FRAM 15743 B) ; FF80-FFFF = interrupt vectors (FRAM 127 B) \end{alltt} \end{small} \begin{figure} \centering \includegraphics[width=\textwidth]{2012-01/fr-fram1} \caption{FRAM} \end{figure} Der MSP430F1611 bietet deutlich mehr Speicher, sowohl Ram als auch Flash. Und ist damit sicherlich eine für Forth interessante MCU. Das dürfte auch der Grund gewesen sein für Rodriguez, sein CF auf dies MCU zu bringen. Doch finde ich das FRAM so interessant, dass CF einfach darauf ausprobiert werden musste. \begin{small} \begin{alltt} ; MEMORY MAP of the \emph{MSP430F1611} ; 0000-01FF = peripherals ; 0200-09FF = 2KB mirrored RAM ; 0A00-0BFF = unused ; 0C00-0FFF = 1KB boot memory ; 1000-10FF = 256B information memory ; 1100-18FF = 2KB mirrored RAM ; 1900-38FF = 8KB RAM ; 3900-3FFF = unused ; 4000-FFFF = 48KB flash ROM ; FFE0-FFFF = interrupt vectors \end{alltt} \end{small} \section{Was zu tun war, um die ersten Lebenszeichen des CF430FR zu erhalten.} Zunächst wurde mit den Dateien des CamelForth/430 das CF430FR als neues Projekt im IAR angelegt. Darin wurden dann alle Forthworte, die für den flash-Zugriff gemacht waren, auskommentiert - netterweise waren solche Worte mit einem \emph{i} für \emph{instruction memory} gekennzeichnet. Daraus folgte ein Haufen Fehlermeldungen beim \mbox{\emph{make}} wegen der nun unbekannten Namen. Etliche davon waren erfreulicherweise schon von Rodriguez als \emph{alias} angelegt worden, und konnten daher einfach umgewidmet werden, also \texttt{IHERE} zu \texttt{HERE} und \texttt{I@} zu \texttt{@} usw. Auch dabei zeigte sich, dass CF gut strukturiert ist. Weitere i-Worte mussten sodann im Quellcode aufgesucht und durch ihre gewöhnliche Funktion ersetzt werden. So wurde nach und nach eine fehlerfreie Übersetzung fertig und ließ sich in die Experimentierplatine laden, nachdem auch die Speicherzuweisungen im Code und für den Linker an die FRAM Speichersegmente angepasst worden waren. Doch es gab daraufhin leider noch kein ok vom frisch erzeugten Forth. Denn die serielle Schnittstelle war noch nicht passend konfiguriert. Dafür musste noch die Datei \emph{init430FR5739.s43} an die neue CPU angepasst werden. Die gut gemachten TI--Handbücher zum Chip und zum Experimentierboard halfen dabei weiter[1]. Insbesondere die korrekte Initialisierung der seriellen Schnittstelle zum Terminal für \texttt {KEY} und \texttt{EMIT} wurde neu geschrieben, sowie die Initialisierung der Ports, die Registerverteilung usw. Schließlich wurde noch eine kleine Testschleife ans Ende des Forthkerns hinzugeladen, die von dem IAR--Debugger durchlaufen werden konnte, und siehe da, das I/O funktionierte, und über die blauen LEDs der Platine und dann auch im Terminal wurde angezeigt, dass die Verbindung hergestellt war. \section{Die \texttt{KEY EMIT} Testschleife} Um nach dem Reset mit der Testschleife zu starten, wurde ihr vorübergehend das label INITIP zugeordnet und die Forthregister im init430FR5739.s43 dazu passend gesetzt: \begin{small} \begin{alltt} ; Forth registers MOV #RSTACK,SP ; set up stack MOV #PSTACK,PSP MOV #UAREA,&UP ; initial user pointer MOV #INITIP,IP ; testschleife MOV #0,TOS NEXT \end{alltt} \end{small} So zeigt der IP also auf die Testschleife, und startete den Test nach dem \emph{reset}. Später konnte dann statt \verb|#INITIP| das \verb|#COLD| eingesetzt werden, um mit dem Forthsystem selbst zu starten. In der endlosen Testschleife wurde einfach nur \texttt{KEY} abgefragt und per \texttt{!LEDS} an die blauen LEDs auf der Platine ausgegeben[2], und auch per \texttt{EMIT} an das Terminal. Die Schwierigkeit lag darin, das Assemblerstückchen \texttt{STORELEDS} mit dem Debugger des IAR zu testen. In der endlosen Schleife des inneren Interpreters des Forth dauerte es zu lange. Ich hab dann einfach das Codestück dem \emph{init} angehängt, so dass es beim \emph{reset} ohne das Forthsystem zu durchlaufen ausgeführt wurde. So ließ es sich einfach debuggen, zumal der IAR--Debugger den I/O mit anzeigt. Danach konnte \texttt{!LEDS} als Forthwort gefasst und in die High--Level--Testschleife einbezogen werden. \begin{footnotesize} \begin{alltt} ; TESTING 8x blue LEDs in a row. ; (portpinX->---resistor---LED---GND) ; LED1 - PJ.0 LED5 - P3.4 ; LED2 - PJ.1 LED6 - P3.5 ; LED3 - PJ.2 LED7 - P3.6 ; LED4 - PJ.3 LED8 - P3.7 ; MSP-EXP430FR5739 FRAM Experimentation board blue LEDS output. ; ( c -- ) HEADER STORELEDS,5,'!LEDS',DOCODE BIC #0x000F,&PJOUT ; LED1..4 off BIC.B #0x00F0,&P3OUT ; LED5..8 off MOV TOS,X ; X = scratch register R10 AND #0x000F,X ; don't change any but LEDs ; lower nible BIS X,&PJOUT ; set the LED bits MOV TOS,X ; X = scratch register R10 AND #0x00F0,X ; don't change any but LEDs ; higher nible BIS.B X,&P3OUT ; set the LED bits MOV @PSP+,TOS ; do_drop NEXT ; TESTING FORTH EXECUTION PUBLIC INITIP INITIP: DW KEY,DUP,STORELEDS,EMIT DW lit,0,qbran DW INITIP-$ DW bran,-2 ; INITIP equ COLD+2 lastword equ link END \end{alltt} \end{footnotesize} %$ to correct syntax highlighting \begin{figure*}[t] \begin{center} \includegraphics[width=0.9\textwidth]{2012-01/fr-screenshot} \caption{\label{fr-screenshot}IAR und CF430FR im Terminal} \end{center} \end{figure*} \section{Vom ersten Test zum ok und dann weiter} Doch obwohl nun die blauen LEDs den \texttt{KEY} zeigten und auch das \texttt{EMIT} richtig rüber kam ins Terminal, das ersehnte OK fehlte noch. Klammerte man den Test aus und setzte \texttt{INITIP equ COLD+2} in Kraft, gab es leider nichts zu sehen auf dem Terminal. Der Verdacht fiel auf \texttt{TYPE}, in dem was noch nicht stimmen konnte. So wurde zunächst mal ein \texttt{.ID} gemacht, an bekannter Adresse im FRAM, das dann von \texttt{TYPE}, welches auch in die Testschleife kam, ausgegeben werden konnte. Und als das ging, wurde \texttt{.ID} in das \texttt{COLD} eingehängt, um zu sehen ob die Ausgabe auch von dort kam. Und auch das ging nun, \texttt{TYPE} war glücklich ans FRAM angepasst worden, das OK war da. \begin{small} \begin{alltt} ;ID 0 1 2 ; 12345678901234567890 FRid: DB 15,'CamelFort V0.2 ' EVEN ; .ID -- type id HEADER DOTID,3,'.ID',DOCOLON DW CR,lit,FRid,COUNT,TYPE DW EXIT \end{alltt} \end{small} Mit dieser Erfahrung war es dann möglich, auch das Wort \verb|."| und seine Faktoren an das FRAM anzupassen, so dass auch der Klassiker \texttt{: test ." hallo world" ; } es nun im CF430FR tat. Welche Freude nächtens, wenn das dann geht! Die weiteren Versuche ergaben dann noch Fehler in \texttt{VARIABLE}, was am \texttt{CREATE} lag. \texttt{CREATE} war noch für die Harvard--Speicheraufteilung des MSP430F1611 ausgelegt gewesen, und verhielt sich wie \texttt{CONSTANT}. Das \texttt{DOCON} war der gemeinsame Code, den auch \texttt{DOVAR} sowie \texttt{docreate} nutzten. Aber es brauchte nur ein copy\&paste und darin dann genau ein einziges Zeichen weniger, um die Anpassung ans FRAM zu machen. Aus dem \begin{small} \begin{alltt} DOCON: ; -- x ; CONSTANT fetches cell ; from PFA to TOS SUB #2,PSP ; make room on stack MOV TOS,0(PSP) MOV @W,TOS ; fetch from parameter ; field to TOS NEXT \end{alltt} \end{small} wurde so zusätzlich erzeugt \begin{small} \begin{alltt} docreate: ; -- a-addr ; CREATE fetches its address DOVAR: ; -- a-addr ; VARIABLE fetches its address SUB #2,PSP ; make room on stack MOV TOS,0(PSP) MOV W,TOS ; move parameter field ; address to TOS NEXT \end{alltt} \end{small} Da im W--Register sowieso immer die nächste pfa liegt, also unsere gesuchte Adresse, braucht sie nur auf den Datenstack geschoben zu werden. Dann gab es noch den Umstand, dass der Linker des IAR die init--Datei hinter die core--Datei ins FRAM packte, also auf höhere Adressen, und damit der dictionary pointer \texttt{DP} mitten in die Initialisierung zeigte. Was solange gut ging, bis etwas neu compiliert wurde und dann ein reset oder \texttt{COLD} kam. Aber es war nicht weiter schwer, das label \texttt{ROMDICT} an das Ende von init zu verlagern, und dann ging auch das. Auch war so (erneut) bewiesen, dass man mit Forth im RAM alles machen kann, auch den eigenen Prozess abschießen. So, damit hat auch der MSP430FR5739 ein Forth und kann damit unter die Lupe genommen werden. \begin{figure} \begin{center} \includegraphics[width=\textwidth]{2012-01/fr-bild2} \caption{\label{fr-bild2}MSP430FR5739} \end{center} \end{figure} Bleibt noch zu erwähnen, dass CamelForth case--sensitiv angelegt ist, und man lauter Fragezeichen bekommt, wenn man das nicht gewöhnt ist. Es muss also \texttt{.S} heißen, und \texttt{WORDS}, also tatsächlich in Großbuchstaben, um ordentliche Ausgaben zu bekommen. \section{Bring es ans Laufen, dann mach es hübsch.} Nun da es soweit funktioniert, kann man sich überlegen, was alles noch hübscher werden sollte am CF430FR, bevor man es an Rodriguez übergibt, was ich vorhabe. So müssten Kommentare verschwinden, die noch für die \emph{Flash}--Version waren und nun ausgedient haben, andere müssten hinzu. Auch die Versionsgeschichte gehört überarbeitet. Das Verhalten des CF bei einem \emph{forth crash test} oder \emph{reset} war noch nicht zufrieden stellend. Es gab im CF nur \texttt{COLD} als Eintrittspunkt, ausgeführt nach Stromausfall oder Reset. Es fehlt noch ein ordentlicher Warmstart. Vom Forth aus hinzu kompilierte Worte sollen ja beim Neustart noch da sein. Auch müsste ein Mechanismus her, mit dem der Anwender wahlweise einen Neustart des Forthkerns durch \texttt{COLD} oder \texttt{WARM} von außen herbeiführen kann. Ferner müsste der \emph{anstest0.8} mal darüberlaufen. Daher steht die Portierung nun auch im Repository der Forth--Gesellschaft [3], und wer möchte, kann mitmachen, das CF430FR weiter zu debuggen. Die Portierung erfolgte übrigens mit Windows XP auf einem Athlon64--Prozessor--3000+ und der IAR--Kickstart--Version 5. %\hrulefill \section{Fußnoten} \begin{tabular}{lp{7cm}} {}[1] & \url{http://www.camelforth.com}\\ {}[2] & Die Idee dazu fand ich im core file des Muster CamelForth vor. !LED wurde lediglich an das vorliegende Board angepasst.\\ {}[3] & \url{http://www.forth-ev.de/repos/CF430FR}\\ \end{tabular} \end{multicols} \section{Links} \url{http://www.ti.com/ -->suchen: MSP-EXP430FR5739}\\ Es wird beworben als: "The Experimenter Board helps designers quickly learn and develop using the new MSP430FR57xx MCUs, which provide the industry's lowest overall power consumption, fast data read /write and unbeatable memory endurance."\\ \url{http://de.wikipedia.org/wiki/Ferroelectric_Random_Access_Memory}\\ %Abbildung: Muybridge_Camel_Racking.jpg \begin{figure} \begin{center} \includegraphics[width=0.6\textwidth]{2012-01/Muybridge_Camel_Racking} \caption{\label{Muybridge_Camel_Racking}Kamel im Passgang} %Quelle: \url{http://commons.wikimedia.org/wiki/File:Muybridge_Camel_Racking.gif \end{center} \end{figure} \end{document}