这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【gd32f527移植Zephyr】实现一键配EXMCSDRAM

共3条 1/1 1 跳转至

【gd32f527移植Zephyr】实现一键配EXMCSDRAM

高工
2026-02-23 13:46:09     打赏
# GD32 EXMC SDRAM 在 Zephyr RTOS 上的移植与实践
## 摘要
本文详细介绍了将GD32F527微控制器的EXMC SDRAM控制器驱动移植到Zephyr RTOS的过程。通过利用Zephyr的MEMC子系统,我们实现了SDRAM的自动初始化,用户只需在配置文件中启用两个选项即可直接使用外部SDRAM,大大简化了开发流程。
一、引言GD32F527是兆易创新推出的高性能ARM Cortex-M33内核MCU,主频达200MHz,内置强大的外部存储控制器(EXMC),支持SDRAM、NAND Flash等外部存储器的扩展。在嵌入式图形显示应用中,SDRAM作为LCD帧缓冲区可以支持更高分辨率的显示。Zephyr RTOS是一款面向物联网的实时操作系统,提供了丰富的驱动框架和设备模型。其MEMC子系统为外部存储控制器提供了统一的接口支持。本文的目标是将GD32的EXMC SDRAM驱动集成到Zephyr的MEMC子系统中,实现一键配置SDRAM。 二、硬件平台与开发环境2.1 硬件平台MCU: GD32F527VCT6 (ARM Cortex-M33, 200MHz)开发板: GD32F527I-EVALSDRAM: IS42S16400J (8MB, 16位数据宽度)LCD: 480x272 RGB TFT显示屏
2.2 软件环境
-RTOS: Zephyr Project v4.3.0编译工具: ARM GCC调试工具: J-Link + Ozone
 2.3 SDRAM硬件连接

SDRAM连接到EXMC Bank0,基地址为0xC0000000:

image.png


 三、Zephyr MEMC子系统概述
Zephyr的MEMC(Memory Controller)子系统为外部存储控制器提供了标准化的设备模型。开发者只需:
1. 在设备树中配置SDRAM参数2. 在Kconfig中启用MEMC驱动3. 在代码中直接使用SDRAM地址
系统启动时会自动初始化SDRAM,无需手动编写初始化代码。
四、移植过程
4.1 设备树配置
首先需要在设备树中添加SDRAM节点配置:
&exmc {
    status = "okay";
    gd_sdram: sdram {
        compatible = "gd,gd32-exmc-sdram";
        status = "okay";
        gd_sdram_device = <0>;
        gd_sdram_column_bits = <9>;
        gd_sdram_row_bits = <13>;
        gd_sdram_data_width = <16>;
        gd_sdram_bank_count = <4>;
        gd_sdram_cas_latency = <3>;
        gd_sdram_sdclock = <2>;
        gd_sdram_tmr_rcd = <2>;
        gd_sdram_tmr_rp = <2>;
        gd_sdram_tmr_ras = <6>;
        gd_sdram_tmr_rc = <5>;
        gd_sdram_tmr_rd = <2>;
        gd_sdram_tmr_xsr = <7>;
        gd_sdram_tmr_wp = <2>;
        gd_sdram_refresh_rate = <761>;
        gd_sdram_mode_reg = <0x230>;
    };
};

4.2 设备树绑定
创建设备树绑定文件 `dts/bindings/memc/gd,gd32-exmc-sdram.yaml`:
description: GD32 EXMC SDRAM Controller
compatible: "gd,gd32-exmc-sdram"
include: base.yaml
properties:
  gd_sdram_device:
    type: int
    required: true
  gd_sdram_column_bits:
    type: int
    required: true
  gd_sdram_row_bits:
    type: int
    required: true
  gd_sdram_data_width:
    type: int
    required: true
  # ... 其他参数
4.3 MEMC驱动实现
驱动核心代码位于 `drivers/memc/memc_gd32_sdram.c`
static int memc_gd32_sdram_init(const struct device *dev)
{
    // 设置SystemCoreClock用于延时计算
    SystemCoreClock = 200000000;
    // 启用EXMC和GPIO时钟
    rcu_periph_clock_enable(RCU_EXMC);
    rcu_periph_clock_enable(RCU_GPIOC);
    // ... 其他GPIO时钟
    // 配置SDRAM引脚
    gpio_af_set(GPIOC, GPIO_AF_12, GPIO_PIN_2 | GPIO_PIN_5);
    gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_PULLUP, ...);
    // ... 其他引脚配置
    // 配置SDRAM时序
    timing.row_to_column_delay = config->timing_rcd;
    timing.row_precharge_delay = config->timing_rp;
    timing.write_recovery_delay = config->timing_trd;
    timing.auto_refresh_delay = config->timing_ras;
    timing.row_address_select_delay = config->timing_rc;
    timing.exit_selfrefresh_delay = config->timing_xsr;
    timing.load_mode_register_delay = config->timing_tmr;
    // 配置SDRAM控制参数
    sdram_config.sdram_device = EXMC_SDRAM_DEVICE0;
    sdram_config.pipeline_read_delay = EXMC_PIPELINE_DELAY_1_HCLK;
    sdram_config.burst_read_switch = ENABLE;
    sdram_config.sdclock_config = EXMC_SDCLK_PERIODS_2_HCLK;
    sdram_config.cas_latency = EXMC_CAS_LATENCY_3_SDCLK;
    // ...
    // 初始化SDRAM
    exmc_sdram_init(&sdram_config);
    // 发送初始化序列命令
    cmd.command = EXMC_SDRAM_CLOCK_ENABLE;
    exmc_sdram_command_config(&cmd);
    cmd.command = EXMC_SDRAM_PRECHARGE_ALL;
    exmc_sdram_command_config(&cmd);
    cmd.command = EXMC_SDRAM_AUTO_REFRESH;
    cmd.auto_refresh_number = 8;
    exmc_sdram_command_config(&cmd);
    cmd.command = EXMC_SDRAM_LOAD_MODE_REGISTER;
    cmd.mode_register_content = config->mode_reg;
    exmc_sdram_command_config(&cmd);
    // 设置刷新率
    exmc_sdram_refresh_count_set(config->refresh_rate);
    return 0;
}
4.4 Kconfig配置
在驱动Kconfig中添加配置选项:
config MEMC_GD32_EXMC
    bool "GD32 EXMC SDRAM support"
    depends on MEMC && GPIO
    help
      Enable support for GD32 EXMC SDRAM controller

