一,开发环境搭建中遇到的问题
1.代码补全
GD32EmbeddedBuilder是基于eclipse开发的,与STM32CubeIDE相同,所以我参考了一个cubeIDE代码补全的教程:https://zhuanlan.zhihu.com/p/621198855
首先,打开程序Window菜单下Preferences选项,在 C/C++ --> Editor --> Content Assist --> Advanced 设置里勾选上下两部分的 Parsing-based Proposals

然后,我们需要设置相应的快捷键。在 General --> Keys 下面搜索content assist, 设置C/C++ Content Assist (Parsing-based Proposals)的Binding快捷键为你所想设置的,在这里笔者设置成了Ctrl+Space(空格),When 设置成 C/C++ Editor。

完成之后我们可以测试一下:输入gd32 GPIO操作函数gpio_bit 然后同时按下Ctrl和空格键,便会弹出自动补全的选项

2. 使用jlink烧录程序
根据网上所说,需要JLinkv10及以上版本才可以烧录程序,而我手头上的JLinkv9并没有引出JTAG引脚,所以无法进行验证,我使用的是J-Link OB RA4M2调试器,支持risk-v内核调试,我的是在闲鱼上购买的,当然也可以自己制作,嘉立创开源平台上也有开源的电路板与固件。
后记:发现芯片支持两线cJTAG引脚烧录,与arm swd引脚相同于是使用jflash软件进行了测试,发现jlinkv9并不支持此接口,遂作罢,同时发现jlinkob ra4m2可以使用cJTAG引脚成功连接芯片;


V2版本的开发板已经将所有JTAG引脚到排针上引出,并在原理图上进行了标注,非常便于我们开发

在run configuration中可以将调试器改为jlink,即可扫描到对应的芯片id 0x10307A6D,根据AI所说应该是芯片内部调试接口(TAP Controller)的 IDCODE。;


同时我也进行了深入探究,使用JLink命令行工具连接芯片,发现AI所说并不正确,ide中扫描到的ID是来自芯来科技(Nuclei)的 N307 内核ID,而第二个是用户手册提到的GD32的JTAG id


而AI所说的IDCODE寄存器读出来的是另一个值

在开发过程中,我发现IDE对JLink的兼容性并不是很好。最初我使用的是iCEasy商城资料中提供的IDE软件,但在尝试使用JLink进行烧录时,系统提示未找到目标地址,导致烧录失败。随后,我从GD32官网下载了最新版本的IDE,新建的工程能够正常烧录。不过,在后续测试Wi-Fi功能时,当我导入SDK中的例程工程,再次遇到了无法烧录的问题,具体情况如下图所示。

二,使用WIFI SDK进行WIFI连接测试
1.例程导入
在开发Wi-Fi功能时,由于从头新建网络程序需要手动导入大量库文件,较为繁琐,因此我选择直接导入官方SDK中的例程进行修改。同时,为了保留原始例程不被破坏,我采用了一个取巧的方法:将所需例程复制到与原始例程同一级目录下(即我新建的工程文件夹所在位置),这样工程中引用的相对路径不会失效,复制后的例程可以直接编译和使用。
如下图所示,原始例程分别存放在各个文件夹的下一级目录中,而我将它们复制出来后,放置在与这些例程同级的自定义文件夹内,从而在保留原例程结构的同时,可以自由修改并确保路径引用正确。

