Quantcast
Channel: OpenEnergyMonitor aggregator
Viewing all articles
Browse latest Browse all 328

JeeLabs: Starting Forth on an STM32F1

$
0
0

Here is what we’re after, as Forth Development Environment (would that be an“FDE”?):

There are a number of steps needed to use Mecrisp-Stellaris Forth in your own projects (for these articles, we’ll be focusing on theSTM32F103µC series with 64..512 KB flash memory):

  1. getting the Mecrisp core “flashed” onto the microcontroller
  2. setting up a convenient connection between your laptop and the µC board
  3. streamlining the iterative coding cycle as much as possible

Note that this is in some way quite similar to hooking up an Arduino or JeeNode, and developing software for it through the Arduino IDE. But there also some substantial differences:

  • pick your own editor, “whatever works for you” is by far the best choice
  • no compilers, no debuggers, no toolchain - just a simple way to talk to the µC
  • no binary code, no runtime libraries, just you, your code, and your terminal

The Arduino approach puts all complexity in the “host” laptop setup. The Mecrisp approach builds words in the µC, on the fly, when they’re typed in (or uploaded, i.e. “simulated typing”).

Installing Mecrisp

Step 1) is not Mecrisp-specific. It’s the same stumbing block with everyµC setup which needs specific firmware. You need to download the latest Mecrisp-Stellaris release from SourceForge, and “get it onto that darn chip… somehow” !

Here are some ways to do this, depending on what interface tools you have and your O/S:

The firmware in the Mecrisp distribution is available in two versions, a“.bin” and a “.hex” file:

stm32f103/mecrisp-stellaris-stm32f103.bin
stm32f103/mecrisp-stellaris-stm32f103.hex

It depends on the upload mechanism as to which one you need. With a Black Magic Probe (BMP) and arm-none-eabi-gdb, for example, the following commands should do the trick:

% arm-none-eabi-gdb
[...]
(gdb) tar ext /dev/cu.usbmodemD5D1AAB1    (adjust as needed, of course)
(gdb) mon swdp
(gdb) at 1
(gdb) mon erase                                (essential for Mecrisp!)
(gdb) load mecrisp-stellaris-stm32f103.hex
(gdb) q

Then, again if you are using a BMP and running on Mac OSX or Linux:

% screen /dev/cu.usbmodemD5D1AAB3 115200
Mecrisp-Stellaris 2.2.1a for STM32F103 by Matthias Koch
  ok.
