打印
[技术问答]

F460 Keil AC6 开发编译环境下如何将变量定义在指定RAM地址

[复制链接]
377|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 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. 注意事项
  • 地址有效性:确保目标地址在芯片 RAM 范围内。
  • 对齐要求:地址需满足变量对齐(如 32 位变量需 4 字节对齐)。
  • 大小检查:自定义区域长度必须 ≥ 变量总大小。
  • 多文件管理:同一自定义段可跨文件收集变量。
  • 默认 RAM:.ANY (+RW +ZI) 需排除自定义段变量。

三、小结
[size=16.002px]通过以上步骤,即可精确控制变量在 RAM 中的物理地址。此方法适用于外设寄存器映射、特殊内存区域访问等场景。



使用特权

评论回复
沙发
wyde518| | 2025-7-4 15:08 | 只看该作者
最近正在学习460,先收藏了 ,谢谢

使用特权

评论回复
板凳
wubangmi| | 2025-7-4 17:12 | 只看该作者
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)/*!< ARM Compiler AC6 */

uint32_t u32wktmCnt   __attribute__((section(".ARM.__at_0x20000000")));

#elif  defined (__CC_ARM)                                    /*!< ARM Compiler AC5 */

uint32_t u32wktmCnt   __attribute__((at(0x20000000)))=0;
      
#endif

KEIL这么写可以了,不涉及到修改分散加载文件,IAR也比较简单, GCC弄起来应该麻烦一点

使用特权

评论回复
地板
zjsx8192| | 2025-7-5 10:37 | 只看该作者
可以在sct文件里面指定吧

使用特权

评论回复
5
ShimmeringDawn| | 2025-7-5 17:40 | 只看该作者
在.sct里面改是常规操作!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

239

帖子

12

粉丝