拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

GD32 USB 虚拟串口移植

GD32 USB 虚拟串口移植

1. 引言

在嵌入式开发中,USB 通信是设备与上位机交互的重要方式。GD32 系列 MCU 自带 USB 外设,通过移植 USBD(USB Device)库并配置 CDC(Communication Device Class)类,可以快速实现虚拟串口功能,让设备通过 USB 线直接与 PC 进行串口通信,无需额外硬件。

本文将以 GD32F4xx 系列为例,详细介绍如何从零开始移植 USBD 库并实现 CDC 移植完整流程。

2. 准备工作

首先准备一个空白能跑的工程文件,本文基于已经移植好的freertos工程进行展示,需要移植freertos的可以看我前两期内容。

硬件

兆易创新GigaDevice-资料下载兆易创新GD32 MCUhttps://www.gd32mcu.com/cn/download?kw=GD32F4&lan=cn官方网上是有给这里例程的,我们从上面抄袭一下。

应该是这个样子,我们找到我们需要的库函数,参考目录:

GD32F4xx_Demo_Suites_V3.3.3\GD32F4xx_Demo_Suites_V3.3.3\GD32F4xx_Demo_Suites_V3.3.3\GD32450V_START_Demo_Suites\GD32F4xx_Firmware_Library

3. 文件裁剪

首先这个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 CA

6. 结语

保持好奇,持续学习,一起努力。

返回列表