Rust on the Sipeed Longan Nano, an inexpensive RISC-V dev board
The Sipeed Longan Nano is a $5 development board based on a new RISC-V processor from Gigadevices. The processor and the dev board are properly documented in English. If you are a RISC-V enthusiast, I believe this is the best option you have at the moment for learning and experimentation.
I was able to run Rust code on this board by making small changes to the riscv/rust PicoSoc example. All the experiments described here were done on a Linux system.
Note: After writing this post, I saw that we already have crates for interfacing with the gd32v processor. That’s real quick, considering the fact that these procesors were released only in August 2019! It is always best to use crates like these when building your projects.
Install the Rust RISC-V target
Getting the RISC-V target for Rust (stable and nightly) is just a matter of running:
rustup target add riscv32imac-unknown-none-elf rustup default nightly rustup target add riscv32imac-unknown-none-elf
Here is the output of running rustc –version on my system:
rustc 1.40.0-nightly (787005079 2019-10-04)
We will use Rust nightly to compile our code.
Install some tools provided by Sipeed
Install the RISC-V GNU toolchain. We will be using just the riscv-nuclei-elf-objcopy tool from this collection.
We need a version of dfu-util provided by Sipeed. For some reason, dfu-util installed using apt or dfu-util compiled from source did not work for me.
Running the example code
Here is the git repo.
Build it with cargo build.
Convert the resulting ELF file into a raw binary which can be written to the flash memory of the microcontroller:
riscv-nuclei-elf-objcopy -O binary target/riscv32imac-unknown-none-elf/debug/rust-sipeed-longan-nano rust-sipeed-longan-nano.bin
The Longan Nano has two buttons: reset and boot. Keep the boot button pressed and then press and release the reset button. This will put the board in USB dfu bootloader mode. You can now use dfu-util to transfer the binary to the flash memory of the microcontroller:
sudo dfu-util -a 0 -s 0x08000000:leave -D rust-sipeed-longan-nano.bin
If dfu-util returns an error, try the key press/release sequence again and it will work!
You should be able to see the Green LED blinking!
About the code
The board has an RGB LED connected to port pins PC13, PA1, and PA2. The code enables only PA1 (Green LED). The GD32V processor seems to have a simple peripheral programming model - just enable the clock associated with the GPIO port (port A) and configure the required pin as a push-pull output and you are ready to go!
The code makes direct use of raw pointers/unsafe to poke the I/O ports. A better way to do it when you are writing production code is to use the higher level abstractions provided by crates like gd32vf103-pac and gd32vf103-hal.
Our code needs to do a few critical operations (like setting up the stack) before it hits the main function. I have borrowed these from the picosoc example, with a few minor changes. This is unlikely to be completely correct (in the context of the GD32V processor).
Show me the output!
Ok! Here is a slightly modified version of the code cycling through the 3 LED’s: