GD32VW553立创开发板折腾日志1

最近入手了一块GD32VW553的开发板,到手价9.9。 号称是有板载的2.4Ghz WiFi6 + BLE5.2支持,感觉买一个来玩玩很划算(?)

购买方式

首先去这里领取开发板优惠券,要求是发送到朋友圈并集5个赞。然后再去这里领取免邮券就可以9.9到手了。

购买凭证

到手开箱

除了开发板本体以外,还额外赠送了两个排针(x)除此以外居然是彩色丝印,给好评。 (图片占位)

东西很小巧,但是对一个买来当玩具的人(我)来说肯定够用了。

扫描随板附送的说明书二维码,可以看到板子的官方文档。扫了一眼感觉还是不错的,适合慢慢从头学起。但是我是一个很没有耐心的人,所以看了一点就开始自己折腾了!以下是一些折腾的成果,附带一些官方教程里没有的东西。

新建工程

新建工程(官方IDE)

点击左上角File -> New -> C/C++ Project新建项目。不要点首页的Create GD Project!!!

然后选择C/C++ Managed Build,选择Project Type: GigaDevice RISC-V Project。输入项目名,在下一页中找到GD32VW553HMQ6就完成了。

创建完成之后并不会自动打开项目,需要手动关闭Welcome选项卡。

新建工程(VSCode)

从头移植

在扩展中搜索Embedded IDE并安装,随后新建项目

GigaDevice资料下载处获取最新的GD32VW55x Firmware Library,解压。

Firmware, TemplateUtilities复制到项目下,删除Template下的xxx_project文件夹和Firmware\RISCV下的env_IAR, env_SES

新建src文件夹,将Template里的main.cmain.h移动到src

右键项目资源,点击添加源文件夹,点击普通文件夹,将Firmware, Template, Utilities, src添加到项目

点击构建配置,将链接脚本路径设置为Firmware\RISCV\env_Eclipse\GD32VW553xM.lds,点击构建器选项右边的编辑按钮,在新打开的页面中选择链接器选项卡,在“不生成指定的二进制文件”中删除*.bin file

在页面中选择全局选项,在编译器附加选项后面加入-msmall-data-limit=8 -mdiv

点击C/C++属性,在包含目录中添加Firmware/GD32VW55x_standard_peripheral, Firmware/GD32VW55x_standard_peripheral/Include, Template, Utilities, src, Firmware/RISCV/stubs, Firmware/RISCV/drivers

在预处理器定义中添加USE_STDPERIPH_DRIVER, HXTAL_VALUE=40000000U

使用模板

EIDE其实是有GD32VW553的模板的,只需要进行如下操作就可以直接启动了。

新建工程(CLion)

要在Clion环境下编译,我们需要先安装对应的工具链。本文使用的是xPack GNU RISC-V Embedded GCC v15.2.0-1,下载win32-x64的包后解压加入环境变量,重启CLion。

新建C可执行文件项目

GigaDevice资料下载处获取最新的GD32VW55x Firmware Library,解压。 将Firmware, TemplateUtilities复制到项目下,删除Template下的xxx_project文件夹和Firmware\RISCV下的env_IAR, env_SES文件夹。随后在项目根目录下新建src文件夹,将Template里的main.cmain.h移动到src内。

打开CMakeLists.txt,将内容更改为

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
cmake_minimum_required(VERSION 3.16)  
set(CMAKE_SYSTEM_NAME Generic)  
set(CMAKE_SYSTEM_PROCESSOR riscv)  
  
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)  
set(CMAKE_EXECUTABLE_SUFFIX .elf)  
project(gd32vw553 C ASM)  
  
set(TOOLCHAIN_PREFIX "riscv-none-elf-")  
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)  
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++)  
set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}gcc)  
set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy CACHE INTERNAL "objcopy tool")  
set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}objdump CACHE INTERNAL "objdump tool")  
set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size CACHE INTERNAL "size tool")  
set(CMAKE_AR ${TOOLCHAIN_PREFIX}ar)  
  
set(ARCH_FLAGS "-march=rv32imac_zicsr -mabi=ilp32 -mcmodel=medlow -msmall-data-limit=8 -mdiv")  
set(CMAKE_C_FLAGS "${ARCH_FLAGS} -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -std=gnu11")  
set(CMAKE_ASM_FLAGS "${ARCH_FLAGS} -x assembler-with-cpp")  
  
