C语言Flash中const配置变量无Flash驱动修改方法咨询
无需Flash驱动修改Flash配置段的实现方案
1. 修改ARM链接脚本,添加Flash配置段
在现有链接脚本中,新增专门的Load Region和Execution Region,用于存储复位向量地址。建议选择Flash中未被现有代码占用的空闲区域(比如现有ER_RO_APPLICATION段结束后的位置),示例修改如下:
; 新增:Bootloader配置段,存储应用复位向量地址(32位,4字节) LR_BOOT_CFG 0x0801E800 NOCOMPRESS ALIGN 4 0x4 ; 地址对应ER_RO_APPLICATION结束位置(0x08002000 + 0x1C800 = 0x0801E800) { ER_BOOT_CFG +0 FIXED ALIGN 4 0x4 { *(:boot_cfg) ; 匹配代码中标记为boot_cfg的段 } }
2. 在代码中声明配置变量
在应用或Bootloader代码中,声明全局变量并通过编译器属性指定其存放的段,确保链接器将变量放入刚才定义的Flash区域:
#include <stdint.h> // 声明复位向量变量,指定到boot_cfg段,used属性防止编译器优化删除 uint32_t app_reset_vector __attribute__((section("boot_cfg"), used)) = 0x08002000;
3. 无需Flash驱动修改变量的方式
变量直接固化在Flash中,不需要在MCU运行时调用Flash驱动程序修改,可通过以下方式更新:
- 编译时固化:直接修改代码中
app_reset_vector的初始值,重新编译生成固件后烧录,新的复位向量地址会自动写入指定Flash区域。 - 烧录时直接写入:使用烧录工具(如STM32CubeProgrammer、J-Link Commander),直接向链接脚本定义的Flash地址(比如
0x0801E800)写入新的32位复位向量地址,无需运行固件。 - 链接器传参设置:编译时通过链接器选项传递变量值,无需修改代码。例如ARM GCC环境下,添加编译选项:
链接器会直接将变量值设置为指定地址,覆盖代码中的初始值。-Wl,--defsym=app_reset_vector=0x08003000
4. Bootloader读取配置的方式
Bootloader启动时,直接从指定Flash地址读取32位值作为复位向量地址,执行跳转逻辑:
#define BOOT_CFG_ADDR 0x0801E800 void bootloader_jump_to_app(void) { uint32_t app_reset_addr = *(volatile uint32_t*)BOOT_CFG_ADDR; // 检查地址合法性(需匹配目标MCU的Flash地址范围) if((app_reset_addr & 0xFF000000) == 0x08000000) { // 复位向量存储的是栈顶地址,复位函数地址在其下4字节 void (*app_reset_handler)(void) = (void*)(*(volatile uint32_t*)(app_reset_addr + 4)); // 设置应用栈指针 __set_MSP(*(volatile uint32_t*)app_reset_addr); // 跳转至应用程序 app_reset_handler(); } }
内容的提问来源于stack exchange,提问作者user10217630
相关产品推荐
相关产品推荐

