F460 Keil AC6 开发编译环境下如何将变量定义在指定RAM地址
本帖最后由 yang377156216 于 2025-7-4 13:57 编辑一、需求背景
用的是小华的 HC32F460 ,开发环境是 Keil 编译器用的 AC6,希望指定个变量将 RAMH 到 RAM1的跨界区 0x1FFFFFFC - 0x20000003 这8个字节给占用掉,避免临界区对齐访问问题的发生。
二、实现步骤在 Keil MDK 环境下使用 AC6 编译器,可以通过修改分散加载文件(.sct)将变量定位到指定的 RAM 地址。以下是详细步骤:
1. 准备代码(定义变量并指定段名)在 C 代码中使用 __attribute__ 将变量分配到自定义段:// 定义变量并指定段名
__attribute__((section("CustomSection1"))) uint32_t ram_placeholder;2. 修改 .sct 文件在项目选项中取消勾选 Use Memory Layout from Target Dialog,然后编辑分散加载文件:; ****************************************************************
; Scatter-Loading Description File
; ****************************************************************
LR_IROM1 0x00000000 0x00080000{ ; load region size_region
ER_IROM1 0x00000000 0x00080000{; load address = execution address
*.o (RESET, +First)
*(InRoot$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x1FFF8000 UNINIT 0x00000008{; RW data
*(.bss.noinit)
}
RW_IRAM2 0x20000008 0x00026FF0{; RW data1FFF80080002EFF8
.ANY (+RW +ZI)
.ANY (RAMCODE)
}
RW_IRAMH 0x1FFF8008 0x00007FF0{; RW data
.ANY (+RW +ZI)
}
RW_IRAMB 0x200F0000 0x00001000{; RW data
.ANY (+RW +ZI)
}
; 以上都是默认 RAM 区域,自定义 RAM 区域 1 (地址 0x1FFFFFFC)
Custom_RAM1 0x1FFFFFFC 0x00000008 { ; 起始地址 0x1FFFFFFC,长度 8bytes
* (CustomSection1) ; 放置 ram_placeholder
}
}3. 关键配置说明
[*]段名匹配:* (CustomSection1) 收集所有分配到 CustomSection1 的变量。
[*]地址分配:直接指定目标地址(如 0x1FFFFFFC)。
[*]内存隔离:确保自定义区域与默认 RAM 区域无重叠。
[*]长度设置:区域大小需 ≥ 变量实际大小。
4. 验证结果编译后查看生成的 .map 文件:5. 注意事项
[*]地址有效性:确保目标地址在芯片 RAM 范围内。
[*]对齐要求:地址需满足变量对齐(如 32 位变量需 4 字节对齐)。
[*]大小检查:自定义区域长度必须 ≥ 变量总大小。
[*]多文件管理:同一自定义段可跨文件收集变量。
[*]默认 RAM:.ANY (+RW +ZI) 需排除自定义段变量。
三、小结
通过以上步骤,即可精确控制变量在 RAM 中的物理地址。此方法适用于外设寄存器映射、特殊内存区域访问等场景。
最近正在学习460,先收藏了 ,谢谢 #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)/*!< ARM Compiler AC6 */
uint32_t u32wktmCnt __attribute__((section(".ARM.__at_0x20000000")));
#elifdefined (__CC_ARM) /*!< ARM Compiler AC5 */
uint32_t u32wktmCnt __attribute__((at(0x20000000)))=0;
#endif
KEIL这么写可以了,不涉及到修改分散加载文件,IAR也比较简单, GCC弄起来应该麻烦一点 可以在sct文件里面指定吧 在.sct里面改是常规操作!
页:
[1]