本帖最后由 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];
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 data 1FFF8008 0002EFF8
- .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 中的物理地址。此方法适用于外设寄存器映射、特殊内存区域访问等场景。
|