set(LDSCRIPT "${CMAKE_SOURCE_DIR}/Firmware/RISCV/env_Eclipse/GD32VW553xM.lds")  
set(CMAKE_EXE_LINKER_FLAGS  
        "${ARCH_FLAGS} -T${LDSCRIPT} -Wl,--cref -Wl,--gc-sections \    --specs=nosys.specs --specs=nano.specs -nostartfiles -Wl,-Bstatic")  
  
if(CMAKE_BUILD_TYPE STREQUAL "Debug")  
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -gdwarf-2 -O0")  
else()  
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")  
endif()  
  
add_definitions(  
        -DUSE_STDPERIPH_DRIVER  
        -DHXTAL_VALUE=40000000U  
)  
  
include_directories(  
        ${CMAKE_SOURCE_DIR}  
        ${CMAKE_SOURCE_DIR}/src  
        ${CMAKE_SOURCE_DIR}/Template  
        ${CMAKE_SOURCE_DIR}/Utilities  
        ${CMAKE_SOURCE_DIR}/Firmware/GD32VW55x_standard_peripheral/Include  
        ${CMAKE_SOURCE_DIR}/Firmware/GD32VW55x_standard_peripheral  
        ${CMAKE_SOURCE_DIR}/Firmware/RISCV/drivers  
)  
  
set(FIRMWARE_DIR ${CMAKE_SOURCE_DIR}/Firmware)  
  
file(GLOB_RECURSE C_SOURCES  
        "${FIRMWARE_DIR}/GD32VW55x_standard_peripheral/Source/*.c"  
        "${FIRMWARE_DIR}/GD32VW55x_standard_peripheral/*.c"  
        "${FIRMWARE_DIR}/RISCV/env_Eclipse/*.c"  
        "${FIRMWARE_DIR}/RISCV/stubs/*.c"  
        "${FIRMWARE_DIR}/RISCV/drivers/*.c"  
        "${CMAKE_SOURCE_DIR}/Template/*.c"  
        "${CMAKE_SOURCE_DIR}/Utilities/*.c"  
        "${CMAKE_SOURCE_DIR}/src/*.c"  
)  
  
set(ASM_SOURCES  
        ${FIRMWARE_DIR}/RISCV/env_Eclipse/start.S  
        ${FIRMWARE_DIR}/RISCV/env_Eclipse/entry.S  
)  
  
add_executable(${PROJECT_NAME} ${C_SOURCES} ${ASM_SOURCES})  
  
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD  
        COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:${PROJECT_NAME}> ${PROJECT_NAME}.hex  
        COMMAND ${CMAKE_OBJCOPY} -O binary -S $<TARGET_FILE:${PROJECT_NAME}> ${PROJECT_NAME}.bin  
        COMMAND ${CMAKE_OBJDUMP} -xS $<TARGET_FILE:${PROJECT_NAME}> > ${PROJECT_NAME}.s  
        COMMAND ${CMAKE_SIZE} $<TARGET_FILE:${PROJECT_NAME}>  
        COMMENT "Post-build: generating hex, bin and disassembly"  
)

加载CMake项目后点击小锤子即可编译。

如果你好奇CMake代码是怎么编写出来的,可以尝试对照3.2.1.从头移植理解一下^^

上手开发

更改GPIO

阅读代码发现,官方的示例中有非常完整的LED闪烁代码,但是接口定义和板子的不同。原理图告诉我们这个板子只有一个LED连接到GPIO:

LED原理图

可以发现LED1连接的是GPIOC的PIN13。打开Utilities\gd32vw553h_eval.h,进行以下更改

gd32vw553h_eval.h

打开Utilities\gd32vw553h_eval.c,进行以下更改

gd32vw553h_eval.c

打开src\main.c,进行以下更改

main.c

下载和调试

虽然板子留了JTAG接口且声称支持J-Link,但是芯片是RISC-V架构的。除非你的J-Link是花大价钱买的新款正版,不然洗洗睡吧。 因本人没有支持RISC-V的J-Link,也没有购买官方的GD-Link,所以这里只介绍如何使用串口下载。

注意:以下工具均可在兆易MCU资源中心找到最新版本。

官方GUI工具

使用官方的GD32 All-In-One Programmer即可方便地通过串口烧录程序。下载并解压后,双击打开GD32AllInOneProgrammer.exe,调整以下红框处参数

