Arm 在特定地址使用linkerscript在mcu闪存中保留16K扇区
我正在使用gnu工具链(9.2.1)为STM32F429创建一个引导加载程序,并尝试为引导加载程序和应用程序共享的用户数据保留一些闪存。我想保留它的前四个16K闪存扇区中的第二个,因为它们很好而且很小:所有其他扇区都是128K。 内存布局应如下所示:Arm 在特定地址使用linkerscript在mcu闪存中保留16K扇区,arm,embedded,bootloader,stm32f4,linker-scripts,Arm,Embedded,Bootloader,Stm32f4,Linker Scripts,我正在使用gnu工具链(9.2.1)为STM32F429创建一个引导加载程序,并尝试为引导加载程序和应用程序共享的用户数据保留一些闪存。我想保留它的前四个16K闪存扇区中的第二个,因为它们很好而且很小:所有其他扇区都是128K。 内存布局应如下所示: ISR vector table : 0x08000000 (428 bytes) padding : 0x080001ac (15956 bytes) ----------------------------- user dat
ISR vector table : 0x08000000 (428 bytes)
padding : 0x080001ac (15956 bytes)
-----------------------------
user data : 0x08004000 (16K)
-----------------------------
bootloader code : 0x08008000 (max 224K, for total of max. 256K)
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K /* max. bootloader binary size */
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 191K /* deduct 1K for NOINIT data */
NOINIT (rwx) : ORIGIN = 0x2002FC00, LENGTH = 1K /* NOINIT data will survive reset */
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* Then comes user flash sector, make sure to get one of the first 4 that are 16K in size
.user_flash :
{
. = ALIGN(0x4000)
KEEP(*(.user_flash))
. = ALIGN(0x4000)
} >FLASH
/* ... more sections below not shown here */
}
我已将ST's修改为如下:
ISR vector table : 0x08000000 (428 bytes)
padding : 0x080001ac (15956 bytes)
-----------------------------
user data : 0x08004000 (16K)
-----------------------------
bootloader code : 0x08008000 (max 224K, for total of max. 256K)
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K /* max. bootloader binary size */
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 191K /* deduct 1K for NOINIT data */
NOINIT (rwx) : ORIGIN = 0x2002FC00, LENGTH = 1K /* NOINIT data will survive reset */
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* Then comes user flash sector, make sure to get one of the first 4 that are 16K in size
.user_flash :
{
. = ALIGN(0x4000)
KEEP(*(.user_flash))
. = ALIGN(0x4000)
} >FLASH
/* ... more sections below not shown here */
}
在我的bootloader.cpp中,我声明用户flash如下:
__attribute__((__section__(".user_flash"))) const uint32_t user_flash[0x4000 / sizeof(uint32_t)] = {0};
但是,在调试器中,user_flash
的地址不是预期的0x08004000
,而是0x0801b4e8
从声明中删除\uuuuu属性((uuu section\uuuu(“.user\u flash”))
会产生不同的地址,证明该属性至少有一些效果
在.elf文件上运行arm non-eabi objdump-h
可确认user\u flash
部分的(不正确)地址。
我还尝试使用声明该节0x08004000
,无效
我尝试的另一种方法是将.isr\u vector
放在它自己的16K部分中,然后是用户flash的16K部分,最后是(256-16-16)=224K flash部分。这就产生了一个伪造的二进制文件,可能会出现硬故障
我做错了什么
编辑:
我在
.isr\u vector
之后插入了一个.padding
部分,试图以这种方式对齐.user\u flash
,但无论我做什么,.text
和.rodata
部分似乎总是紧跟在之后,即使它们是在.user\u flash
部分之后声明的。更改了标题并澄清了所需的内存布局。
/* move the NVIC because we are running from 08004000 */
SCB->VTOR = (FLASH_BASE | 0x4000);