
1. 引言在嵌入式开发中USB 通信是设备与上位机交互的重要方式。GD32 系列 MCU 自带 USB 外设通过移植 USBDUSB Device库并配置 CDCCommunication Device Class类可以快速实现虚拟串口功能让设备通过 USB 线直接与 PC 进行串口通信无需额外硬件。本文将以 GD32F4xx 系列为例详细介绍如何从零开始移植 USBD 库并实现 CDC 移植完整流程。2. 准备工作首先准备一个空白能跑的工程文件本文基于已经移植好的freertos工程进行展示需要移植freertos的可以看我前两期内容。硬件兆易创新GigaDevice-资料下载兆易创新GD32 MCUhttps://www.gd32mcu.com/cn/download?kwGD32F4lancn官方网上是有给这里例程的我们从上面抄袭一下。应该是这个样子我们找到我们需要的库函数参考目录GD32F4xx_Demo_Suites_V3.3.3\GD32F4xx_Demo_Suites_V3.3.3\GD32F4xx_Demo_Suites_V3.3.3\GD32450V_START_Demo_Suites\GD32F4xx_Firmware_Library3. 文件裁剪首先这个host是作为主机模式的我们不需要可以删除只保留上面这三个就行了点开 /driver/Source 图中两个也是作为主机才会使用的可以删除点开 /device/class 仅仅保留 cdc 就好参考路径 GD32F4xx_usb_library\ustd\class 也是只保留 cdc 就好了4. 移植到工程文件然后还有一个usb_port驱动层也是需要去源码里面去拿参考目录\GD32F4xx_Demo_Suites_V3.3.3\GD32F4xx_Demo_Suites_V3.3.3\GD32F4xx_Demo_Suites_V3.3.3\GD32450V_START_Demo_Suites\Projects\05_USB_MSC_Device分别移植其中的src和inc可以单独在我们自己的usb文件中新建立一个文件夹把这两个文件放进去当然也不是都是有用的下面标出来的也可以进行删除src这里只有这个是底层驱动编写的其他的是关于msc的文件也可以删除再次移植记得添加头文件5. 应用层适配关于usb_conf.h和usbd_conf.h都是一些关于的配置我下面贴自己注释好的可以直接粘我这一部分#ifndef __USB_CONF_H #define __USB_CONF_H #include stdlib.h // 包含标准库 #include gd32f4xx.h // 包含GD32F4系列寄存器头文件 #include drv_usb_regs.h //#include gd32f450v_start.h // USB内核与PHY接口配置 // USB全速/高速PHY配置 #ifdef USE_USB_FS // 若启用USB全速 #define USB_FS_CORE // 定义全速内核标志 #endif /* USE_USB_FS */ // 全速判断结束 #ifdef USE_USB_HS // 若启用USB高速 #define USB_HS_CORE // 定义高速内核标志 #endif /* USE_USB_HS */ // 高速判断结束 /* USB FIFO size config */ // USB FIFO大小配置 #ifdef USB_FS_CORE // 全速内核FIFO配置 #define RX_FIFO_FS_SIZE 128 // 全速接收FIFO大小(字) #define TX0_FIFO_FS_SIZE 64 // 全速TX0 FIFO大小(字) #define TX1_FIFO_FS_SIZE 128 // 全速TX1 FIFO大小(字) #define TX2_FIFO_FS_SIZE 0 // 全速TX2 FIFO未使用 #define TX3_FIFO_FS_SIZE 0 // 全速TX3 FIFO未使用 #define USBFS_SOF_OUTPUT 0 // 禁止全速SOF输出 #define USBFS_LOW_POWER 0 // 全速低功耗模式 #endif /* USB_FS_CORE */ // 全速FIFO配置结束 #ifdef USB_HS_CORE // 高速内核FIFO配置 #define RX_FIFO_HS_SIZE 512 // 高速接收FIFO大小(字) #define TX0_FIFO_HS_SIZE 128 // 高速TX0 FIFO大小(字) #define TX1_FIFO_HS_SIZE 384 // 高速TX1 FIFO大小(字) #define TX2_FIFO_HS_SIZE 0 // 高速TX2 FIFO未使用 #define TX3_FIFO_HS_SIZE 0 // 高速TX3 FIFO未使用 #define TX4_FIFO_HS_SIZE 0 // 高速TX4 FIFO未使用 #define TX5_FIFO_HS_SIZE 0 // 高速TX5 FIFO未使用 #ifdef USE_ULPI_PHY // 若使用ULPI PHY #define USB_ULPI_PHY_ENABLED // 使能ULPI PHY #endif // ULPI判断结束 #ifdef USE_EMBEDDED_PHY // 若使用内置PHY #define USB_EMBEDDED_PHY_ENABLED // 使能内置PHY #endif // 内置PHY判断结束 // #define USB_HS_INTERNAL_DMA_ENABLED // 高速内部DMA(已禁用) // #define USB_HS_DEDICATED_EP1_ENABLED // EP1专用通道(已禁用) #define USBHS_SOF_OUTPUT 0 // 禁止高速SOF输出 #define USBHS_LOW_POWER 0 // 禁止高速低功耗模式 #endif /* USB_HS_CORE */ // 高速FIFO配置结束 //#define VBUS_SENSING_ENABLED // VBUS检测(已禁用) //#define USE_HOST_MODE // 主机模式(已禁用) #define USE_DEVICE_MODE // 使能从机模式 //#define USE_OTG_MODE // OTG模式(已禁用) #ifndef USB_FS_CORE // 若未定义全速内核 #ifndef USB_HS_CORE // 且未定义高速内核 #error USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 #endif // 高速内核检查结束 #endif // 全速内核检查结束 #ifndef USE_DEVICE_MODE // 若未定义从机模式 #ifndef USE_HOST_MODE // 且未定义主机模式 #error USE_DEVICE_MODE or USE_HOST_MODE should be defined! // 报错提示必须选择工作模式 #endif // 主机模式检查结束 #endif // 从机模式检查结束 #ifndef USE_USB_HS // 若未定义高速宏 #ifndef USE_USB_FS // 且未定义全速宏 #error USE_USB_HS or USE_USB_FS should be defined! // 报错提示必须指定速度 #endif // 全速宏检查结束 #endif // 高速宏检查结束 // 事务数据需4字节对齐 #ifdef USB_HS_INTERNAL_DMA_ENABLED // 若使能高速内部DMA #if defined (__GNUC__) /* GNU Compiler */ // GCC编译器 #define __ALIGN_END __attribute__ ((aligned (4))) // 尾部对齐属性 #define __ALIGN_BEGIN // 头部对齐为空 #else // 非GCC编译器 #define __ALIGN_END // 尾部对齐为空 #if defined (__CC_ARM) /* ARM Compiler */ // Keil编译器 #define __ALIGN_BEGIN __align(4) // 头部4字节对齐 #elif defined (__ICCARM__) /* IAR Compiler */ // IAR编译器 #define __ALIGN_BEGIN // IAR无需头部对齐关键字 #elif defined (__TASKING__)/* TASKING Compiler */// TASKING编译器 #define __ALIGN_BEGIN __align(4) // 头部4字节对齐 #endif /* __CC_ARM */ // 编译器判断结束 #endif /* __GNUC__ */ // GCC判断结束 #else // 未使能DMA时 #define __ALIGN_BEGIN // 头部对齐为空 #define __ALIGN_END // 尾部对齐为空 #endif /* USB_HS_INTERNAL_DMA_ENABLED */ // DMA对齐宏定义结束 // packed关键字强制1字节对齐 #if defined (__GNUC__) /* GNU Compiler */ // GCC编译器 #ifdef __packed // 若已定义packed #undef __packed // 取消原有定义 #endif // packed检查结束 #define __packed // GCC下packed为空(用attribute替代) #elif defined (__TASKING__) /* TASKING Compiler */ // TASKING编译器 #define __packed __unaligned // TASKING用__unaligned代替 #endif /* __CC_ARM */ // 编译器packed定义结束 #endif /* __USB_CONF_H */#ifndef __USBD_CONF_H #define __USBD_CONF_H #include usb_conf.h #define USBD_CFG_MAX_NUM 1 // 最大配置描述符数量 #define USBD_ITF_MAX_NUM 1 // 最大接口数量 #define USB_STR_DESC_MAX_SIZE 64 // 字符串描述符最大字节数 /*------------------------------ CDC 宏定义 ------------------------------*/ #define USB_CDC_DATA_PACKET_SIZE 64 #define USB_CDC_CMD_PACKET_SIZE 8 #define CDC_CMD_EP EP2_IN #define CDC_DATA_OUT_EP EP1_OUT #define CDC_DATA_IN_EP EP1_IN #define CDC_COM_INTERFACE 0 /*------------------------------ MSC 宏定义 ------------------------------*/ #define USBD_MSC_INTERFACE 0 // MSC类使用的接口编号 #define MSC_IN_EP EP1_IN // MSC批量传输IN端点 #define MSC_OUT_EP EP1_OUT // MSC批量传输OUT端点 #ifdef USE_USB_HS #ifdef USE_ULPI_PHY // 若使用ULPI外部PHY #define MSC_DATA_PACKET_SIZE 512 // MSC数据包大小512字节 #else // 否则(内置HS PHY) #define MSC_DATA_PACKET_SIZE 64 // MSC数据包大小64字节 #endif // ULPI判断结束 #else #define MSC_DATA_PACKET_SIZE 64 // MSC数据包大小64字节 #endif // HS/FS判断结束 #define MSC_MEDIA_PACKET_SIZE 4096 // 介质读写缓冲区大小 #define MEM_LUN_NUM 1 // 逻辑单元数量(几个盘) #define USB_STRING_COUNT 4 // USB字符串描述符个数 #endif /* __USBD_CONF_H */关于app部分他官方有给一个例程看看是怎么写的不过这个例程是关于msc的参考目录GD32F4xx_Demo_Suites_V3.3.3\GD32F4xx_Demo_Suites_V3.3.3\GD32F4xx_Demo_Suites_V3.3.3\GD32450V_START_Demo_Suites\Projects\05_USB_MSC_Device\src/*! \file app.c \brief main routine \version 2026-02-12, V3.3.3, demo for GD32F4xx */ /* Copyright (c) 2026, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include drv_usb_hw.h #include usbd_msc_core.h usb_core_driver msc_udisk; unsigned char SRAM[40 * 1024]; /*! \brief main routine will construct a USB MSC device \param[in] none \param[out] none \retval none */ int main(void) { /* configure the GPIO */ usb_gpio_config(); /* configure the USB peripheral clock */ usb_rcu_config(); /* initialize the USB timer */ usb_timer_init(); usbd_init(msc_udisk, #ifdef USE_USB_FS USB_CORE_ENUM_FS, #elif defined(USE_USB_HS) USB_CORE_ENUM_HS, #endif msc_desc, msc_class); usb_intr_config(); while (1) { } }大概意思就是做一些初始化操作我们也可以学着弄先尝试编译一下Build started: Project: gd32f450test *** Using Compiler V5.06 update 7 (build 960), folder: D:\keil5\keil535\ARM\ARMCC\Bin Build target Target 1 compiling cdc_acm_core.c... ..\GD32F4xx_usb_library\port\inc\usb_conf.h(66): error: #35: #error directive: USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 #error USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 ..\GD32F4xx_usb_library\device\class\cdc_acm_core.c: 0 warnings, 1 error compiling usbd_enum.c... ..\GD32F4xx_usb_library\port\inc\usb_conf.h(66): error: #35: #error directive: USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 #error USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 ..\GD32F4xx_usb_library\device\core\Source\usbd_enum.c: 0 warnings, 1 error compiling usbd_transc.c... ..\GD32F4xx_usb_library\port\inc\usb_conf.h(66): error: #35: #error directive: USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 #error USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 ..\GD32F4xx_usb_library\device\core\Source\usbd_transc.c: 0 warnings, 1 error compiling drv_usb_core.c... ..\GD32F4xx_usb_library\port\inc\usb_conf.h(66): error: #35: #error directive: USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 #error USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 ..\GD32F4xx_usb_library\driver\Source\drv_usb_core.c: 0 warnings, 1 error compiling usbd_core.c... ..\GD32F4xx_usb_library\port\inc\usb_conf.h(66): error: #35: #error directive: USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 #error USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 ..\GD32F4xx_usb_library\device\core\Source\usbd_core.c: 0 warnings, 1 error compiling drv_usbd_int.c... ..\GD32F4xx_usb_library\port\inc\usb_conf.h(66): error: #35: #error directive: USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 #error USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 ..\GD32F4xx_usb_library\driver\Source\drv_usbd_int.c: 0 warnings, 1 error compiling gd32f4xx_hw.c... ..\GD32F4xx_usb_library\port\inc\usb_conf.h(66): error: #35: #error directive: USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 #error USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 ..\GD32F4xx_usb_library\port\src\gd32f4xx_hw.c: 0 warnings, 1 error compiling drv_usb_dev.c... ..\GD32F4xx_usb_library\port\inc\usb_conf.h(66): error: #35: #error directive: USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 #error USB_HS_CORE or USB_FS_CORE should be defined! // 报错提示必须选择一种内核 ..\GD32F4xx_usb_library\driver\Source\drv_usb_dev.c: 0 warnings, 1 error .\Objects\gd32f450test.axf - 8 Error(s), 0 Warning(s). Target not created. Build Time Elapsed: 00:00:01这里提出库函数么有办法区分我们是那种usb设备查了一下手册gd32f450能支持这个全速和高速不过如果是hs的话需要外接一个芯片我这里硬件没有外接所以这里是fs需要再宏定义头文件这里添加一个,USE_USB_FS再次编译就没有什么问题了创建一个usbd.c.h文件来编写我们的应用层其实很简单就只有一个初始化仿照那个app写就好了我这里是做一个数据队列然后后面方便接入项目做比较方便下面大家可以参考一下/*------------------------------ 头文件 ------------------------------ */ #include main.h #include gd32f4xx_rcu.h #include usbd.h #include usb_conf.h #include drv_usb_hw.h #include usbd_core.h #include drv_usbd_int.h #include cdc_acm_core.h /*------------------------------ 宏定义 ------------------------------ */ /*------------------------------ 全局变量定义 ------------------------------ */ /* APP */ usb_core_driver cdc_udisk; /* BSP */ QueueHandle_t xCdcRxQueue; /*------------------------------ 枚举定义 ------------------------------ */ /*------------------------------ 静态函数声明 ------------------------------ */ /*------------------------------ 结构体定义 ------------------------------ */ /*------------------------------ 联合体定义 ------------------------------ */ /*------------------------------ 联合体定义 ------------------------------ */ /*------------------------------ 外部函数声明 ------------------------------ */ /*------------------------------ 外部函数 ------------------------------ */ /* APP */ /****************************************************************************** 函数名称 void USBDTask(void *pvParameters) 函数版本 1.00 功能说明 usbd线程函数 输入参数 无 输出参数 无 返回值 无 其它说明 ******************************************************************************/ void USBDTask(void *pvParameters) { USB_Init(); xCdcRxQueue xQueueCreate(CDC_RX_QUEUE_LEN, sizeof(cdc_queue)); if (xCdcRxQueue NULL) {while(1); } while (1) { if (USBD_CONFIGURED cdc_udisk.dev.cur_status) { cdc_acm_data_receive(cdc_udisk); usb_cdc_handler *cdc (usb_cdc_handler *)cdc_udisk.dev.class_data[CDC_COM_INTERFACE]; if (cdc cdc-receive_length 0) { cdc_queue item; uint16_t copy_len (cdc-receive_length CDC_RX_PACKET_MAX) ? CDC_RX_PACKET_MAX : cdc-receive_length; memcpy(item.data, cdc-data, copy_len); item.len copy_len; if (xQueueSendToBack(xCdcRxQueue, item, 0) ! pdPASS) { // 队列满丢弃 } cdc-receive_length 0; } cdc_acm_data_send(cdc_udisk); } vTaskDelay(10); } } /****************************************************************************** 函数名称 void ProtocalTask(void *pvParameters) 函数版本 1.00 功能说明 数据线程函数 输入参数 无 输出参数 无 返回值 无 其它说明 ******************************************************************************/ void ProtocalTask(void *pvParameters) { cdc_queue item; while (1) { if (xQueueReceive(xCdcRxQueue, item, portMAX_DELAY) pdPASS){ usbd_ep_send(cdc_udisk, CDC_DATA_IN_EP, item.data, item.len); } } } /****************************************************************************** 函数名称 void USB_Init(void) 函数版本 1.00 功能说明 usbd初始化函数 输入参数 无 输出参数 无 返回值 无 其它说明 ******************************************************************************/ void USB_Init(void) { //硬件初始化 usb_gpio_config(); usb_rcu_config(); usb_timer_init(); usb_intr_config(); { usbd_init(cdc_udisk, #ifdef USE_USB_FS USB_CORE_ENUM_FS, #elif defined(USE_USB_HS) USB_CORE_ENUM_HS, #endif cdc_desc, cdc_class); } } /****************************************************************************** 函数名称 void USBFS_IRQHandler(void) 函数版本 1.00 功能说明 usbd串口回调函数 输入参数 无 输出参数 无 返回值 无 其它说明 无 ******************************************************************************/ void USBFS_IRQHandler(void) { usbd_isr(cdc_udisk); }#ifndef USBD_H #define USBD_H /*------------------------------ 头文件 ------------------------------ */ #include main.h /*------------------------------ 宏定义 ------------------------------ */ #define CDC_RX_QUEUE_LEN 10 // 队列最多缓存10包 #define CDC_RX_PACKET_MAX 64 // 每包最大64字节全速CDC包大小 /*------------------------------ 全局变量定义 ------------------------------ */ /*------------------------------ 枚举定义 ------------------------------ */ typedef struct { uint8_t data[CDC_RX_PACKET_MAX]; uint16_t len; } cdc_queue; /*------------------------------ 静态函数声明 ------------------------------ */ /*------------------------------ 类型定义 ------------------------------ */ typedef void (*usbd_suspend_callback_t)(void); /*------------------------------ 结构体定义 ------------------------------ */ /*------------------------------ 联合体定义 ------------------------------ */ /*------------------------------ 联合体定义 ------------------------------ */ /*------------------------------ 外部函数声明 ------------------------------ */ /*------------------------------ 静态函数 ------------------------------ */ /*------------------------------ 外部函数 ------------------------------ */ /****************************************************************************** 函数名称 void USBDTask(void *pvParameters) 函数版本 1.00 功能说明 usbd线程函数 输入参数 无 输出参数 无 返回值 无 其它说明 ******************************************************************************/ void USBDTask(void *pvParameters); /****************************************************************************** 函数名称 void ProtocalTask(void *pvParameters) 函数版本 1.00 功能说明 数据线程函数 输入参数 无 输出参数 无 返回值 无 其它说明 ******************************************************************************/ void ProtocalTask(void *pvParameters); /****************************************************************************** 函数名称 void USB_Init(void) 函数版本 1.00 功能说明 usbd初始化函数 输入参数 无 输出参数 无 返回值 无 其它说明 ******************************************************************************/ void USB_Init(void); /****************************************************************************** 函数名称 void USBFS_IRQHandler(void) 函数版本 1.00 功能说明 usbd串口回调函数 输入参数 无 输出参数 无 返回值 无 其它说明 ******************************************************************************/ void USBFS_IRQHandler(void); #endif下面是我的main函数#include main.h #define INIT_TASK_PRIO ( tskIDLE_PRIORITY 5 ) #define Led_Task_PRIO ( tskIDLE_PRIORITY 1 ) #define Regular_Task_PRIO ( tskIDLE_PRIORITY 1 ) #define USBD_Task_PRIO ( tskIDLE_PRIORITY 2 ) #define PROTOCAL_Task_PRIO ( tskIDLE_PRIORITY 1 ) TaskHandle_t InitTask_Handler NULL; TaskHandle_t LedTask_Handle NULL; TaskHandle_t RegularTask_Handle NULL; TaskHandle_t USBDTask_Handle NULL; TaskHandle_t PROTOCALTask_Handle NULL; void LedTask (void *pvParameters); void RegularTask (void *pvParameters); void USBDTask (void *pvParameters); void InitTask (void *pvParameters) { BaseType_t err; SEGGER_RTT_Init(); taskENTER_CRITICAL(); err xTaskCreate(LedTask, _LED , configMINIMAL_STACK_SIZE , NULL, Led_Task_PRIO ,(TaskHandle_t *)LedTask_Handle); err xTaskCreate(RegularTask, _REGULAR , configMINIMAL_STACK_SIZE , NULL, Regular_Task_PRIO ,(TaskHandle_t *)RegularTask_Handle); err xTaskCreate(USBDTask, _USBD , configMINIMAL_STACK_SIZE*70 , NULL, USBD_Task_PRIO ,(TaskHandle_t *)USBDTask_Handle); err xTaskCreate(ProtocalTask, _PROTOCAL , configMINIMAL_STACK_SIZE , NULL, PROTOCAL_Task_PRIO ,(TaskHandle_t *)PROTOCALTask_Handle); if (err pdPASS){} vTaskDelete(InitTask_Handler); taskEXIT_CRITICAL(); } void Led_Init(void) { rcu_periph_clock_enable(RCU_GPIOD); gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_13); gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13); gpio_bit_set(GPIOD, GPIO_PIN_13); } int main(void) { nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0); __set_PRIMASK(0); //开启中断 xTaskCreate(InitTask, _INIT, configMINIMAL_STACK_SIZE, NULL, INIT_TASK_PRIO, (TaskHandle_t* )InitTask_Handler); vTaskStartScheduler(); while(1) { } } void LedTask(void *pvParameters) { Led_Init(); while(1) { gpio_bit_set(GPIOD, GPIO_PIN_13); vTaskDelay(125); gpio_bit_reset(GPIOD, GPIO_PIN_13); vTaskDelay(125); SEGGER_RTT_printf(0,OK\n); } } void RegularTask(void *pvParameters) { while(1) { SEGGER_RTT_printf(0,Ready\n); vTaskDelay(1000); } }编译通过其实也没有什么问题但是发现没有跑起来查看发现这个usb是基于这个定时器2做的时刻判断在我们的gd32f4xx.hw.c文件中所以这里需要补充一个定时器2的中断回调void TIMER2_IRQHandler(void) { usb_timer_irq(); }这个写在哪里都行我是写在了这个文件的gd32f4xx.hw.c末尾到这里就移植完成了测试一下没有啥大问题[11:16:41.948]收←◆01 03 00 01 00 01 D5 CA [11:22:23.546]发→◇01 03 00 01 00 01 D5 CA □ [11:22:23.554]收←◆01 03 00 01 00 01 D5 CA [11:22:23.674]发→◇01 03 00 01 00 01 D5 CA □ [11:22:23.676]收←◆01 03 00 01 00 01 D5 CA [11:22:23.809]发→◇01 03 00 01 00 01 D5 CA □ [11:22:23.814]收←◆01 03 00 01 00 01 D5 CA [11:22:23.914]发→◇01 03 00 01 00 01 D5 CA □ [11:22:23.916]收←◆01 03 00 01 00 01 D5 CA6. 结语保持好奇持续学习一起努力。