在STM32的项目中,默认的STM32F103RETX_Flash.ld的链接文件中对代码进行了基本的分配,见下图:
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN=0x20000000, LENGTH=64K//RAM的空间分配
FLASH (rx) : ORIGIN=0x8000000, LENGTH=640K//Flash的空间分配
}
在实际的应用需求中,我们可能需要在一些特定的位置存储特定的数据,比如上一篇文章中(C# BIN文件读取以及CRC校验(匹配STM32F103)),需要在特定的位置存储Application的CRC校验值,这个校验值会在BootLoader中调用。
当然,还有一些数据,如Application Firmware版本,芯片版本,用户配置等信息,需要存储在一定的位置,在我的应用中,开辟了1K Bytes的空间,来存储这些信息,地址为0x8008000到0x8008400。
它们的代码空间分配如下:
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K //RAM空间分配
CRC (rw) : ORIGIN = 0x8008000, LENGTH = 4//CRC校验值空间分配,地址0x8008000,长度为4bytes
DEVICEID (rw) : ORIGIN = 0x8008004, LENGTH = 4//Device ID的空间分配,地址为0x8008004,长度为4bytes
APPFWVERSION (rw) : ORIGIN = 0x8008008, LENGTH = 4//Application Firmware版本的空间分配,地址为0x8008008,长度为4bytes
APPDATA (rw) : ORIGIN = 0x800800C, LENGTH = 1012//预留的配置空间
FLASH (rx) : ORIGIN = 0x8008400, LENGTH = 470K//Application Firmware执行代码的空间,长度为470K。
//剩下的32K给了BootLoader,不在这里定义。
}
然后对配置信息的空间进行定义:(这一部分关系到空间区域的调用)
/*user reserved data*/ //预留配置信息的定义
.app_data :
{
.=ALIGN(4);
PROVIDE_HIDDEN (__app_data_start=.);
KEEP (*(SORT(.app_data.*)))
KEEP (*(.app_data*))
PROVIDE_HIDDEN (__app_data_end=.);
.=ALIGN(4);
} >APPDATA
/*user code for app fw version value*/ //fw_vesrsion 定义分配到APPFWVERSION空间
.fw_version :
{
.=ALIGN(4);
PROVIDE_HIDDEN (__fw_version_start=.);
KEEP (*(SORT(.fw_version.*)))
KEEP (*(.fw_version*))
PROVIDE_HIDDEN (__fw_version_end=.);
.=ALIGN(4);
} >APPFWVERSION
/*user code for device id value*/ //device_id
.device_id :
{
.=ALIGN(4);
PROVIDE_HIDDEN (__device_id_start=.);
KEEP (*(SORT(.crc_value.*)))
KEEP (*(.device_id*))
PROVIDE_HIDDEN (__device_id_end=.);
.=ALIGN(4);
} >DEVICEID
/*user code for app flash crc value*/ //crc_value
.crc_value :
{
.=ALIGN(4);
PROVIDE_HIDDEN (__crc_value_start=.);
KEEP (*(SORT(.crc_value.*)))
KEEP (*(.crc_value*))
PROVIDE_HIDDEN (__crc_value_end=.);
.=ALIGN(4);
} >CRC
上述空间分配完毕之后,如何调用呢?
#define APP_FIRMWARE_MAX_VERSION (0)
#define APP_FIRMWARE_MIN_VERSION (0)
#define APP_FIRMWARE_PATCH_VERSION (0)
#define APP_FIRMWARE_BUILD_VERSION (1)
static const uint32_t app_flash_crc_value __attribute__((section(".crc_value")))=0x41E588DD; //CRC值,注意section里面的字符要和上面定义的字符一致才可以
static const uint32_t app_flash_device_id __attribute__((section(".device_id")))=0x03330000;
static const uint32_t app_fw_version __attribute__((section(".fw_version")))=APP_FIRMWARE_BUILD_VERSION|(APP_FIRMWARE_PATCH_VERSION<<8)|(APP_FIRMWARE_MIN_VERSION<<16)|(APP_FIRMWARE_MAX_VERSION<<24);
就这样就可以简单地调用数据,编译出来的效果为,0x8008000地址上的数据为0x41E588DD,0x8008004地址上的数据为0x03330000。
当然了,不同的编译软件,链接文件的格式会有差别,我这个是针对STM32CubeIDE,可能Keil或者IAR就修改格式不一样,有一个小窍门就是,看它默认的Flash的定义,是如何定义的,复制一下,然后修改一下名称,基本上都是可以用的。