[Thanks to Phillip Burgess for the above image!]
The STM32 Primer is a very innovative (and low cost) evaluation kit for the STM32F103RB ARM Cortex-M3 based processor from ST.
For a change, instead of a drab rectangular PCB, the Primer comes packaged as a nice little CIRCLE - with a good quality color LCD display and an accelerometer as an input device. The “cursor” on the LCD screen is controlled by tilting the Primer!
The only trouble was, you had to boot into (horror) MS-Windows to write cute little applications for the device.
But that was the past - the great guys who wrote OpenOCD have made sure that you no longer have to suffer this horror - it's now perfectly possible to do all kinds of Primer-based development on a pure Free Software platform!
[Note: we are referring to the first version of the primer device here - the “Primer1”]
Most modern microprocessors/controllers provide JTAG support to facilitate debugging. Trouble is, proprietary JTAG solutions can be very costly; most hobbyists won't be able to afford one. Dominic Rath's OpenOCD project is a wonderful effort to provide a free software solution to the JTAG interfacing problem.
The STM32 primer provides a USB based JTAG interface (called `rlink') - OpenOCD is capable of using the rlink interface to control the STM32F103RB processor.
The current version of OpenOCD (released on Feb 13, 2009) is 0.1.0. You can download it from here.
Compile with rlink support enabled:
./configure --enable-rlink make
The OpenOCD binary will be available in the folder `src'.
Plug a USB cable to the “debug” port on the primer. Here is what you might see if you run `dmesg':
New USB device found, idVendor=138e, idProduct=9000 New USB device strings: Mfr=1, Product=2, SerialNumber=3 Product: Raisonance RLINKUSB Dongle. Manufacturer: RAISONANCE S.A. SerialNumber: dngWNYe00002910
Now run `openocd':
src/openocd -f src/target/interface/rlink.cfg -f src/target/board/stm32f10x_128k_eval.cfg
You should see output which looks like this:
$URL: https://firstname.lastname@example.org/svnroot/repos/openocd/tags/openocd-0.1.0/src/openocd.c $ 500 kHz Info : JTAG tap: stm32.cpu tap/device found: 0x3ba00477 (Manufacturer: 0x23b, Part: 0xba00, Version: 0x3) Info : JTAG Tap/device matched Info : JTAG tap: stm32.bs tap/device found: 0x16410041 (Manufacturer: 0x020, Part: 0x6410, Version: 0x1) Info : JTAG Tap/device matched Warn : no telnet port specified, using default port 4444 Warn : no gdb port specified, using default port 3333 Warn : no tcl port specified, using default port 6666
OpenOCD runs as a server (listening to port 4444 by default); connect to it using `telnet':
$ telnet localhost 4444 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Open On-Chip Debugger >
And run a few commands to test if things are working fine:
> halt target was in unknown state when halt was requested
> flash probe 0 device id = 0x20016410 flash size = 128kbytes flash 'stm32x' found at 0x08000000
OpenOCD reports that the flash memory in the STM32F103 device is organized as a “flash bank” of 1Kb sectors. Let's check whether these “sectors” are erased or not:
> flash erase_check 0
The argument to erase_check is the bank number.
Let's erase sector 0 and write some data to it:
> flash erase_sector 0 0 0 > flash write_bank 0 /absolute/path/to/file.bin 0
The first argument to erase_sector is the bank number; the second and third parameters are the first and last sectors to erase.
The first argument to write_bank is the bank number and the third argument is the offset at which data is to be written. Note that OpenOCD expects a file containing pure binary data (and not something like a .hex file).
If the flash memory is “locked”, we will have to unlock it before erasing:
> stm32x_unlock 0
The parameter 0 is the number of the flash bank to be unlocked.
Here is how to read a word from memory (0x40021014 is address of the AHBENR register whose reset value is 0x14)
OpenOCD will accept connections from gdb (which can even be running on a different machine on the network). The default port on which OpenOCD listens for gdb connection is 3333. When we issue a gdb command to say display the contents of a CPU register, gdb will relay this command to OpenOCD which will perform the required actions and convey the result back to gdb.
There is some problem with the version of gdb distributed by CodeSourcery as part of cs2008q3-66. Gdb which comes with cs2007q3-53 works fine.
If OpenOCD and gdb are both running on the same machine, the following command (issued at the gdb prompt) connects gdb with OpenOCD:
(gdb) target remote :3333