本帖最后由 yang377156216 于 2025-7-4 13:57 编辑
一、需求背景
用的是小华的 HC32F460 ,开发环境是 Keil 编译器用的 AC6,希望指定个变量将 RAMH 到 RAM1的跨界区 0x1FFFFFFC - 0x20000003 这8个字节给占用掉,避免临界区对齐访问问题的发生。
二、实现步骤[size=16.002px]在 Keil MDK 环境下使用 AC6 编译器,可以通过修改分散加载文件(.sct)将变量定位到指定的 RAM 地址。以下是详细步骤:
1. 准备代码(定义变量并指定段名)[size=16.002px]在 C 代码中使用 __attribute__ 将变量分配到自定义段: // 定义变量并指定段名
__attribute__((section("CustomSection1"))) uint32_t ram_placeholder[2];
2. 修改 .sct 文件[size=16.002px]在项目选项中取消勾选 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. 验证结果[size=16.002px]编译后查看生成的 .map 文件: [size=16.002px]
5. 注意事项三、小结
[size=16.002px]通过以上步骤,即可精确控制变量在 RAM 中的物理地址。此方法适用于外设寄存器映射、特殊内存区域访问等场景。
|