Notice that the Environment here is for C/C++, Assembly, Bare metal, not for MaixPy.
English | 简体中文
This tutorial is designed to help you build a bare metal debugging and development environment for Sipeed Maix Bit (Kendryte 210). The tutorial will guide you step by step without basic knowledge of embedded system and try to reduce uncontrollable bugs.
Please strictly follow every step of the tutorial since every step of the tutorial has a quite reasonable reason to avoid some crazy mistakes.
Please ensure that you have basic knowledge of electronic circuit, Linux (operating system), GCC & GDB (C/C++) before starting the tutorial.
-
Sipeed Maix Bit (NOT include display and camera)
This board is designed for AI+IOT and has 16MiB flash on board. The 400MHz dual core chip Kendryte 210 on the board is 64-bit RISC-V Architecture.
Its typical development scenario is the computer vision of IOT by using MaixPy (Maybe you can do more fun things on it.) However, we mainly use it for bare metal development here.
Advantage: Relatively reasonable price: $12.9 & Relatively complete documentation: K210, Maix Bit & Relatively complete support & Relatively good cost–performance ratio (even can run Linux or overclock) -
Sipeed-USB-JTAG-TTL-RISC-V-Debugger (include DuPont Cable)
This Debugger use FT2232C from FTDI Chip as its USB UART/FIFO IC.
J-Link is about $400, J-Link EDU is about $60. Sipeed RV Debugger is only $7.6.
Also, it can work with PlatformIO and K210.
The pin layout of debugger:
The pin layout of Maix Bit:
Connection table:
Debugger | Maix Bit |
---|---|
GND | GND |
RXD |
TX |
TXD |
RX |
5V | 5V |
3V3 | 3V3 |
TDI | TDI |
RST | RST |
TMS | TMS |
TDO | TDO |
TCK | TCK |
Notice that Debugger's
RX
pin should be connected to Board'sTXD
pin, and Debugger'sTX
pin should be connected to Board'sRXD
pin. This is important forUART for Serial Communication
.
Host: Windows 10 Build 19042.685
Virtual Machine: VMware Workstation 16 Player (VirtualBox has some tricky things on USB)
System image: ubuntu-20.04.1-desktop-amd64.iso (Use desktop version to use multiple terminals and VS Code easily)
We did not choose WSL2 here because of WSL #2195. WSL2 is using Hyper-V, but Hyper-V does not support USB pass-through.
Alternative Solutions:
1. OpenOCD on Windows, ToolChain on WSL2
2. Use usbip-win, OpenOCD use IP access USB device
3. Similar to 2, usbipd-win has provided an "official" workaround, see Connecting USB devices to WSL
Just do yourself a favor, use VM :)
Recommend Step for creating a working directory (optional):
mkdir k210 && cd k210
- Download Kendryte ToolChain Release v8.2.0
tar -xvzf kendryte-toolchain-ubuntu-amd64-8.2.0-20190213.tar.gz
cd kendryte-toolchain-ubuntu-amd64-8.2.0-20190213/kendryte-toolchain
sudo cp -a ./. /opt/riscv-toolchain
, the ToolChain is copied to/opt/riscv-toolchain
, notice that the folder name isriscv-toolchain
instead ofkendryte-toolchain
!export k210toolchain=/opt/riscv-toolchain/bin
,export PATH="$k210toolchain:$PATH"
, add ToolChain to path.
Now, ToolChain Installation has finished.
About ToolChain: https://metalcode.eu/2019-11-16-gnu-toolchain.html
- Download Kendryte SDK Release v0.5.6
tar -xvzf kendryte-standalone-sdk-0.5.6.tar.gz
cd kendryte-standalone-sdk-0.5.6
mkdir build && cd build
cmake .. -DPROJ=<ProjectName> -DTOOLCHAIN=/opt/riscv-toolchain/bin && make
Notice that<ProjectName>
needed to be replaced by real Project Name (hello_world
).
Now, SDK Installation has finished, andhello_world
should be compiled successfully inbuild
.
If
riscv64-unknown-elf-gcc: error trying to exec 'cc1': execvp: No such file or directory
occurs, recheck ToolChain Installation steps to make sure (1) you have/opt/riscv-toolchain
& (2) you have added ToolChain location to$PATH
.
Notice that Maix Bit uses CH552 chip to implement USB-Serial without JTAG. (K210 supports JTAG, but the CH552 on Maix Bit has no JTAG function) (https://wiki.sipeed.com/soft/maixpy/en/get_started/install_driver/bit.html)
CH552 emulates FT2232 chip, which is the same as the debugger chip (FT2232C) and causing conflict if they are used at the same time.
ONLY connect the debugger to your VM to avoid conflict!
- Download Kendryte OpenOCD Relaese v0.2.3
tar -xvzf kendryte-openocd-0.2.3-ubuntu64.tar.gz
cd kendryte-openocd-0.2.3-ubuntu64/kendryte-openocd
cd bin
./openocd -f ../tcl/kendryte.cfg
If
./openocd: error while loading shared libraries: libusb-0.1.so.4: cannot open shared object file: No such file or directory
occurs, runsudo apt-get install libusb-0.1
;
If./openocd: error while loading shared libraries: libftdi.so.1: cannot open shared object file: No such file or directory
occurs, runsudo apt-get install libftdi-dev
;
If./openocd: error while loading shared libraries: libhidapi-hidraw.so.0: cannot open shared object file: No such file or directory
, runsudo apt-get install libhidapi-hidraw0
.
See https://github.com/ntfreak/openocd/blob/0dd3b7fa6c7930446967772832a351e90c426d69/README#L221
-
Then, you should see
_ __ _ _ | |/ /___ _ __ __| |_ __ _ _| |_ ___ | ' // _ \ '_ \ / _` | '__| | | | __/ _ \ | . \ __/ | | | (_| | | | |_| | || __/ |_|\_\___|_| |_|\__,_|_| \__, |\__\___| |___/ Kendryte Open On-Chip Debugger For RISC-V v0.2.3 (2019-02-21) Licensed under GNU GPL v2 adapter speed: 3000 kHz Error: No J-Link device found.
If you are not using J-Link Debugger, you will see the error. It is okay, we just check the correctness of OpenOCD installation here. You can
Ctrl+C
to exit. -
By https://steward-fu.github.io/website/mcu/k210/openocd.htm & https://metalcode.eu/2019-11-19-k210-debugging.html & https://mensi.ch/blog/articles/using-the-sipeed-jtag-debugger-with-a-blue-pill,
first,
cd ../tcl
- create file
ft2232c.cfg
interface ftdi ftdi_vid_pid 0x0403 0x6010 # [3:0] = [TMS 1, TDO 0, TDI 1, TCK 1] # [7:4] = GPOPL0-3 # [11:8] = GPOPH0-3 # 0xfff8 = 1111 1111 1111 1000 # 0xfffb = 1111 1111 1111 1011 ftdi_layout_init 0xfff8 0xfffb ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100 ftdi_layout_signal nSRST -data 0x0200 -oe 0x0200
- create file
k210.cfg
# debug adapter source [find ft2232c.cfg] transport select jtag adapter_khz 10000 # server port gdb_port 3333 telnet_port 4444 # add cpu target set _CHIPNAME riscv jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x04e4796b set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME riscv -chain-position $_TARGETNAME # command init halt
- create file
-
cd ../bin
Again, confirm you are inkendryte-openocd/bin
.
Just run./openocd -f ../tcl/k210.cfg
. (Debug-d
)
IfError: libusb_open() failed with LIBUSB_ERROR_ACCESS Error: libusb_open() failed with LIBUSB_ERROR_ACCESS Error: no device found Error: unable to open ftdi device with vid 0403, pid 6010, description '*', serial '*' at bus location '*'
occurs, run
sudo ./openocd -f ../tcl/k210.cfg
.Now, OpenOCD will connect successfully and shows something like:
_ __ _ _ | |/ /___ _ __ __| |_ __ _ _| |_ ___ | ' // _ \ '_ \ / _` | '__| | | | __/ _ \ | . \ __/ | | | (_| | | | |_| | || __/ |_|\_\___|_| |_|\__,_|_| \__, |\__\___| |___/ Kendryte Open On-Chip Debugger For RISC-V v0.2.3 (2019-02-21) Licensed under GNU GPL v2 adapter speed: 10000 kHz Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi_tdo_sample_edge falling" Info : clock speed 10000 kHz Info : JTAG tap: riscv.cpu tap/device found: 0x04e4796b (mfg: 0x4b5 (<unknown>), part: 0x4e47, ver: 0x0) Core [0] halted at 0x8000b434 due to debug interrupt Info : Examined RISCV core; found 2 harts Info : Listening on port 3333 for gdb connections Core [1] halted at 0x8000bf8e due to debug interrupt Core [0] halted at 0x8000b434 due to debug interrupt Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections
be sure there is
Core [0]
andCore [1]
. Also, notice that we will useport 3333
in GDB for debugging later.
Start a new terminal here and keep the old OpenOCD terminal!
-
cd kendryte-toolchain/bin
-
./riscv64-unknown-elf-gdb ../../kendryte-standalone-sdk-0.5.6/build/hello_world
-
In (gdb):
set print pretty on
(optional)target remote localhost:3333
monitor reset halt
load
Debug:tb (tbreak) main
c (continue)
Debug:s (step)
(step into)n (next)
(step over)
(If
hello_world
is debugging, the program will be stuck inscanf()
and will not print anything byprintf()
. To solve this issue, we need to useUART for Serial Communication
) -
Any time,
Ctrl+C
will stop current debugging. Then,q (quit)
in (gdb) can quit gdb.
About OpenOCD and GDB debug:
https://stackoverflow.com/questions/38033130/how-to-use-the-gdb-gnu-debugger-and-openocd-for-microcontroller-debugging-fr
Start a new terminal here and keep OpenOCD terminal and GDB terminal alive!
Arguments are from k210 UART Doc p118:
Arguments for UART:
Baud Rate(Bps): 115200 (9600 no working!)
Parity: None
Data bits: 8
Stop bit: 1
If you are in Linux, you do NOT need a driver. If you are in Windows, download
CDM21228_Setup.zip
for Win10, downloadFTDI_Win7.zip
for Win7 from https://dl.sipeed.com/MAIX/tools/ftdi_vcp_driver.
If you are following OpenOCD Debug
and only connecting debugger to your VM, just go to Step 1.
If you are using Maix Bit's ft2232c chip for USB-UART (on your host):
Notice that Maix BiT's CH552T chip only use ONE serial interface of K210 to implement USB-Serial.
Thus, two serial interfaces will be shown in device management, but only one can be used for UART so you need to try both! (https://wiki.sipeed.com/soft/maixpy/en/get_started/upgrade_maixpy_firmware.html)
sudo apt-get install minicom
ls /dev/ttyUSB* -la
remember the device name: (for example)ttyUSB1
When the debugger is just connected to VM, there may be two ttyUSBs (like
ttyUSB0
andttyUSB1
). If OpenOCD is running, there should be only one ttyUSB available.sudo minicom -s -con
(Colorful screen-con
)- select
Serial port setup
- press
A
, change device to the device in 1. , for example,/dev/ttyUSB1
pressF
, set toNo
(Important!)
pressEnter
- select
Modem and dialing
press the corresponding keys and set 9 stringsInit string, Reset string, Dialing prefix #1, Dialing suffix #1, Dialing prefix #2, Dialing suffix #2, Dialing prefix #3, Dialing suffix #3, Hang-up string
to nothing.
pressEnter
- select
Screen and keyboard
pressB
, set toDEL
pressR
, set toYes
pressEnter
- select
Save setup as dfl
(Save the current setup as default) - select
Exit from Minicom
sudo minicom
Now, you should seePortWelcome to minicom 2.7.1 OPTIONS: I18n Compiled on Dec 23 2019, 02:06:26. Port /dev/ttyUSB1, 08:31:02
/dev/ttyUSB1
is connected.
Notice that pressCtrl+A
first, thenZ
for help orany key
for other function, not press them simultaneously.- If you are debugging
hello_world
in gdb with OpenOCD, and type6
in minicom.
Then, you should seeNow, UART should work well.Welcome to minicom 2.7.1 OPTIONS: I18n Compiled on Dec 23 2019, 02:06:26. Port /dev/ttyUSB1, 03:12:01 Press CTRL-A Z for help on special keys Core 0 Hello world Core 1 Hello world 6 Data is 6
MaixPy bin should be burned to Maix Bit by default. If Maix Bit's UART is connected correctly, press the RESET
button on Maix Bit, and you should see something like
About Minicom setup:
https://maixpy.sipeed.com/en/get_started/serial_tools.html?h=115200
https://wiki.emacinc.com/wiki/Getting_Started_With_Minicom
This tutorial is written when I only have the experience of using development board but have no knowledge of embedded development. In fact, it is mainly for building an on-chip verification environment for my compiler project about RISC-V assembly.
Now (2020.12), there are not many resources of RISC-V development board, which means we need some exploration during development, especially for non-MaixPy development environment of Maix Bit. I hope this tutorial can help more people enjoy the fun of RISC-V bare metal development :)
@steward-fu (Steward Fu):
https://steward-fu.github.io/website/mcu/k210/openocd.htm
@metalcode-eu (Metalcode):
https://metalcode.eu/2019-11-19-k210-debugging.html
@mensi (Manuel Stocker):
https://mensi.ch/blog/articles/using-the-sipeed-jtag-debugger-with-a-blue-pill
Copyright (C) 2020-2021 Qingpeng Li
This work is licensed under a Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) License.