How do I find out the size of the flash memory in the code itself?

Viewed 1431

I want to get the limiting address of the flash in the code itself, or at least the size of this flash.

I found only the start address of the flash in the stm32f302xc.h file, but did not find the end address.

/** @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 */

What defines are responsible for this, thanks.

2 Answers

What you want is described in the reference manual RM0366 in section 29.2 Memory size data register.

ST provide this functionaility but for some reason they don't always give an easy way to access it in the headers.

The address of this register is FLASHSIZE_BASE. You have to read it at run-time, eg:

uint16_t flash_size_kb = *(const uint16_t*)FLASHSIZE_BASE;

STM32 MCU families come in different flash sizes, that's why it's not defined in their header files. Although STM32CubeMX code generator could, in theory, add it when you select the exact model of your MCU. But this would mean code might not work if you flash it to variant with a different flash size.

However some STM32 MCUs come with a Flash size data register that contains information about the flash size. This address is often found in a header file and sometimes a macro is included. Note that it not a compile time constant, but a ROM constant that needs to be read at runtime.

stm32f3xx_hal_flash_ex.h contains the following register address:

#define FLASH_SIZE_DATA_REGISTER (0x1FFFF7CCU)

You can use it like this:

const size_t FLASH_SIZE = (*((uint16_t*)FLASH_SIZE_DATA_REGISTER)) << 10;

For the stm32g4xx there is a macro defined in stm32g4xx_hal_flash.h:

FLASH_SIZE

Be careful with writing your own macro for this as the flash size is not always linear with the value in the register. In the case of the stm32g4xx the value 0xFFFF means either 128kiB or 512kiB as seen below:

#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

The same applies to flash page size. Page size depends on the family and sometimes on the flash size. Sometimes ST provides a macro for this too.

Related