使用場景如下:
我需要將bootloader/APP的版本號和一些字段信息定義到指定FLASH地址.
在STM32CubeIDE中的方法:
截止當前STM32CubeIDE還沒有提供圖形化的針對FLASH划分定義的支持選項, 所以第一步我們需要手動更改 .ld文件 (鏈接文件).
原文件如下(部分):
/* Memories definition */
MEMORY
{
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K
}
修改后:
/* Memories definition */
MEMORY
{
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 8K
VERSION_FLASH (rx) : ORIGIN = 0x8002000, LENGTH = 1K
REMFLASH (rx) : ORIGIN = 0x8002400, LENGTH = 55K
}
/* Sections */
SECTIONS
{
/* The startup code into "FLASH" Rom type memory */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* The program code and other data into "FLASH" Rom type memory */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} > REMFLASH
.version_code :
{
*(.bl_info.ver)
*(.bl_info.date)
*(.bl_info.detailed);
} > VERSION_FLASH
....略
我們重點看一下修改后的FLASH內存結構.
這里將FLASH的前8K預留出來, 用於存放中斷向量表這是硬規! 所以我們不能划分FLASH的起始區域自用.
僅中斷向量表是用不完8K的,因為后面還有一些其它項的分配如 .ARM.extab, .ARM 所以這里簡單預留為8K.
后面的 VERSION_FLASH 用於存儲我們的自定義字段. 這里划分為1K.
REMFLASH 用於存放程序代碼.
具體變量定義使用如下
volatile const char __RO_BL_INFO_VERSION__[] __attribute__((section(".bl_info.ver"))) = {"XXXX_V1.0"};
volatile const char __RO_BL_INFO_DATE__[] __attribute__((section(".bl_info.date"))) = { __DATE__ };
volatile const char __RO_BL_INFO_DETAIL__[] __attribute__((section(".bl_info.detailed"))) = { "Hello world !" };
定義好之后, 可以通過 .map 文件查看變量具體的存儲地址.
如上操作后, 正常情況下 .map 中並不會有你想要的變量. 原因是編譯器給優化了.
我嘗試使用了很多別的辦法, 但是最終只有如下方法可行.
if (__RO_BL_INFO_VERSION__[0] == 'A' && __RO_BL_INFO_VERSION__[2] == 'A'
&& __RO_BL_INFO_DATE__[1] == 'A') {
while (1);
}
如有其它更好的方法, 預防編譯器優化. 請留言.
下面是一個重要提示:
切忌不要將上文中的 VERSION_FLASH 分配到FLASH的最后. 例如:
/* Memories definition */
MEMORY
{
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 8K
REMFLASH (rx) : ORIGIN = 0x8002000, LENGTH = 32K
VERSION_FLASH (rx) : ORIGIN = 0x800A000, LENGTH = 1K
}
原因是我們並不清楚(或者非常麻煩)程序到底需要占用多大的FLASH空間. 如果 REMFLASH 定義的非常大, 則最終生成的 bin 文件將非常大(中間會有空填充),
如上的具體大小為 8+32 = 40K, 而實際的有效程序可能只有18K大小(HEX無影響). 該bin文件的大小計算僅僅適用於STM32CubeIDE, 在一些其它的IDE可能會是
40K大小. 但不管計算方法如何, 最終都會造成bin體積的增大. 如果該bin用於APP程序的升級將造成很大的時間浪費.