2.程序编写
#include <stdint.h>
#include <stdio.h>
#include "app_cfg.h"
#include "gd32vw55x_platform.h"
#include "wifi_management.h"
#include "wifi_init.h"
#include "FreeRTOS.h"
#include "task.h"
#define SSID "your ssid"
#define PASSWORD "your password"
TaskHandle_t task1_handle;
TaskHandle_t task2_handle;
TaskHandle_t wifi_task_handle;
static void wifi_task(void *param)
{
int status = 0;
char *ssid = SSID;
char *password = PASSWORD;
struct mac_scan_result candidate;
if (ssid == NULL) {
printf("ssid can not be NULL!\r\n");
goto exit;
}
/*
* 1. Start Wi-Fi scan
*/
printf("Start Wi-Fi scan.\r\n");
status = wifi_management_scan(1, ssid); //使用阻塞模式扫描是否存在ssid对应的wifi
if (status != 0) {
printf("Wi-Fi scan failed.\r\n");
goto exit;
}
sys_memset(&candidate, 0, sizeof(struct mac_scan_result));
/*在已完成的扫描结果中查找与指定 ssid 匹配的 AP(接入点)。
* 这里 bssid 为 NULL,
* 因此仅根据 SSID 进行匹配。找到后将 AP 的详细信息(如 BSSID、信道、信号强度等)填充到 candidate 结构体中。*/
status = wifi_netlink_candidate_ap_find(WIFI_VIF_INDEX_DEFAULT, NULL, ssid, &candidate);
if (status != 0) {
goto exit;
}
/*
* 2. Start Wi-Fi connection
*/
printf("Start Wi-Fi connection.\r\n");
if (wifi_management_connect(ssid, password, 1) != 0) {
printf("Wi-Fi connection failed\r\n");
goto exit;
}
exit:
printf("The test has ended.\r\n");
vTaskDelete(wifi_task_handle);
}
void task1(void* pvParameters)
{
uint16_t num_task1 = 0;
while(1)
{
printf("task1 running%d\r\n",num_task1++);
vTaskDelay(pdMS_TO_TICKS(500));
}
}
void task2(void* pvParameters)
{
uint16_t num_task2 = 0;
while(1)
{
printf("task2 running%d\r\n",num_task2++);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
int main(void)
{
platform_init();
uart_config(UART1, 115200, false, false, false);
uart_put_data(UART1, (uint8_t*)"Hello\r\n", 7);
printf("hello world\r\n");
if (wifi_init()) {
printf("wifi init failed.\r\n");
}
xTaskCreate(wifi_task,"wifi_task",2048,NULL,5,&wifi_task_handle);
xTaskCreate(task1,"task1",1024,NULL,2,&task1_handle);
xTaskCreate(task2,"task2",1024,NULL,2,&task2_handle);
sys_os_start();
for ( ; ; );
}
3.现象描述


可以发现已经成功连接到了WIFI网络,并且freertos的两个测试任务也在正常运行
4.遇到的串口问题说明
在开发过程中,我遇到了串口输出的问题。默认情况下,printf 函数的内容并不会被重定向到开发板的串口,因此需要手动修改相关代码才能输出调试信息。所幸,重定向的工作已经在 log_uart.c 文件中完成。借此机会,我也了解到了不同编译器下的实现差异:在 ARM Keil(即 ARMCC 编译器)中,需要重写 fputc 函数;而在 RISC‑V 的 GNU 编译链中,则是通过实现 _write 函数来完成重定向。以下是 log_uart.c 中对应的实现代码:
#elif defined(__GNUC__)
int _write(int fd, char *str, int len)
{
(void)fd;
int32_t i = 0;
/* Send string and return the number of characters written */
while (i != len) {
while (RESET == usart_flag_get(LOG_UART, USART_FLAG_TBE));
usart_data_transmit(LOG_UART, *str);
str++;
i++;
}
while (RESET == usart_flag_get(LOG_UART, USART_FLAG_TC));
return i;
}
要正常使用串口输出,我们需要在 uart_config.h 文件中正确配置 LOG_UART 的宏定义。例如,我的开发板上使用的是 UART1,因此需要将 LOG_UART 定义为 USART1。此外,我还遇到一个问题:串口始终没有输出信息。当时我修改了 uart.h 中关于串口引脚及引脚复用的定义,但不确定默认的配置是否与开发板匹配。因此,在使用前建议检查这两个文件中的相关设置,确保引脚分配和复用功能正确无误。

开源社区 