4.5 用户配置
用户只需在项目的 `prj.conf` 中添加:
# 启用MEMC子系统
CONFIG_MEMC=y
# 启用GD32 EXMC SDRAM驱动
CONFIG_MEMC_GD32_EXMC=y

 五、关键注意事项
 5.1 HAL库位域配置

GD32 HAL库的EXMC SDRAM配置使用位域结构,必须使用官方定义的宏,不能使用原始数值:

参数错误写法正确写法
sdclock_config2EXMC_SDCLK_PERIODS_2_HCLK
 sdram_device4EXMC_SDRAM_DEVICE0
 column_address_width9EXMC_SDRAM_COW_ADDRESS_9
row_address_width13EXMC_SDRAM_ROW_ADDRESS_13
data_width1EXMC_SDRAM_DATABUS_WIDTH_16B
cas_latency3EXMC_CAS_LATENCY_3_SDCLK
bank_select
0EXMC_SDRAM_DEVICE0_SELECT
直接使用数值会导致位字段错位,SDRAM无法正常工作。
 5.2 SystemCoreClock配置
EXMC初始化需要正确的SystemCoreClock值用于时序计算。在驱动初始化时需要强制设置为200MHz:
extern uint32_t SystemCoreClock;
SystemCoreClock = 200000000;
 5.3 MPU和Cache配置
访问外部SDRAM时需要禁用MPU和Data Cache:
CONFIG_MPU=n
CONFIG_DCACHE=n
六、使用示例
6.1 SDRAM测试
#include <zephyr/kernel.h>
#define SDRAM_BASE 0xC0000000U
int main(void)
{
    volatile uint16_t *sdram = (volatile uint16_t *)SDRAM_BASE;
    // 写入测试
    sdram[0] = 0x55AA;
    // 读取验证
    if (sdram[0] == 0x55AA) {
        printk("SDRAM test PASSED!\n");
    } else {
        printk("SDRAM test FAILED!\n");
    }
    return 0;
}
6.2 LCD帧缓冲应用
配置LCD使用SDRAM作为帧缓冲区:
// LCD帧缓冲地址
#define FRAMEBUFFER_ADDR 0xC0000000U
// 填充屏幕
void fill_screen(uint16_t color)
{
    volatile uint16_t *fb = (volatile uint16_t *)FRAMEBUFFER_ADDR;
    for (int i = 0; i < 480 * 272; i++) {
        fb[i] = color;
    }
}

 七、测试结果
通过MEMC驱动的自动初始化,SDRAM测试全部通过:
*** Booting Zephyr OS build v4.3.0-6235-g8a139a091dd0 ***
[memc_gd32_sdram] GD32 EXMC SDRAM initialized at 0xC0000000 - TEST OK
--- Test 1: Basic 16-bit write/read ---
PASS: 0x55AA written and read back
--- Test 2: Multiple address test ---
PASS: All 10 addresses OK
--- Test 3: 32-bit write/read ---
PASS: 0xDEADBEEF written and read back
--- Test 4: Fill patterns ---
PASS
--- Test 5: March test ---
PASS
RESULT: SDRAM TEST PASSED!
LCD显示也正常工作,可以显示480x272分辨率的全屏图像。
八、总结
本文详细介绍了GD32 EXMC SDRAM在Zephyr RTOS上的移植过程。通过以下改进实现了"一键配置":
集成到MEMC子系统:利用Zephyr的设备模型,实现自动初始化使用GD32固件库:直接调用HAL函数,确保兼容性完善位域配置:全部使用官方宏定义,避免配置错误
用户现在只需在配置文件中启用两个选项即可使用SDRAM,无需编写任何初始化代码:
CONFIG_MEMC=y
CONFIG_MEMC_GD32_EXMC=y
这种方法具有良好的可移植性,可以方便地推广到其他GD32F5系列MCU。
参考资料
1. Zephyr Project Documentation - MEMC Subsystem2. GD32F5xx Firmware Library3. GD32F527 User Manual4. IS42S16400J SDRAM Datasheet

实现效果:

image.png





关键词: gd32f527     Zephyr     SDRAM    

专家
2026-02-24 08:49:17     打赏
2楼

谢谢分享


院士
2026-02-28 16:03:18     打赏
3楼

高级,真是高级呀!


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]