Forth Lesson 13: Difference between revisions

From OLPC
Jump to navigation Jump to search
(→‎Saving and loading: add missing backslash)
(not missing: "( addr len )" is an inline comment, documenting the stack)
Line 100: Line 100:
: nvread \ filename ( -- )
: nvread \ filename ( -- )
reading
reading
load-base dup h# 10000 ifd @ fgets \ ( adr len )
load-base dup h# 10000 ifd @ fgets ( adr len )
to nvramrc
to nvramrc
ifd @ fclose
ifd @ fclose

Revision as of 22:25, 21 December 2007

Mitch Bradley's Forth and
Open Firmware Lessons:

Draft

This is a draft Forth lesson based on tips received directly from Mitch Bradley. He'll hopefully fix any problems he finds offensive and then remove this notice. :-)

See also the first section of this page for editing files on an external device like a USB stick or SD card.

Review

In the previous lesson we learned that:

  • Console I/O operates directly on a framebuffer (text is rendered by Forth code)
  • OFW can boot from ELF images, Linux bzImage files, or Forth source files
  • Boot images can be explicitly loaded from either local storage devices or the network (TFTP, NFS, HTTP)

Overview

In this lesson we'll cover how to write Forth programs and save them in persistent storage on the XO.

Storage options

The OFW and EC code both reside in SPI FLASH. There is extra room there that, in principle, could be used to store user-entered stuff, but there are some practical problems. There is the risk of bricking the machine, from which recovery is possible, but extremely tedious, requiring a special dongle and an on-board connector that is often unpopulated. There is also the problem that, in order to write to the SPI FLASH, it is necessary to hold the EC's 8051 in reset (so it doesn't interfere with the programming by doing microcode instruction fetches from the same serial bus that the programming commands go over). While the 8051 is in reset, the keyboard doesn't work, and when you have finished programming, you have to restart the 8051, which resets the whole system.

OFW can write to files on FAT-16 and FAT-32 filesystems, so you can use USB keys and SD memory cards to store your own files. An SD memory card is a good choice for adding personal storage, so the examples will use filenames on the SD memory filesystem.

Text editing

OFW has a simple editor; it is the same one that is used for editing command lines, but it also works for multi-line memory buffers.

  ok nvedit
  <Edit using arrow keys or basic emacs>
  ^C
  Store script to NVRAM [y/n]? y
  ok

It doesn't really store the data to NVRAM, because the OLPC machine doesn't have any (CMOS RAM is too small, and SPI FLASH has the problems listed above). What it does is save the data in memory, where you can get it back with "nvramrc ( -- adr len )".

  ok  nvramrc .s
  ff9f4baa 3d
  ok nvramrc list
  <whatever you put in there>
  ok nvramrc evaluate
  <executes the contents of nvramrc as Forth code>
  ok nvramrc eval              \ Same as above but shorter
  ok

Saving and loading

To save it to disk, you could write this definition:

  : nvwrite  \ filename  ( -- )
    safe-parse-word  $create-file >r    nvramrc " write" r@ $call-method
  drop  r> close-dev
  ;

then

  ok nvwrite sd:\myfile.fth

then one of these lines to evaluate the Forth code from disk:

  ok including sd:\myfile.fth       \ For standards-aware persons
  ok fload sd:\myfile.fth           \ Another way to say the same thing
  ok fl sd:\myfile.fth              \ For impatient people like me

$create-file will not overwrite an existing file. You can delete it with:

  ok  rm sd:\myfile.fth

Or you could modify nvwrite as follows:

  : nvwrite  \ filename  ( -- )
    safe-parse-word  2dup ?delete-file  if
      $create-file >r    nvramrc " write" r@ $call-method drop  r> close-dev
    then
  ;

Here is a definition that will read a file into nvramrc so you can edit it

  : nvread  \ filename  ( -- )
    reading
    load-base   dup h# 10000  ifd @ fgets   ( adr len )
    to nvramrc
    ifd @ fclose
  ;

The primitive editing routine that nvedit uses is "edit-file ( adr len maxlen -- newlen )" . If you want to do your own buffer management, you could use that to build a custom set of editing words.