(quit with "ctrl-a ctrl-\" or "ctrl-a \" - depending on your setup)

The serial connection must be set up as 115200 Baud for Mecrisp - 8 bits, no parity, 1 stop bit.

If you’re using an ST-Link to upload the firmware, these two commands will do the trick:

st-flash erase                                # essential for Mecrisp!
st-flash write mecrisp-stellaris-stm32f103.bin 0x08000000

It’s very simple and quick, but only · a f t e r · you’ve got all those Pesky Little Details just right. Getting firmware onto a bare STM32F103 µC can still be a hit-and-miss affair. There are simply too many variables involved to come up with a procedure here which will work for everyone.

The good news is that with a little care, you will not have to repeat this step again. Mecrisp is quite good at keeping itself intact (it refuses to re-flash itself, for example).

Installing PicoCom

One of the things you’ll notice if you try out the above setup with screen, is that it doesn’t quite get the line endings right (which are bare LFs in Mecrisp, not CR+LF). It’s better to install a slightly more elaborate terminal emulator - and PicoCom is in fact a very good option for Mac OSX and Linux, as will become clear below. For Windows, there isTeraTerm.

To install PicoCom on Mac OSX with Homebrew, enter this in a command shell:

brew install picocom

To install PicoCom on Debian/Raspbian/Ubuntu Linux, type:

sudo apt-get install picocom

The benefit of PicoCom is that it allows specifying a program to use for uploads. We don’t want to manually enter text, we also need to send entire source files to Mecrisp Forth over serial. The problem is that a bare Mecrisp installation only supports polled serial I/O without handshake. This can only handle text if it’s not coming in “too fast”. In Mecrisp, each word on a line needs to be looked up and compiled, and it all happens on a line-by-line basis. This means that you have to wait for its“ok.” prompt after each line, before sending more text.

One solution is to send all text · v e r y · s l o w l y · but that’ll make it extremely time-consuming.

Installing msend

A better solution is to send full speed and wait for that final prompt before sending the next line, to avoid input characters getting lost. This little utility has been created to do just that:msend.

If you have Go installed, getting msend (Mac OSX and Linux only, for now) is again a one-liner:

go get github.com/jeelabs/embello/tools/msend

Otherwise, you can get the latest binary release for a few platforms fromGitHub.

With “msend” installed, PicoCom can now be started up as follows:

picocom -b 115200 --imap lfcrlf -s msend /dev/cu.usbmodemD5D1AAB3

Or even as “mcom /dev/cu.usbmodemD5D1AAB3” - if you add an alias to your.bashrc init file:

alias mcom='picocom -b 115200 --imap lfcrlf -s msend'

And now line endings not only work properly, you also get a very effective upload facility. This will be worth its own article, but you can see a transcript of an upload with includes over here.

Sending a file with PicoCom is triggered by typing “ctrl-a ctrl-s”.

To quit PicoCom, type “ctrl-a ctrl-x” - see also the manual page for further details.

Windows

Neither PicoCom nor msend are available for Windows, but there’s another solution:

  • install TeraTerm, which is a terminal emulator for Windows
  • look at this script file for TeraTerm, by Jean Jonethal

This combination should accomplish more or less the same as picocom + msend, i.e. terminal access, throttling text sends, and inserting “include” files.

Optimising workflow

Forth software development is aboutflow and insanely fast turnaround times between coming up with an idea and trying it out. There are no compilers or other tools to slow you down, and as a result you can type and try out an idea the moment it pops into your head. Total interactivity!

At the same time, the last thing we want, is to constantly re-enter code, let alone lose it for good if the µC crashes. The challenge is to find a proper balance between volatile commands (typed in directly at the Mecrisp prompt, on the µC) and re-sending lots of text from a laptop all the time.

Mecrisp has an elegant and simple approach to help with this:

  • when you power it up, Mecrisp remembers only what it had stored in flash memory
  • all new definitions (i.e. “: myword ... ;”) are added and compiled into RAM
  • stack underflows (a common mistake) clear the stack but won’t lose RAM
  • a reset (whether in hardware or using the “reset” word) will lose everything in RAM
  • you can save your next definitions to flash memory by typing“compiletoflash
  • this will continue until you press reset or enter “compiletoram

The thing is that in Mecrisp Forth, a hard crash is no big deal - youshould expect to run into stuck code, awful crashes, weird things happening, non-responsive terminal I/O, etc. There’s a reset button on the µC which will get you back to a working state the (sub-) second you use it.

It could be a typo. There could be a hint in what’s on the screen. But even if not, if you make your coding cycles short and frequent, then chances are that you’ll quickly discover what went wrong.

Otherwise… the interactive Forth prompt is your friend: examine the values of variables, or the settings in hardware registers, and invent whatever words you need to help figure out this issue. Words can be one-liners, written only for use in the next few minutes of your investigation!

The more loosely coupled your words are, i.e. called in sequence, not nested too deeply, the easier it will be to set up the stack and call any one of them, in isolation, from the prompt. If something fails, you can take over and repeat the rest of the words by hand, verifying that the stack is as expected (check out the “.s” word!), and peeking around to see what’s going on.

Looking at the diagram above, you’ll see that there are two kinds ofpermanence in this context: source code in files, and words defined in flash memory. The latter cannot easily be turned back into source, alas. That means they should be either one-offs or created by an earlier upload.

Although the best workflow has yet to be found, some comments on what is likely to work well:

  • new code, especially when it’s about getting the hardware interface right, needs to run on the µC and can be quickly explored ad-hoc - at the Forth prompt, no definitions needed
  • you can read / write to registers with “io@” / “io!” commands in a“peek and poke” style
  • lengthy setup code can be written in your editor, and then uploaded and saved to flash
  • hardware addresses are a lot easier to use as pre-defined Forth words (i.e.“constant”)
  • if you make uploaded code store itself in flash, you won’t have to re-upload it after a reset
  • the “cornerstone” word can partially unwind definitions from flash - great for uploads
  • make sure your terminal window keeps a lot of history - it’s a very effective historical log

Maybe the rlwrap tool can be made to work with PicoCom - for command history and editing.

There is a lot more to say about this. The “msend” utility recognizes lines starting with the word “include” as special requests to fetch a file from the system and send its contents (this can be nested). This allows keeping various word sets in their own files, and then selectively include them in each project. You can add “compiletoflash” to save the more stable words in flash.

For more ideas on how to organise the code, see theREADME in the Embello area on GitHub.

There is no need for large nested source file trees. Forth source code tends to be very compact - a single page of code is usually more than enough to implement a complete well-defined module. One directory with a few dozen files is plenty. Put them under source code control in GitHub or elsewhere, and you’ll have your entire project under control for the long-term. Each project can contain all the files it needs to be re-created (i.e. re-uploaded to a µC running Mecrisp Forth).

Enough for now, this’ll get you started. Now go Forth, and create lots of embedded µC projects!


Viewing all articles
Browse latest Browse all 328

Trending Articles