一、前期准备
1.1 环境搭建
安装 west 和 Zephyr SDK
pip install west
west sdk install
初始化 Zephyr 项目
west init zephyrproject
cd zephyrproject
west update
1.2 获取官方SDK
从GigaDevice官网下载GD32F527 SDK V1.4.0,获取:
- CMSIS头文件
- HAL库源码
- 官方例程参考
二、核心文件修改
2.1 系统时钟配置
文件: modules/hal/gigadevice/gd32f5xx/cmsis/gd/gd32f5xx/source/system_gd32f5xx.c
--- 修改前 ---
#include "gd32f5xx.h" #include "gd32f5xx_rcu.h" #define __SYSTEM_CLOCK_IRC16M (uint32_t)(__IRC16M) #define __SYSTEM_CLOCK_200M_PLL
--- 修改后 ---
#include "gd32f5xx.h" #include "gd32f5xx_rcu.h" /* PLL startup timeout */ #ifndef PLL_STARTUP_TIMEOUT #define PLL_STARTUP_TIMEOUT ((uint16_t)0x0500) #endif /* FMC/FLASH access latency register for GD32F5XX */ #define FMC_ACR (*(volatile uint32_t *)(0x40023C00UL + 0x00UL)) #define FMC_ACR_PRFTEN BIT(1) #define FMC_ACR_LATENCY BITS(0,2) /* select system clock - 200MHz PLL with HXTAL=25MHz */ #define __SYSTEM_CLOCK_200M_PLL
2.2 SOC复位初始化
文件: zephyr/soc/gd/gd32/gd32f5xx/soc.c
--- 在soc_reset_hook函数中实现完整时钟配置 ---
void soc_reset_hook(void)
{
volatile uint32_t *rcu_ctl = (uint32_t *)0x40023800;
volatile uint32_t *rcu_cfg0 = (uint32_t *)0x40023804;
volatile uint32_t *rcu_ahben = (uint32_t *)0x40023830;
volatile uint32_t *fmc_acr = (uint32_t *)0x40023C00;
volatile uint32_t *gpiof_ctl = (uint32_t *)0x40021400;
volatile uint32_t *gpiof_octl = (uint32_t *)0x40021414;
volatile uint32_t *gpiof_bc = (uint32_t *)0x40021428;
/* Enable IRC16M first */
*rcu_ctl |= (1 << 0);
while (!(*rcu_ctl & (1 << 1))) {}
/* Try to enable HXTAL (25MHz crystal) with timeout */
uint32_t timeout = 0;
*rcu_ctl |= (1 << 15);
while (!(*rcu_ctl & (1 << 17)) && timeout < 0xFFFF) {
timeout++;
}
if (*rcu_ctl & (1 << 17)) {
/* HXTAL ready - use 200MHz PLL */
*fmc_acr = (*fmc_acr & ~0x07) | 5; /* 5 wait states for 200MHz */
*rcu_cfg0 &= ~(0x07 << 7); /* AHB = 200MHz */
*rcu_cfg0 |= (4 << 10); /* APB2 = 100MHz */
*rcu_cfg0 |= (4 << 13); /* APB1 = 100MHz */
/* PLL = 25MHz * 16 / 2 = 200MHz */
*(volatile uint32_t *)0x4002382C = (25U << 0) | (0x01U << 16) | (0x10U << 6);
*rcu_ctl |= (1 << 24); /* Enable PLL */
while (!(*rcu_ctl & (1 << 25))) {} /* Wait PLL ready */
*rcu_cfg0 = (*rcu_cfg0 & ~0x03) | 0x02; /* Select PLL as system clock */
while (((*rcu_cfg0 >> 2) & 0x03) != 0x02) {}
} else {
/* HXTAL not ready - use IRC16M (16MHz) */
*fmc_acr = (*fmc_acr & ~0x07) | 0; /* 0 wait states */
*rcu_cfg0 = (*rcu_cfg0 & ~0x03) | 0x00; /* Select IRC16M */
}
/* LED initialization (PF7) */
*rcu_ahben |= 0x20; /* Enable GPIOF clock */
*gpiof_ctl = 0xC000; /* PF7 output mode */
*gpiof_octl |= (1 << 7); /* Push-pull */
*gpiof_bc = (1 << 7); /* LED ON (active low) */
}2.3 串口驱动修复
文件: zephyr/drivers/serial/usart_gd32.c
--- 添加GPIOA时钟使能 ---
#define GPIOA_BASE 0x400200UL
#define RCU_BASE 0x40023800UL
#define RCU_AHBEN (*(volatile uint32_t *)(RCU_BASE + 0x30UL))
#define RCU_AHBEN_GPIOAEN BIT(17) /* GPIOA clock enable bit */
static int usart_gd32_init(const struct device *dev)
{
/* ... */
/* Enable GPIOA clock for USART0 TX/RX pins (PA9/PA10) */
RCU_AHBEN |= RCU_AHBEN_GPIOAEN;
ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
/* ... */
}2.4 PinCtrl配置
文件: zephyr/drivers/pinctrl/pinctrl_gd32_af.c
--- 添加GD32F5XX支持 ---
BUILD_ASSERT((GD32_OSPEED_2MHZ == GPIO_OSPEED_2MHZ) && #if defined(CONFIG_SOC_SERIES_GD32F3X0) || \ defined(CONFIG_SOC_SERIES_GD32A50X) || \ defined(CONFIG_SOC_SERIES_GD32F5XX) || \ // 添加此行 defined(CONFIG_SOC_SERIES_GD32L23X) (GD32_OSPEED_10MHZ == GPIO_OSPEED_10MHZ) && (GD32_OSPEED_50MHZ == GPIO_OSPEED_50MHZ) &&
2.5 配置文件
文件: zephyr/boards/gd/gd32f527_eval/gd32f527_eval_defconfig
CONFIG_NO_OPTIMIZATIONS=y CONFIG_ARM_MPU=n CONFIG_HW_STACK_PROTECTION=n CONFIG_SOC_RESET_HOOK=y CONFIG_SOC_EARLY_INIT_HOOK=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=200000000 CONFIG_GPIO=y CONFIG_GD32_EXTI=y CONFIG_PINCTRL=y CONFIG_SERIAL=y CONFIG_USART_GD32=y CONFIG_UART_CONSOLE=y CONFIG_CONSOLE=y CONFIG_PRINTK=y
2.6 设备树配置
文件: zephyr/boards/gd/gd32f527_eval/gd32f527_eval.dts
/* Enable USART0 for console */
&usart0 {
status = "okay";
current-speed = <115200>;
pinctrl-0 = <&usart0_default>;
pinctrl-1 = <&usart0_sleep>;
pinctrl-names = "default", "sleep";
};文件: zephyr/boards/gd/gd32f527_eval/gd32f527_eval-pinctrl.dtsi
&pinctrl {
usart0_default: usart0_default {
group1 {
pinmux = <USART0_TX_PA9>, <USART0_RX_PA10>;
};
};
usart0_sleep: usart0_sleep {
group1 {
pinmux = <GD32_PINMUX_AF('A', 9, ANALOG)>,
<GD32_PINMUX_AF('A', 10, ANALOG)>;
};
};
};2.7 PinCtrl头文件
文件: modules/hal/gigadevice/include/dt-bindings/pinctrl/gd32f527xx-pinctrl.h
#include "gd32-af.h"
/* USART0 */
#define USART0_TX_PA9 GD32_PINMUX_AF('A', 9, AF7)
#define USART0_RX_PA10 GD32_PINMUX_AF('A', 10, AF7)三、关键问题排查
3.1 常见问题速查表

3.2 GD32F5XX USART寄存器偏移
注意:GD32F5XX与GD32F4XX寄存器偏移不同!

3.3 波特率计算公式
官方GD32公式:
USARTDIV = (APB2CLK + BAUD/2) / BAUD
BAUD寄存器 = (USARTDIV & 0xFFF0) | (USARTDIV & 0xF)
常用配置:
- 16MHz IRC16M + 115200波特率 = 0x8B
- 100MHz APB2 + 115200波特率 = 0x364
四、测试代码
文件: zephyr/samples/hello_world/src/main.c
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/printk.h>
#define LED0_NODE DT_ALIAS(led0)
static const struct gpio_dt_spec led_spec = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
int main(void)
{
gpio_pin_configure_dt(&led_spec, GPIO_OUTPUT_ACTIVE);
printk("=== GD32F527 Zephyr Test ===\r\n");
printk("UART working!\r\n");
while (1) {
gpio_pin_set_dt(&led_spec, 0);
printk("LED ON\r\n");
k_msleep(500);
gpio_pin_set_dt(&led_spec, 1);
printk("LED OFF\r\n");
k_msleep(500);
}
}六、总结
移植GD32F527到Zephyr的关键点:
1. 时钟配置
- PLL 200MHz需要Flash等待状态配置
- HXTAL晶振超时回退到IRC16M
2. GPIO时钟
- USART使用GPIOA,需要单独使能时钟
- 关键: RCU_AHBEN |= BIT(17)
3. Pinctrl
- 正确配置PA9/PA10为AF7模式
- 添加GD32F5XX到BUILD_ASSERT检查
4. 控制台配置
- 启用 CONFIG_UART_CONSOLE=y
- 启用 CONFIG_PRINTK=y
5. 容错处理
- HXTAL超时时自动回退到IRC16M
【日志打印效果】

我要赚赏金