Port Name调整为CH340对应的串口号,将Baud Rate调整为512000。修改完成后,按住板子上的BOOT0按钮并轻按RESET按钮,此时MCU会进入BootLoader模式。现在你可以点击页面上的Connect按钮连接串口了。

连接完成且下方出现Device Information后,在右侧Download处点击Browse按钮,找到编译好的固件后Download,等待下方进度条跑满后,在没有按住BOOT0按钮的状态下再次轻按RESET按钮,此时固件烧录并启动成功。

嵌入IDE

使用官方的GD32_ISP_CLI配合各种脚本即可做到丝滑地编译+烧录。在进行以下操作前,请确保GD32_ISP_CLI.exe已在环境变量里。

VSCode(EIDE)

待补充

CLion(CMake)

在CMakeLists.txt中加入

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
set(COM_PORT 5) # 这里设置你的串口号

find_program(GD32_TOOL_PATH GD32_ISP_CLI.exe)  
get_filename_component(GD32_TOOL_DIR ${GD32_TOOL_PATH} DIRECTORY)  
add_custom_target(flash  
        COMMAND GD32_ISP_CLI.exe -c --pn ${COM_PORT} --br 512000 -i GD32VW553HMQ6 -d --a 08000000 --fn ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.bin --n || exit 0
        WORKING_DIRECTORY ${GD32_TOOL_DIR}  
        DEPENDS ${PROJECT_NAME}  
        COMMENT "Flashing via UART..."  
)

随后选择构建目标flash,点击小锤子即可编译并烧录。

疑难解答

Q: 我正在尝试在其他工具链中使用这个CLI,为什么提示Init OptionBytes failed!

A: 在目前最新的5.1.0.39034版本下,这个CLI工具依赖当前工作目录来获取OptionBytesXML。你需要想办法切换工作目录,或是把OptionBytesXML文件夹复制到当前目录下。

进阶SDK

要想使用蓝牙和WiFi,我们需要构建专用的SDK包。SDK内包括两个部分:MBLMSDKMBL就是我们固件的BootLoader,负责启动系统前的初始化工作。我们想要二次开发一般只需要修改MSDK部分,也就是MSDK\app文件夹内的代码。 在执行以下操作前,请先下载GD32VW553系列Wi-Fi & BLE SDK, Nuclei RISC-V Embedded Toolchain(Baremetal/RTOS + Newlibc)OpenOCD,并将工具链和OpenOCD添加至环境变量。

注意:以上工具可在兆易MCU资源中心芯来工具链找到最新版本。

如果你想尝试使用更新版本的工具链,请务必检查目标平台是否为riscv-nuclei-elf!! (为什么?)

注意:必须下载并将OpenOCD添加至环境变量,即使你使用串口下载。 (为什么?)

CLion(CMake)

打开项目GD32VW55x_RELEASE_V1.0.3g,点击设置 - 构建、执行、部署 - CMake,将CMake选项更改为-DCMAKE_TOOLCHAIN_FILE:PATH=scripts/cmake/toolchain.cmake

打开MSDK\plf\src\uart\uart_config.h,将第81行的#define LOG_UART UART2改为#define LOG_UART USART0

打开MBL\mainboot\mbl.c,将第48行的#define LOG_UART UART2改为#define LOG_UART USART0

将120行的
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
改为
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_8);
并同样修改122行的代码,配置上拉模式。

打开MSDK\plf\src\uart\uart.h,将58-64行的

1
2
3
4
5
6
7
#define USART0_TX_GPIO                  GPIOA  
#define USART0_TX_PIN                   GPIO_PIN_0  
#define USART0_TX_AF_NUM                GPIO_AF_0  
  
#define USART0_RX_GPIO                  GPIOA  
#define USART0_RX_PIN                   GPIO_PIN_1  
#define USART0_RX_AF_NUM                GPIO_AF_0

改为

1
2
3
4
5
6
7
#define USART0_TX_GPIO                  GPIOB  
#define USART0_TX_PIN                   GPIO_PIN_15  
#define USART0_TX_AF_NUM                GPIO_AF_8  
  
#define USART0_RX_GPIO                  GPIOA  
#define USART0_RX_PIN                   GPIO_PIN_8  
#define USART0_RX_AF_NUM                GPIO_AF_2

现在你应该能够编译MBL和MSDK了。编译完的固件bin在scripts\images文件夹下。

Licensed under CC BY-NC-SA 4.0