軟體主要是用於編譯的 RISC-V GCC , 和用於燒錄的 OpenOCD.
前往 https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases 下載
前往 http://mounriver.com/download 下載 MRS_Toolchain_Linux_x64, 當前是 MRS_Toolchain_Linux_x64_V1.50.tar.xz, RISC-V GCC 版本為 8.2.0.
解壓工具鏈壓縮包, 目錄結構為
── beforeinstall
│ ├── 50-wch.rules
│ ├── 60-openocd.rules
│ ├── libhidapi-hidraw.so -> libhidapi-hidraw.so.0.0.0
│ ├── libhidapi-hidraw.so.0 -> libhidapi-hidraw.so.0.0.0
│ ├── libhidapi-hidraw.so.0.0.0
│ ├── libhidapi-libusb.so -> libhidapi-libusb.so.0.0.0
│ ├── libhidapi-libusb.so.0 -> libhidapi-libusb.so.0.0.0
│ ├── libhidapi-libusb.so.0.0.0
│ ├── libjaylink.so -> libjaylink.so.0.1.0
│ ├── libjaylink.so.0 -> libjaylink.so.0.1.0
│ ├── libjaylink.so.0.1.0
│ ├── libmcuupdate.so
│ ├── libncurses.so.5 -> libncurses.so.5.9
│ ├── libncurses.so.5.9
│ ├── libtinfo.so.5 -> libtinfo.so.5.9
│ ├── libtinfo.so.5.9
│ ├── libusb-1.0.so -> libusb-1.0.so.0.3.0
│ ├── libusb-1.0.so.0 -> libusb-1.0.so.0.3.0
│ ├── libusb-1.0.so.0.3.0
│ └── start.sh
├── OpenOCD
│ ├── bin
│ │ ├── openocd
│ │ ├── wch-arm.cfg
│ │ └── wch-riscv.cfg
│ ├── README.md
│ └── share
├── README
└── RISC-V Embedded GCC
├── bin
├── distro-info
├── include
│ └── gdb
│ └── jit-reader.h
├── lib
│ ├── bfd-plugins
│ └── gcc
├── lib64
│ ├── libcc1.so -> libcc1.so.0.0.0
│ ├── libcc1.so.0 -> libcc1.so.0.0.0
│ ├── libcc1.so.0.0.0
│ ├── libgcc_s.so.1
│ ├── libstdc++.so.6 -> libstdc++.so.6.0.24
│ └── libstdc++.so.6.0.24
├── libexec
│ └── gcc
├── README.md
├── riscv-none-embed
└── share
其中
這部分比較簡單, 在 /opt 目錄下建一個 gcc-riscv 目錄, 將工具解壓後複製過去, 用公版或WCH工具鏈中帶的版本都行. 設定好相應的許可權, 路徑在後面設定 Makefile 的時候需要使用, 用 --version
驗證一下是否正常
/opt/gcc-riscv$ /opt/gcc-riscv/riscv-none-embed-gcc-10.2.0-1.2/bin/riscv-none-embed-gcc --version
riscv-none-embed-gcc (xPack GNU RISC-V Embedded GCC x86_64) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
也是解壓後複製到 /opt 目錄下, 驗證一下
/opt/gcc-riscv$ /opt/openocd/wch-openocd/bin/openocd --version
Open On-Chip Debugger 0.11.0+dev-02215-gcc0ecfb6d-dirty (2022-06-23-10:21)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
在openocd可以正常燒錄前, 需要進行一些環境設定, 參考 WCH 工具包下的 beforeinstall 目錄
因為環境中還安裝了其他的工具, 為避免衝突, 對 start.sh 中的步驟手工安裝. 在 /usr/lib 下建立一個單獨的目錄, 用於放置這些動態連結庫檔案
cd /usr/lib
sudo mkdir wch-moun-river
sudo cp ./beforeinstall/lib* wch-moun-river/
為這個新的連結庫檔案目錄增加ldconfig設定, 在 /etc/ld.so.conf.d/ 下建立檔案 wch-moun-river.conf , 內容如下
more /etc/ld.so.conf.d/wch-moun-river.conf
# lib for wch moun river studio
/usr/lib/wch-moun-river
然後更新生效
sudo ldconfig
如果出現這樣的提示, 說明環境中存在多個同樣名稱的動態連結庫, 如果不想看到這些警告可以將這些檔案刪除, 也可以忽略
/sbin/ldconfig.real: /usr/lib/wch-moun-river/libtinfo.so.5 is not a symbolic link
先檢查一下 /etc/udev/ 下是否已經存在相關的設定, 如果有, 需要和這兩個規則整合一下, 如果沒有, 直接複製然後更新就可以了
sudo cp ./50-wch.rules /etc/udev/rules.d
sudo cp ./60-openocd.rules /etc/udev/rules.d
# Reload rules
sudo udevadm control --reload-rules
將 WCH-Link 和開發板連線到電腦, 此時dmesg應該能正常檢測到 WCH-Link 裝置, 檢查一下 WCH-Link 是否執行在 WCH-Link 模式, 如果執行在 DAP-Link模式下, 需要切換一下.
[ 2449.285125] usb 2-3: USB disconnect, device number 2
[ 2452.341042] usb 2-3: new full-speed USB device number 5 using xhci_hcd
[ 2452.494530] usb 2-3: New USB device found, idVendor=1a86, idProduct=8010, bcdDevice= 2.05
[ 2452.494543] usb 2-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 2452.494549] usb 2-3: Product: WCH-Link
[ 2452.494554] usb 2-3: Manufacturer: wch.cn
[ 2452.494558] usb 2-3: SerialNumber: 0001A0000000
[ 2452.498525] cdc_acm 2-3:1.1: ttyACM0: USB ACM device
到工具鏈解壓目錄下, 用 OpenOCD 檢查是否能正常連線
./openocd -f wch-riscv.cfg -c init -c halt
# 如果有以下的顯示說明設定正確
Open On-Chip Debugger 0.11.0+dev-02215-gcc0ecfb6d-dirty (2022-06-23-10:21)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
Ready for Remote Connections
Info : WCH-Link-CH549 mod:RV version 2.5
Info : wlink_init ok
Info : This adapter doesn't support configurable speed
Info : JTAG tap: riscv.cpu tap/device found: 0x00000001 (mfg: 0x000 (<invalid>), part: 0x0000, ver: 0x0)
Warn : Bypassing JTAG setup events due to errors
Info : [riscv.cpu.0] datacount=2 progbufsize=8
Info : Examined RISC-V core; found 1 harts
Info : hart 0: XLEN=32, misa=0x0
[riscv.cpu.0] Target successfully examined.
Info : starting gdb server for riscv.cpu.0 on 3333
Info : Listening on port 3333 for gdb connections
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
如果顯示下面的錯誤, 說明動態連結庫設定有誤
./openocd: symbol lookup error: ./openocd: undefined symbol: jaylink_device_get_usb_bus_ports
如果顯示下面的錯誤, 說明使用的不是 wch 提供的客製化 openocd
wch-riscv.cfg:2: Error: invalid command name "adapter"
in procedure 'script'
at file "embedded:startup.tcl", line 60
at file "wch-riscv.cfg", line 2
從 GitHub 匯出專案到本地
git clone https://github.com/IOsetting/ch32v103-template.git
開啟 Makefile 將工具路徑設定為自己的路徑
TOOL_CHAIN_PATH ?= /opt/gcc-riscv/riscv-none-embed-gcc-10.2.0-1.2/bin
OPENOCD_PATH ?= /opt/openocd/wch-openocd/bin
專案名稱可以修改
PROJECT_NAME = test001
# 清理
make clean
# 編譯
make
make flash
編譯命令的基本格式如下
riscv-none-embed-gcc
-march=rv32imac
-mabi=ilp32
-msmall-data-limit=8
-mno-save-restore
-Os
-fmessage-length=0
-fsigned-char
-ffunction-sections
-fdata-sections
-Wunused
-Wuninitialized
-g
-I"/home/milton/WorkRiscV/ch32v_ws001/ch32v103_test001/Debug"
-I"/home/milton/WorkRiscV/ch32v_ws001/ch32v103_test001/Core"
-I"/home/milton/WorkRiscV/ch32v_ws001/ch32v103_test001/User"
-I"/home/milton/WorkRiscV/ch32v_ws001/ch32v103_test001/Peripheral/inc"
-std=gnu99
-MMD
-MP
-MF"Peripheral/src/ch32v10x_crc.d"
-MT"Peripheral/src/ch32v10x_crc.o"
-c
-o "Peripheral/src/ch32v10x_crc.o"
"../Peripheral/src/ch32v10x_crc.c"
各引數的說明, 引自 RISC-V-Options, GCC C Dialect Options GCC Preprocessor Options
Generate code for given RISC-V ISA (e.g. ‘rv64im’). ISA strings must be lower-case. Examples include ‘rv64i’, ‘rv32g’, ‘rv32e’, and ‘rv32imaf’.
When -march= is not specified, use the setting from -mcpu.
If both -march and -mcpu= are not specified, the default for this argument is system dependent, users who want a specific architecture extensions should specify one explicitly.
Specify integer and floating-point calling convention. ABI-string contains two parts: the size of integer types and the registers used for floating-point types. For example ‘-march=rv64ifd -mabi=lp64d’ means that ‘long’ and pointers are 64-bit (implicitly defining ‘int’ to be 32-bit), and that floating-point values up to 64 bits wide are passed in F registers. Contrast this with ‘-march=rv64ifd -mabi=lp64f’, which still allows the compiler to generate code that uses the F and D extensions but only allows floating-point values up to 32 bits long to be passed in registers; or ‘-march=rv64ifd -mabi=lp64’, in which no floating-point arguments will be passed in registers.
The default for this argument is system dependent, users who want a specific calling convention should specify one explicitly. The valid calling conventions are: ‘ilp32’, ‘ilp32f’, ‘ilp32d’, ‘lp64’, ‘lp64f’, and ‘lp64d’. Some calling conventions are impossible to implement on some ISAs: for example, ‘-march=rv32if -mabi=ilp32d’ is invalid because the ABI requires 64-bit values be passed in F registers, but F registers are only 32 bits wide. There is also the ‘ilp32e’ ABI that can only be used with the ‘rv32e’ architecture. This ABI is not well specified at present, and is subject to change.
Put global and static data smaller than n bytes into a special section (on some targets).
Do or don’t use smaller but slower prologue and epilogue code that uses library function calls. The default is to use fast inline prologues and epilogues.
Optimize for size. -Os enables all -O2 optimizations except those that often increase code size:
-falign-functions -falign-jumps
-falign-labels -falign-loops
-fprefetch-loop-arrays -freorder-blocks-algorithm=stc
Try to format error messages so that they fit on lines of about n characters. If n is zero, then no line-wrapping is done; each error message appears on a single line. This is the default for all front ends.
Note - this option also affects the display of the ‘#error’ and ‘#warning’ pre-processor directives, and the ‘deprecated’ function/type/variable attribute. It does not however affect the ‘pragma GCC warning’ and ‘pragma GCC error’ pragmas.
Let the type char be signed, like signed char.
Note that this is equivalent to -fno-unsigned-char, which is the negative form of -funsigned-char. Likewise, the option -fno-signed-char is equivalent to -funsigned-char.
Place each function or data item into its own section in the output file if the target supports arbitrary sections. The name of the function or the name of the data item determines the section’s name in the output file.
Use these options on systems where the linker can perform optimizations to improve locality of reference in the instruction space. Most systems using the ELF object format have linkers with such optimizations. On AIX, the linker rearranges sections (CSECTs) based on the call graph. The performance impact varies.
Together with a linker garbage collection (linker --gc-sections option) these options may lead to smaller statically-linked executables (after stripping).
Warns, all the -Wunused options combined.
Warn if an object with automatic or allocated storage duration is used without having been initialized. In C++, also warn if a non-static reference or non-static const member appears in a class without constructors.
generates debug information to be used by GDB debugger.
-MD is equivalent to -M -MF file, except that -E is not implied. The driver determines file based on whether an -o option is given. If it is, the driver uses its argument but with a suffix of .d, otherwise it takes the name of the input file, removes any directory components and suffix, and applies a .d suffix.
Like -MD except mention only user header files, not system header files.
This option instructs CPP to add a phony target for each dependency other than the main file, causing each to depend on nothing. These dummy rules work around errors make gives if you remove header files without updating the Makefile to match.
This is typical output:
test.o: test.c test.h
test.h:
When used with -M or -MM, specifies a file to write the dependencies to. If no -MF switch is given the preprocessor sends the rules to the same place it would send preprocessed output.
When used with the driver options -MD or -MMD, -MF overrides the default dependency output file.
If file is -, then the dependencies are written to stdout.
Change the target of the rule emitted by dependency generation. By default CPP takes the name of the main input file, deletes any directory components and any file suffix such as ‘.c’, and appends the platform’s usual object suffix. The result is the target.
An -MT option sets the target to be exactly the string you specify. If you want multiple targets, you can specify them as a single argument to -MT, or use multiple -MT options.
For example, -MT '$(objpfx)foo.o' might give
$(objpfx)foo.o: foo.c
# 擦寫
./openocd -f wch-riscv.cfg -c init -c halt -c "flash erase_sector wch_riscv 0 last " -c exit
# 寫入
./openocd -f wch-riscv.cfg -c init -c halt -c "program ./obj/ch32v103_test001.elf" -c exit
# 校驗
./openocd -f wch-riscv.cfg -c init -c halt -c "verify_image ./obj/ch32v103_test001.elf" -c exit
# 重置,執行
./openocd -f wch-riscv.cfg -c init -c halt -c wlink_reset_resume -c exit
milton@/OpenOCD/bin$ ./openocd -f wch-riscv.cfg -c init -c halt -c "flash erase_sector wch_riscv 0 last " -c exit
Open On-Chip Debugger 0.11.0+dev-02215-gcc0ecfb6d-dirty (2022-06-23-10:21)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
Ready for Remote Connections
Info : WCH-Link-CH549 mod:RV version 2.5
Info : wlink_init ok
Info : This adapter doesn't support configurable speed
Info : JTAG tap: riscv.cpu tap/device found: 0x00000001 (mfg: 0x000 (<invalid>), part: 0x0000, ver: 0x0)
Warn : Bypassing JTAG setup events due to errors
Info : [riscv.cpu.0] datacount=2 progbufsize=8
Info : Examined RISC-V core; found 1 harts
Info : hart 0: XLEN=32, misa=0x0
[riscv.cpu.0] Target successfully examined.
Info : starting gdb server for riscv.cpu.0 on 3333
Info : Listening on port 3333 for gdb connections
Info : device id = 0x3c83abcd
Info : flash size = 64kbytes
erased sectors 0 through 63 on flash bank 0 in 0.019672s
milton@/OpenOCD/bin$ ./openocd -f wch-riscv.cfg -c init -c halt -c "program ch32v103_test001/obj/ch32v103_test001.elf" -c exit
Open On-Chip Debugger 0.11.0+dev-02215-gcc0ecfb6d-dirty (2022-06-23-10:21)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
Ready for Remote Connections
Info : WCH-Link-CH549 mod:RV version 2.5
Info : wlink_init ok
Info : This adapter doesn't support configurable speed
Info : JTAG tap: riscv.cpu tap/device found: 0x00000001 (mfg: 0x000 (<invalid>), part: 0x0000, ver: 0x0)
Warn : Bypassing JTAG setup events due to errors
Info : [riscv.cpu.0] datacount=2 progbufsize=8
Info : Vector support with vlenb=0
Info : Examined RISC-V core; found 1 harts
Info : hart 0: XLEN=32, misa=0xffffffff
[riscv.cpu.0] Target successfully examined.
Info : starting gdb server for riscv.cpu.0 on 3333
Info : Listening on port 3333 for gdb connections
Info : JTAG tap: riscv.cpu tap/device found: 0x00000001 (mfg: 0x000 (<invalid>), part: 0x0000, ver: 0x0)
Warn : Bypassing JTAG setup events due to errors
** Programming Started **
Info : device id = 0x3c83abcd
Info : flash size = 64kbytes
** Programming Finished **
milton@/OpenOCD/bin$ ./openocd -f wch-riscv.cfg -c init -c halt -c "verify_image ch32v103_test001/obj/ch32v103_test001.elf" -c exit
Open On-Chip Debugger 0.11.0+dev-02215-gcc0ecfb6d-dirty (2022-06-23-10:21)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
Ready for Remote Connections
Info : WCH-Link-CH549 mod:RV version 2.5
Info : wlink_init ok
Info : This adapter doesn't support configurable speed
Info : JTAG tap: riscv.cpu tap/device found: 0x00000001 (mfg: 0x000 (<invalid>), part: 0x0000, ver: 0x0)
Warn : Bypassing JTAG setup events due to errors
Info : [riscv.cpu.0] datacount=2 progbufsize=8
Info : Vector support with vlenb=0
Info : Examined RISC-V core; found 1 harts
Info : hart 0: XLEN=32, misa=0xffffffff
[riscv.cpu.0] Target successfully examined.
Info : starting gdb server for riscv.cpu.0 on 3333
Info : Listening on port 3333 for gdb connections
Info : Verify Success
milton@/OpenOCD/bin$ ./openocd -f wch-riscv.cfg -c init -c halt -c wlink_reset_resume -c exit
Open On-Chip Debugger 0.11.0+dev-02215-gcc0ecfb6d-dirty (2022-06-23-10:21)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
Ready for Remote Connections
Info : WCH-Link-CH549 mod:RV version 2.5
Info : wlink_init ok
Info : This adapter doesn't support configurable speed
Info : JTAG tap: riscv.cpu tap/device found: 0x00000001 (mfg: 0x000 (<invalid>), part: 0x0000, ver: 0x0)
Warn : Bypassing JTAG setup events due to errors
Info : [riscv.cpu.0] datacount=2 progbufsize=8
Info : Examined RISC-V core; found 1 harts
Info : hart 0: XLEN=32, misa=0x0
[riscv.cpu.0] Target successfully examined.
Info : starting gdb server for riscv.cpu.0 on 3333
Info : Listening on port 3333 for gdb connections