在基于 G32R501 开发高性能、高实时性项目时,Keil 分散加载脚本(.sct) 是决定代码存放、运行速度、内存安全性的关键文件。AN1130 应用笔记完整讲解 G32R501 内存结构、官方链接脚本选型、MDK 配置方法、自定义编写规则,覆盖单核 / 双核、Flash/ITCM/DTCM/SRAM 全场景,照着做就能稳定分配内存、提升执行效率。
资料获取:AN1130_G32R501 Keil 链接文件应用笔记
1. G32R501 内存结构总览(必须先看懂)
G32R501 分为单核、双核两个版本,内存区域包含:ITCM、DTCM、SRAM1/2/3、Flash,用途与速度差异极大。
1.1 单核内存分配
| 内存区域 | 基地址 | 大小 | 用途 |
|---|---|---|---|
| ITCM RAM | 0x00000000 | 64KB | 高速指令 |
| DTCM RAM | 0x20000000 | 16KB | 高速数据 |
| Flash | 0x08000000 | 640KB | 程序存储 |
| SRAM1 | 0x20100000 | 8KB | 通用数据 |
| SRAM2 | 0x20200000 | 8KB | 通用数据 |
| SRAM3 | 0x20300000 | 32KB | 通用数据 / DMA |
1.2 双核内存分配(CPU0 + CPU1)
| 内存区域 | 基地址 | 大小 | 归属 |
|---|---|---|---|
| ITCM CPU0 | 0x00000000 | 48KB | CPU0 |
| ITCM CPU1 | 0x00000000 | 8KB | CPU1 |
| DTCM CPU0 | 0x20000000 | 16KB | CPU0 |
| DTCM CPU1 | 0x20000000 | 8KB | CPU1 |
| Flash | 0x08000000 | 640KB | 共享 |
| SRAM1/2/3 | 0x2010000~ | 8+8+32KB | 共享 |
2. 官方 .sct 脚本怎么选?(直接对应场景)
SDK 自带多套脚本,路径:g32r5xx_SDK\device_support\DEVICE_GPN\common\sct
常用脚本速查
| 脚本名称 | 说明 | 适用场景 |
|---|---|---|
g32r501xy_cbus_flash.sct |
代码放 Flash(默认) | 单核通用 |
g32r501xy_itcm_flash.sct |
代码映射到 ITCM | 高性能运行 |
g32r501xy_itcm_ram.sct |
代码在 ITCM RAM | 极致实时 |
g32r501dxy_cpu0_cbus_flash.sct |
双核 CPU0 | 双核项目 |
g32r501dxy_cpu1_cbus_flash.sct |
双核 CPU1 | 双核项目 |
3. MDK 中使用 .sct 链接脚本(一步不踩坑)
- 打开工程 → 魔法棒 Options for Target
- 进入 Linker 选项卡
- 取消
Use Memory Layout from Target Dialog - 点击
...选择对应的.sct文件 - 可点击
Edit直接修改脚本 - 确定 → 重新编译生效
可视化配置(Configuration Wizard)
支持图形化修改:
- SRAM1/SRAM2/SRAM3 启用 / 大小配置
- Stack / Heap 大小与位置(默认 DTCM)
- 代码执行区域:Flash / ITCM / SRAM
注意:
- DMA 数据不能放在 DTCM,必须放 SRAM1/2/3
- 双核项目两个核心 Flash 区域不能重叠
4. Scatter 文件语法(看懂就能自己写)
基本结构
LOAD_ROM 加载地址 大小
{
EXEC_ROM 运行地址 大小
{
*.o(RESET, +First)
.ANY(+RO)
}
RW_RAM RAM地址 大小
{
.ANY(+RW +ZI)
}
}
段属性说明
- RO:代码 + 只读数据(放 Flash)
- RW:已初始化变量(放 RAM)
- ZI:未初始化变量(放 RAM)
- FIRST:放在段最前面(如中断向量)
5. 最常用实战用法(直接复制)
5.1 指定变量放到 DTCM
.sct 添加:
RW_RAM_DTCM 0x20000000 0x4000
{
.ANY(dtcm.data)
.ANY(+RW +ZI)
}
C 代码:
__attribute__((section("dtcm.data"))) uint32_t Variable;
5.2 指定函数放到 ITCM
__attribute__((section("itcm.ramfunc"))) void FastFunc(void);
5.3 指定变量绝对地址
__attribute__((section(".ARM.__at_0x20300000"))) const uint8_t data[];
5.4 双核 Flash 分区修改
#define __CPU0_CBUS_FLASH_BASE 0x08000000
#define __CPU0_CBUS_FLASH_SIZE 0x00060000 // 384KB
#define __CPU1_CBUS_FLASH_BASE 0x08060000
#define __CPU1_CBUS_FLASH_SIZE 0x00040000 // 256KB
6. 常见问题与避坑
- 死机 / 不运行:中断向量放对位置?ITCM / Flash 地址是否正确?
- DMA 异常:DMA 缓冲必须放在 SRAM,不能放在 DTCM
- 双核冲突:CPU0 / CPU1 的 Flash、RAM 区域不能重叠
- 栈溢出:Stack 设置太小,建议 ≥ 0x1000
- 速度上不去:关键函数和中断处理放到 ITCM
AN1130 是 G32R501 最权威的 Keil 链接脚本开发手册,覆盖:
- 单核 / 双核内存结构
- 官方脚本快速选型
- MDK 图形化配置
- Scatter 语法与自定义
- 高速代码 / 数据存放实战
无论做电机控制、高频采集、双核调度,都能通过 .sct 脚本实现内存最优分配、速度最大化、系统稳定可靠。
阅读全文
394