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! 🎉