STM32F427将函数设定在固定位置

STM32F427 基于 Cortex-M4F、GD32/STM32 通用,编译器(Keil MDK、GCC/STM32CubeIDE、IAR)都支持通过「编译器段属性 + 链接脚本」两步把函数放到固定地址。核心思路是:__attribute__((section(...))) 只负责把函数放进自定义段,真正决定地址的是链接脚本里对该段的定位。

方法一:Keil MDK(最常用于 STM32F4)

Keil 用分散加载文件 .sct 控制内存布局。

第 1 步:在 .sct 文件中新增 Flash 段

复制代码
LR_IROM1 0x08000000 0x00100000 {      ; 加载域,地址按你的工程实际Flash起点/大小调整
  ; ...其他默认段...
  ER_MYFUNC 0x08060000 0x2000 {     ; 执行域:函数固定到 0x08060000
    *(.my_func)                     ; 收集所有标记为 .my_func 的代码
  }
  ; ...其余段...
}

【也可用 FIXED 属性】

复制代码
ER_MYFUNC 0x08060000 FIXED { *(.my_func) }

第 2 步:在 C 代码中用段属性标记函数

复制代码
#define MY_FLASH __attribute__((section("my_func")))
MY_FLASH void test_function(void) {
    return 1;
}

编译后在 map 文件中即可确认 test_function 是否定位到 0x08060000。

方法二:GCC / STM32CubeIDE

GCC 同样用 __attribute__((section)) 标记,然后在 .ld 链接脚本中指定段地址。

C 代码标记:

复制代码
void my_function(void) __attribute__((section(".my_func")));
void my_function(void) { /* 函数体 */ }

链接脚本(.ld)中定位:

复制代码
SECTIONS {
  ...
  .my_section 0x10000000 : {
    *(.my_section)   /* 所有标记 .my_section 的部分 */
  }
}

也可以使用 ARM 编译器提供的「__at 段」,直接以地址命名:

复制代码
void Communication_Test(u8 *in, u8 *out, u8 len)
    __attribute__((section(".ARM.__at_0x00031000")));

其中 .ARM.__at_<address> 的地址即该函数被放置的位置。

方法三:IAR

IAR 用 #pragma location 指定地址,例如:

复制代码
#pragma location = 0x00031000
void my_func(void);

关键注意事项

  1. 段属性≠地址 :__attribute__((section)) 只决定函数进入哪个段,最终地址必须由链接脚本分配,二者缺一不可。

  2. 防止被优化丢弃 :若函数未被调用,链接器可能剔除它。GCC 下用 __attribute__((used)) 或链接脚本中的 KEEP(...) 保留,例如 KEEP((*(.boot.init)));Keil 下也建议用 __attribute__((used))。

  3. 地址对齐 :Flash 段建议使用 ALIGN(4),因为 Cortex-M 指令(尤其 Thumb-2)要求按半字/字对齐,函数地址通常需 4 字节对齐。

    .my_func 0x08060000 : ALIGN(4) { *(.my_func) }

  4. 多函数顺序:同一段内多个函数按声明顺序存放(GCC/IDE 下),可据此安排相对位置。

  5. 验证 :编译后务必打开 map 文件或使用反汇编、nm 工具,确认目标函数确实位于期望地址,这是最可靠的检查方式。

  6. 未使用函数保留 :若函数不在调用链中且开 -ffunction-sections,链接时可能被 section GC 移除,需配合 KEEP/used 处理。

相关推荐
智购科技无人售货机厂家7 小时前
压缩机一启动设备就重启,排查发现是电源功率选小了~YH
单片机·嵌入式硬件
黑马水牛9 小时前
RK3588系列:01-系统烧录与开发环境搭建
arm开发·嵌入式硬件
铅笔小新z9 小时前
【stm32】IWDG(独立看门狗)
stm32·单片机·嵌入式硬件
无敌贵点大王10 小时前
从寄存器层面重学STM32(2)——RCC和时钟树
stm32·单片机·嵌入式硬件
玄芯散人11 小时前
【元婴·103】GPIO深度:复用、上下拉、翻转速度
单片机·嵌入式硬件
xiangw@GZ13 小时前
四线开尔文(Kelvin)测量原理
单片机·嵌入式硬件
优信电子13 小时前
HC05蓝牙模块主机与从机进行连接通信
单片机·物联网·嵌入式
深圳老胡14 小时前
STM32CubeMX 2 与 STM32CubeMX 的主要区别
笔记·stm32·单片机·代码规范
BSD_CGQ14 小时前
FSR 压力传感器 I2C 接口实战:地址规划与 MCU 软件滤波的工程取舍
嵌入式硬件·机器人·压力传感器·柔性薄膜压力传感器
゛凌乱的记忆づ15 小时前
50元从零到成品:一套AI辅助的嵌入式实战入门教程——IIC篇
人工智能·stm32·单片机·嵌入式硬件