GD32VW553-IOT 测评和vscode开发环境搭建
GD32VW553-IOT 测评和vscode开发环境搭建
1. 背景介绍
iCEasy商城的产品, Firefly Workshop 萤火工厂的样片, 是一款基于GD32VW553 MCU的开源硬件, 这款MCU内置了32bit的RISC-V内核, 支持双模无线WIFI-6和BLE-5.2, 最高主频可达160Mhz.
本人曾在公司参与开发了一款基于RISC-V内核的触控芯片, 所以之前接触过兆易更早的一款RISC-V的MCU, 即GD32VF103, 同时也使用过GD32W5系列的IOT MCU, 这次正好看到了结合GD的V和W联手的产品, 于是就申请了一块板子回来研究研究。
同样想要玩玩这款芯片的小伙伴, 可以去申请样品, 链接如下:https://www.iceasy.com/
2. 准备工作
样品拿到手之后, 先去GD官网把手册和开发软件下载一下, 同时也可以去iCEasy商城网站上下载对应资料。https://www.gd32mcu.com/cn/download/0?kw=GD32VW5
- 用户手册、数据手册
- 固件库、原理图
- GD32AllInOneProgrammer_win
- GD32EmbeddedBuilder
3. 展示一下
4. 创建工程
基于GD32EmbeddedBuilder可以很方便快速的把demo程序跑起来, 下面是创建工程的步骤, 软件提供了MCU的ARM C project和RISC-V Cproject, 本次测试的芯片是基于RISC-V的, 因此选择对应的选项.
5. 工程结构
Firmware目录中是GD的外设库和RISC-V的驱动库, inc和src是具体实现的功能, 可以参考官方提供的demo来移植想要的功能, idscripts提供的链接文件, 指定了芯片的内存大小和布局, openocd提供了基于gd_link的openocd下载脚本。
比较需要注意的是Firmware/RISC-V/env_Eclipse和stubs文件夹, 其中stubs文件夹提供的是一些系统调用的桩函数, env_Eclipse文件夹下提供的entry.S和start.S实现了芯片启动部分和中断向量表设置。
编译选项如图所示:
riscv-nuclei-elf-gcc -march=rv32imac -mabi=ilp32 -mcmodel=medlow -msmall-data-limit=8 -mdiv -O0 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -g3 -std=gnu11 -DGD_ECLIPSE_GCC -DUSE_STDPERIPH_DRIVER ........
riscv-nuclei-elf-gcc -march=rv32imac -mabi=ilp32 -mcmodel=medlow -msmall-data-limit=8 -mdiv -O0 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -g3 -Wa,-adhlns=Firmware/RISCV/env_Eclipse/entry.o.lst -x assembler-with-cpp -I"../Firmware/RISCV/drivers" -c -o "Firmware/RISCV/env_Eclipse/entry.o" "../Firmware/RISCV/env_Eclipse/entry.S"
riscv-nuclei-elf-gcc -march=rv32imac -mabi=ilp32 -mcmodel=medlow -msmall-data-limit=8 -mdiv -O0 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -g3 -Wl,-Map,"gd32vw553_test.map" -T GD32VW55X.lds -nostartfiles -Xlinker --gc-sections -L"../ldscripts/" --specs=nano.specs --specs=nosys.specs -o "gd32vw553_test.elf" ......
6. 代码下载
- 启动模式修改, 从表中可以看出, 将BOOT0接高之后, 会从Bootloader启动, 就能用串口ISP更新固件, 根据原理图可以看出, 首先需要将R4和R5两个电阻焊接上
7. 串口LOG打印和LED闪烁
-
使用的是串口0和PA15作为LED口
int main(void){/* configure systick */systick_config();eclic_priority_group_set(ECLIC_PRIGROUP_LEVEL3_PRIO1);/* enable the led clock */rcu_periph_clock_enable(RCU_GPIOA);/* configure led GPIO port */gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_15);gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO_PIN_15);GPIO_BC(GPIOA) = GPIO_PIN_15;/* initilize the LEDs, USART and key */gd_eval_com_init(EVAL_COM0);/* print out the clock frequency of system, AHB, APB1 and APB2 */printf("CK_SYS is %d\r\n", rcu_clock_freq_get(CK_SYS));printf("CK_AHB is %d\r\n", rcu_clock_freq_get(CK_AHB));printf("CK_APB1 is %d\r\n", rcu_clock_freq_get(CK_APB1));printf("CK_APB2 is %d\r\n", rcu_clock_freq_get(CK_APB2));while(1) {delay_1ms(500);GPIO_TG(GPIOA) = GPIO_PIN_15;}}
-
在桩函数中修改串口打印的功能
int _put_char(int ch){usart_data_transmit(EVAL_COM0, (uint8_t) ch );while (usart_flag_get(EVAL_COM0, USART_FLAG_TBE)== RESET){}return ch;}
-
将代码下载进板子, 打开串口助手, 可以看到log打印
8. vscode开发环境搭建
-
目录修改
-
CmakeList.txt编写
cmake_minimum_required(VERSION 3.22)# Setup compiler settings
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)###########################################################
# Set the project name
set(CMAKE_PROJECT_NAME gd32vw553_test)set(APP_ADDR "0x08000000") # 从0x08000000启动
add_definitions(-DDOWNLOAD_MODE=DOWNLOAD_MODE_FLASHXIP -DDOWNLOAD_MODE_STRING=\"FLASHXIP\" -D__IDE_RV_DE_RV_CORE=n303 -DSYSTEM_CLOCK=160000000 -DSYSCLK_USING_HXTAL)# Define the build type
if(NOT CMAKE_BUILD_TYPE)set(CMAKE_BUILD_TYPE "Debug")
endif()find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif(CCACHE_FOUND)###########################################################
# Include toolchain file
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR riscv)set(CMAKE_C_COMPILER_FORCED TRUE)
set(CMAKE_CXX_COMPILER_FORCED TRUE)
set(CMAKE_C_COMPILER_ID GNU)
set(CMAKE_CXX_COMPILER_ID GNU)# Some default GCC settings
# riscv64-unknown-elf- must be part of path environment
set(TOOLCHAIN_PREFIX riscv64-unknown-elf-)set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++)
set(CMAKE_LINKER ${TOOLCHAIN_PREFIX}g++)
set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy)
set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size)
set(CMAKE_OpenOCD "E:/Program Files/NucleiStudio/toolchain/openocd/bin/openocd.exe")set(CMAKE_EXECUTABLE_SUFFIX_ASM ".elf")
set(CMAKE_EXECUTABLE_SUFFIX_C ".elf")
set(CMAKE_EXECUTABLE_SUFFIX_CXX ".elf")set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)# MCU specific flags
set(TARGET_FLAGS "-march=rv32imac -mabi=ilp32 -mtune=nuclei-200-series -mcmodel=medlow -mno-save-restore")set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TARGET_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -fno-common")if(CMAKE_BUILD_TYPE MATCHES Debug)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Og -g -gdwarf-2")
endif()
if(CMAKE_BUILD_TYPE MATCHES Release)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
endif()
if(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g")
endif()
if(CMAKE_BUILD_TYPE MATCHES MinSizeRel)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os")
endif()set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp -MMD -MP")set(CMAKE_C_LINK_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -T \"${CMAKE_SOURCE_DIR}/ldscripts/GD32VW55X.lds\"")
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostartfiles")
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,-Map=${CMAKE_PROJECT_NAME}.map -Wl,--check-sections -Wl,--no-warn-rwx-segments")
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group -lc -lm -Wl,--end-group")
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--print-memory-usage")set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions -fno-threadsafe-statics")
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group,-lstdc++,-lc_nano,-lgcc,--end-group")
########################################################### Enable compile command to ease indexing with e.g. clangd
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)# must need
enable_language(C ASM)# Core project settings
project(${CMAKE_PROJECT_NAME})
message("Build type: " ${CMAKE_BUILD_TYPE})# Create an executable object type
add_executable(${CMAKE_PROJECT_NAME})# 汇编的宏定义
# Add project symbols (macros)
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE# Add user defined symbols
)# Add linked libraries
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATEstm32cubemx# Add user defined libraries
)##########################################################
add_library(stm32cubemx INTERFACE)target_compile_definitions(stm32cubemx INTERFACE # TX_INCLUDE_USER_DEFINE_FILE
)target_include_directories(stm32cubemx INTERFACEApplication/Include/ Hardware/Include/Firmware/GD32VW55x_standard_peripheral/Firmware/GD32VW55x_standard_peripheral/Include/Firmware/RISCV/drivers/# Firmware/OS/FreeRTOS/Source/include# Firmware/OS/FreeRTOS/Source/portable# Firmware/OS/ThreadX/common/inc# Firmware/OS/ThreadX/ports/nuclei/
)file(GLOB SRC_LIB_0 Firmware/GD32VW55x_standard_peripheral/*.c)
file(GLOB SRC_LIB_1 Firmware/GD32VW55x_standard_peripheral/Source/*.c)
file(GLOB SRC_LIB_2 Firmware/RISCV/env_Eclipse/*.c)
file(GLOB SRC_LIB_3 Firmware/RISCV/stubs/*.c)# file(GLOB SRC_LIB_4 Firmware/OS/FreeRTOS/Source/*.c)
# file(GLOB SRC_LIB_5 Firmware/OS/FreeRTOS/Source/portable/*.c)
# file(GLOB SRC_LIB_6 Firmware/OS/FreeRTOS/Source/portable/MemMang/*.c)
# file(GLOB SRC_LIB_7 Firmware/OS/FreeRTOS/Source/portable/GCC/portasm.S)# file(GLOB SRC_LIB_4 Firmware/OS/ThreadX/common/src/*.c)
# file(GLOB SRC_LIB_5 Firmware/OS/ThreadX/ports/nuclei/*.c)
# file(GLOB SRC_LIB_6 Firmware/OS/ThreadX/ports/nuclei/gcc/context.S)
# file(GLOB SRC_LIB_7 Firmware/OS/ThreadX/ports/nuclei/gcc/interrupt.S)file(GLOB SRC_APP_0 Application/Source/*.c)
file(GLOB SRC_APP_1 Hardware/Source/*.c)target_sources(stm32cubemx INTERFACE${SRC_APP_0}${SRC_APP_1}${SRC_LIB_0}${SRC_LIB_1}${SRC_LIB_2}${SRC_LIB_3}${SRC_LIB_4}${SRC_LIB_5}${SRC_LIB_6}${SRC_LIB_7}# GLOB *.S doesn't workFirmware/RISCV/env_Eclipse/entry.SFirmware/RISCV/env_Eclipse/start.S
)
##########################################################
# For Download & Debug
set(ELF_FILE ${PROJECT_NAME}.elf)
set(HEX_FILE ${PROJECT_NAME}.hex)
set(BIN_FILE ${PROJECT_NAME}.bin)
set(DFU_FILE ${PROJECT_NAME}.dfu)# PRE_BUILD(预构建)、PRE_LINK(链接前)和POST_BUILD(构建后)用于指定自定义命令在构建过程中的执行时机。
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILDCOMMAND ${CMAKE_OBJCOPY} -Obinary -S ${ELF_FILE} ${BIN_FILE}COMMAND ${CMAKE_OBJCOPY} -Oihex ${ELF_FILE} ${HEX_FILE}COMMENT "Building ${PROJECT_NAME}.bin and ${PROJECT_NAME}.hex"
)# print size
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILDCOMMAND ${CMAKE_SIZE} --format=berkeley ${PROJECT_NAME}.elfCOMMENT "Invoking: Cross ARM GNU Print Size"
)# make openocd_flash
add_custom_target(openocd_flashCOMMAND ${CMAKE_OpenOCD} -f "${CMAKE_SOURCE_DIR}/nuclei_sdk/SoC/gd32vf103/Board/gd32vf103v_rvstar/openocd_gd32vf103.cfg" -c "program gd32vf103.elf verify reset exit"COMMENT "USE OpenOCD to make flash at ${APP_ADDR}"
)
- 编译工具链配置(这里windows平台工具链下载就不多说了,下载对应工具,然后添加环境变量可以找找其他教程)
- gcc
- riscv-none-embed-gcc
- ninja
- cmake
- cacache
9. Timer Breath LED
- 移植DEMO中的Timer Breath LED功能
10. 移植MBL和MSDK
SDK 最终生成的执行程序主要有两个:一个是 MBL(Main Bootloader),一个是 MSDK
( Main SDK ) 。它们最终都将被烧写到 FLASH 运行。 上电之后, 程序将从 MBL 的
Reset_Handler 启动,然后跳转到 MSDK 主程序运行
- 三个配置文件
- GD32VW55x_RELEASE/config/platform_def.h 用于配置WIFI 和 BLE
- GD32VW55x_RELEASE/config/config_gdm32.h 用于设置Flahs和SRAM内存布局
- GD32VW55x_RELEASE/MSDK/app/app_cfg.h 用于配置一些无线相关的应用, 例如: ATCMD,阿里云, MQTT, COAP
注:通过修改 app_cfg.h 内的宏CONFIG_BLE_LIB 可切换BLE library。将 CONFIG_BLE_LIB 配
置为 BLE_LIB_MIN,工程编译时会选择libble.a,同时头文件会include ble_config_min.h;将CONFIG_BLE_LIB 配置为BLE_LIB_MAX, 工程编译时会选择 libble_max.a,同时头文件会include ble_config_max.h。
-
工程配置
-
编译工程
- Embedded Builder IDE 下编译和调试 SDK。首先下载GD32VW55x_RELEASE, 目前官网最新版本是1.0.3a.
- 将workspaces 指向 GD32VW55x_RELEASE 目录
- 然后选择 MSDK 或 MBL 工程进行导入, 路径为GD32VW55x_RELEASE/MBL/project/eclipse和GD32VW55x_RELEASE/MSDK/projects/eclipse/msdk
- 分别编译 MBL 和 MSDK 工程
- MSDK 编译完成之后, 会调用 MSDK/projects/image_afterbuild.bat 生成 image-ota.bin 和image-all.bin。并将生成的 bin 文件拷贝至/scripts/images 内, image-ota.bin是MSDK工程生成的bin文件,可用于OTA 升级, image-all.bin是MBL(mbl.bin)和 MSDK(image-ota.bin)的组合,该固件可用于生产,烧录到 FLASH 中运行
- 编译报错
编译MSDK时候,出现了以下错误信息, 而且image没有成功生成
导致的原因是bat命令没有识别出我路径中的空格, 这里我的路径是program file, 导致脚本将空格之后和空格之前设别成了两条指令,解决办法就是将整个路径用双引号括起来
11. 初始化成功
视频链接和项目地址
- https://github.com/1508912767/gd32vw553_test
- https://www.bilibili.com/video/BV1MEeJzrE9u/