Programming the BL602 EVB using OpenOCD, GDB and Rust
27 Dec 2020 · 5 min

I recently got the BL602 EVB from Sipeed. This boards contains the BL602 from Bouffalo Lab, a system on a chip (SoC) with WiFi and Bluetooth, built around a 32-bit RISC-V core. Sipeed is working on adding Rust support for the BL602 EVB (yes please, more Rust! 🦀) and they were searching for folks to try it out. I thought this might be a cool opportunity to learn more about RISC-V, do some embedded stuff and get more experience with embedded Rust! (Let's hope I haven't taken on too many new challenges at once... 🤞🏻).

As a first step, I tried to program the example program blinky from sipeed/bl602-rust-guide. Since I had to jump through some hurdles, I decided to document my steps here.

These steps are all for macOS since I only use macOS at the moment, but hopefully they are also useful for other OS's.

I have since discovered that probe-rs has beta support for RISC-V, so I'll try that out next!

Setup

As mentioned before, I got the BL602 EVB from Sipeed. This board contains a FT2232H for programming and debugging the BL602. The FT2232H has a micro-USB port, so all I need to get started is a micro-USB cable.

I assume you have Rust installed, if not find instructions to install Rust here.

I'm starting out with the code provided by Sipeed, specifically I cloned the following repositories (all next to each other, in the same directory):

Or from the command line:

git clone https://github.com/sipeed/bl602-pac.git
git clone https://github.com/sipeed/bl602-hal.git
git clone https://github.com/sipeed/bl602-rust-guide.git

Install the tools

You'll need some tools to interact with the BL602 and its RISC-V core. I already had a version of OpenOCD and GDB installed from programming ARM-based microcontrollers, but these didn't support the RISC-V architecture (yet?).

OpenOCD

You'll need a version of OpenOCD that can communicate with RISC-V. To check whether your version of OpenOCD supports RISC-V as target, you can use the target types command:

openocd -c 'target tpyes'

This will print a list of supported targets. Unfortunately, the version shipped by Homebrew does not support RISC-V. You'll get the following error when connecting:

embedded:startup.tcl:21: Error: Unknown target type riscv, try one of arm7tdmi, arm9tdmi, ...

Instead I built riscv/riscv-openocd from source using the following commands:

# clone github.com/riscv/riscv-openocd
git clone https://github.com/riscv/riscv-openocd.git
cd riscv-openocd

# you'll need these tools (if you don't have them installed yet)
brew install autoconf automake libtool

# build and install riscv-openocd

./bootstrap

# -D_FTDI_DISABLED_DEPRECATED: avoid deprecations warnings that will
#                              otherwise fail the build
# --program-prefix: install the program as 'riscv-opencd' instead of
#                   overwriting 'openocd'
# all other options are copied from the openocd Homebrew formula:
# https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/open-ocd.rb
CFLAGS=-D_FTDI_DISABLE_DEPRECATED ./configure --disable-dependency-tracking --enable-buspirate --enable-stlink --enable-dummy --enable-jtag_vpi --enable-remote-bitbang --program-prefix=riscv-

make install

This will install a new program riscv-openocd in /usr/local/bin/.

If you run target types again, it should list riscv as option:

riscv-openocd -c 'target types'

The output on my machine:

Open On-Chip Debugger 0.10.0+dev-01409-gb8620764c (2020-12-26-18:39)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
arm7tdmi arm9tdmi arm920t arm720t arm966e arm946e arm926ejs fa526
feroceon dragonite xscale cortex_m cortex_a cortex_r4 arm11 ls1_sap
mips_m4k avr dsp563xx dsp5680xx testee avr32_ap7k hla_target nds32_v2
nds32_v3 nds32_v3m or1k quark_x10xx quark_d20xx stm8 riscv mem_ap
esirisc arcv2 aarch64 mips_mips64

To uninstall later, run make uninstall.

GDB

GDB is supposed to be multi-target, but when I run the GDB installed by Homebrew I get:

Reading symbols from target/riscv32imac-unknown-none-elf/debug/examples/bl602-gpio-blinky...
I'm sorry, Dave, I can't do that.  Symbol format `elf32-littleriscv' unknown.

Instead, had to install a custom GDB from riscv/riscv-gnu-toolchain using riscv/homebrew-riscv:

brew tap riscv/riscv
brew install riscv-gnu-toolchain

This will install riscv64-unknown-elf-gdb and more. Note that the 64-bit version of GDB will also work with 32-bit RISC-V targets.

Rust

Lastly, To build Rust code for the BL602 (and thus RISC-V), you'll need to install the appropriate RISC-V target:

rustup target install riscv32imac-unknown-none-elf

I didn't figure this out myself, I just tried to build the example code and the compilation failed with a helpful error message:

   ...
   Compiling bit_field v0.10.1
error[E0463]: can't find crate for `core`
  |
  = note: the `riscv32imac-unknown-none-elf` target may not be installed

error: aborting due to previous error

For more information about this error, try `rustc --explain E0463`.
error: could not compile `bit_field`

A first RISC-V program

With all this set up, you should be able to run the examples in sipeed/bl602-rust-guide!

In one terminal start OpenOCD:

riscv-openocd

This will log some information while connecting to the BL602 and should eventually print:

...
Info : Listening on port 3333 for gdb connections
...

Then, from another terminal run the example:

cargo run --example bl602-gpio-blinky

Once the program is compiled and the BL602 has been programmed, it will start a debugging session using GDB and immediately halt the processor. To execute the program, type c or continue.

The LED on the board should now blink! Hooray! 🎉


blog · about · home