我想在代码本身中获得闪存的限制地址,或者至少是这个闪存的大小。
我在stm32f302xc.h
文件中只找到了闪存的起始地址,但没有找到结束地址。
/** @addtogroup Peripheral_memory_map
* @{
*/
#define FLASH_BASE 0x08000000UL /*!< FLASH base address in the alias region */
#define SRAM_BASE 0x20000000UL /*!< SRAM base address in the alias region */
#define PERIPH_BASE 0x40000000UL /*!< Peripheral base address in the alias region */
#define SRAM_BB_BASE 0x22000000UL /*!< SRAM base address in the bit-band region */
#define PERIPH_BB_BASE 0x42000000UL /*!< Peripheral base address in the bit-band region */
什么定义对此负责,谢谢。
参考手册RM0366中29.2内存大小数据寄存器部分描述了您想要的内容。
ST提供了这种功能,但由于某些原因,它们并不总是提供一种在标头中访问它的简单方法。
此寄存器的地址为FLASHSIZE_BASE
。你必须在运行时阅读它,例如:
uint16_t flash_size_kb = *(const uint16_t*)FLASHSIZE_BASE;
STM32 MCU系列有不同的闪存大小,这就是为什么它们的头文件中没有定义它。尽管STM32CubeMX代码生成器理论上可以在您选择MCU的确切型号时添加它。但这意味着,如果您将代码闪存为具有不同闪存大小的变体,代码可能无法工作。
然而,一些STM32 MCU附带一个闪存大小数据寄存器,其中包含有关闪存大小的信息。这个地址经常出现在头文件中,有时还会包含一个宏。请注意,它不是编译时常数,而是需要在运行时读取的ROM常数。
stm32f3x_hal_flash_ex.h包含以下寄存器地址:
#define FLASH_SIZE_DATA_REGISTER (0x1FFFF7CCU)
你可以这样使用它:
const size_t FLASH_SIZE = (*((uint16_t*)FLASH_SIZE_DATA_REGISTER)) << 10;
对于stm32g4xx,在stm32g4xx_hal_flash.h:中定义了一个宏
FLASH_SIZE
为此编写自己的宏时要小心,因为闪存大小并不总是与寄存器中的值线性。在stm32g4xx的情况下,值0xFFFF表示128kiB或512kiB,如下所示:
#define FLASH_SIZE_DATA_REGISTER FLASHSIZE_BASE
#if defined (FLASH_OPTR_DBANK)
#define FLASH_SIZE ((((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0xFFFFU)) ? (0x200UL << 10U) :
(((*((uint32_t *)FLASH_SIZE_DATA_REGISTER)) & 0xFFFFUL) << 10U))
#define FLASH_BANK_SIZE (FLASH_SIZE >> 1)
#define FLASH_PAGE_NB 128U
#define FLASH_PAGE_SIZE_128_BITS 0x1000U /* 4 KB */
#else
#define FLASH_SIZE ((((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0xFFFFU)) ? (0x80UL << 10U) :
(((*((uint32_t *)FLASH_SIZE_DATA_REGISTER)) & 0xFFFFUL) << 10U))
#define FLASH_BANK_SIZE (FLASH_SIZE)
#define FLASH_PAGE_NB ((FLASH_SIZE == 0x00080000U) ? 256U : 64U)
#endif
这同样适用于flash页面大小。页面大小取决于家庭,有时还取决于闪光灯的大小。有时ST也为此提供了一个宏。