2024-01-11 02:19 AM - edited 2024-08-12 02:42 AM
The main objective of this article is to provide a step-by-step guide on how to develop and add your own external loader to manage external memories. This demo implementation uses a STM32U5A9J-DK and octo-SPI interface, but it can be easily tailored for other microcontrollers and memory types. Thanks to the external loader feature in STM32CubeProgrammer, it is possible to have a direct access to external memories.
In section 2.1 below, the method of handling files is described in depth.
If you want to have the results of the edited files at hand immediately, then you can download the extractable file attached at the bottom of the article and skip to section 2.2.
File name | Source | Destination |
stm32u5xx_hal.h |
Repository\STM32Cube_FW_U5_V1.3.0\ Drivers\STM32U5xx_HAL_Driver\Inc |
MX25UM51245G_ STM32U5A9-DK\Includes\Library |
stm32u5xx_hal_cortex.h | ||
stm32u5xx_hal_def.h | ||
stm32u5xx_dma.h | ||
stm32u5_dma.exe.h | ||
stm32u5xx_hal_flash.h | ||
stm32u5xx_hal_flash_ex.h | ||
stm32u5xx_hal_gpio.h | ||
stm32u5xx_hal_gpio_ex.h | ||
stm32u5xx_hal_ospi.h | ||
stm32u5xx_hal_pwr.h | ||
stm32u5xx_hal_pwr_ex.h | ||
stm32u5xx_hal_rcc_ex.h | ||
stm32u5xx_hal_rcc.h | ||
stm32u5xx_hal_xspi.h | ||
stm32u5xx_hal_gfxtim.h | ||
stm32u5xx_ll_dlyb.h | ||
stm32u5x9j_discovery.h |
Repository\STM32Cube_FW_U5_V1.3.0\ Drivers\BSP\STM32U5x9J-DK |
MX25UM51245G_ STM32U5A9-DK\Includes\Library |
stm32u5x9j_discovery_bus.h | ||
stm32u5x9j_discovery_conf_template.h | ||
stm32u5x9j_discovery_errno.h | ||
stm32u5x9j_discovery_ospi.h | ||
mx25um51245g.h |
Repository\STM32Cube_FW_U5_V1.3.0\ Drivers\BSP\Components\mx25um51245g |
MX25UM51245G_ STM32U5A9-DK\Includes\Library. |
mx25um51245g_conf_template.h | ||
stm32u5a9xx.h |
Repository\STM32Cube_FW_U5_V1.3.0\ Drivers\CMSIS\Device\ST\ |
MX25UM51245G_ STM32U5A9-DK\Includes\Library |
stm32u5xx.h | ||
system_stm32u5xx.h | ||
stm32u5xx_hal.c |
Repository\STM32Cube_FW_U5_V1.3.0\ Drivers\STM32U5xx_HAL_Driver\Src |
MX25UM51245G_ STM32U5A9-DK\Sources\Library |
stm32u5xx_hal_cortex.c | ||
stm32u5xx_hal_dma.c | ||
stm32u5xx_hal_dma_ex.c | ||
stm32u5xx_hal_flash.c | ||
stm32u5xx_hal_flash_ex.c | ||
stm32u5xx_hal_gpio.c | ||
stm32u5xx_hal_ospi.c | ||
stm32u5xx_hal_pwr.c | ||
stm32u5xx_hal_pwr_ex.c | ||
stm32u5xx_hal_rcc.c | ||
stm32u5xx_hal_rcc_ex.c | ||
stm32u5xx_hal_xspi.c | ||
stm32u5xx_ll_dlyb.c | ||
stm32u5x9j_discovery.c |
Repository\STM32Cube_FW_U5_V1.3.0\ Drivers\BSP\STM32U5x9J-DK |
MX25UM51245G_ STM32U5A9-DK\Sources\Library |
stm32u5x9j_discovery_bus.c | ||
stm32u5x9j_discovery_ospi.c | ||
mx25um51245g.c |
Repository\STM32Cube_FW_U5_V1.3.0\ Drivers\BSP\Components\mx25um51245g |
MX25UM51245G_ STM32U5A9-DK\Sources\Library |
system_stm32u5xx.c file |
Repository\STM32Cube_FW_U5_V1.3.0\ Drivers\CMSIS\Device\ST\ |
MX25UM51245G_ STM32U5A9-DK\Sources\Library |
Old file name | New file name | Location |
stm32u5x9j_discovery_hal_conf_template.h | stm32u5x9j_discovery_hal_conf.h | MX25UM51245G_ STM32U5A9-DK\Includes\Library |
mx25um51245g_conf_template.h | mx25um51245g_conf.h | MX25UM51245G_ STM32U5A9-DK\Includes\Library |
File | Location | Modification |
stm32u5xx_hal.h | MX25UM51245G_STM32U5A9-DK\Includes\Library | Change #include "stm32u5xx_hal_conf.h" by #include "stm32u5xx_hal_conf_template.h" |
stm32u5xx_hal_gfxtim.h | MX25UM51245G_STM32U5A9-DK\Includes\Library | Comment " GFXTIM_TypeDef *Instance; " |
mx25um51245g_conf.h | MX25UM51245G_STM32U5A9-DK\Includes\Library |
Delete #include "stm32xxxx_hal.h" Add: #include "stm32u5xx.h" #include "stm32u5xx_hal.h" |
stm32u5xx.h | MX25UM51245G_STM32U5A9-DK\Includes\Library | Uncomment "#define STM32U5A9xx" |
stm32u5x9j_discovery_ospi.h | MX25UM51245G_STM32U5A9-DK\Includes\Library | Change #include "../Components/mx25um51245g/mx25um51245g.h" by #include "mx25um51245g.h" |
The purpose is to modify MX25UM51245G_STM32U5A9-DK\Sources\Loader\ Dev_Inf.c to support MX25UM51245G memory and STM32U5A9-DK board. For more information, refer to the memory MX25UM51245G datasheet and UM2967.
It is described in the datasheet, that MX25UM51245G is 512 Mbit octal interface serial NOR_Flash memory. In this case, the device type is "NOR_FLASH" with "Device Size 512 Mbit = 64 Mbytes = 0x4000000".
It is also mentioned in the memory datasheet that the "programming page size" is "256 bytes=0x100" and the "sector size" is "64 Kbytes=0x00010000".
In this case the memory has "1024 Sectors=0x00000400". You can find these details in the memory datasheet section 1. FEATURES.
The UM2967 states that MX25UM5124GXDIOO memory is connected to OCTOSPI1, so the "Device start address" is "0x90000000."
In conclusion, you can modify the Dev_Inf.c as shown below:
MX25UM51245G_STM32U5A9J-DK", // Device Name + Discovery Board name
NOR_FLASH, // Device Type
0x90000000, // Device Start Address
0x4000000, // Device Size in 64 MBytes
0x100, // Programming Page Size 4096 Bytes
0xFF, // Initial Content of Erased Memory
// Specify Size and Address of Sectors (view example below)
0x00000400, 0x00010000, // Sector Num : 1024 ,Sector Size: 64 KBytes
0x00000000, 0x00000000,
File | Location | Modification |
Loader_Src.c | MX25UM51245G_STM32U5A9-DK\Sources\Loader | Change #include "stm32u575i_eval_ospi.h" by #include "stm32u5x9j_discovery_ospi.h" |
Change “BSP_OSPI_NOR_Erase_Block(0,BlockAddr, MX25LM51245G_ERASE_64K);” by “BSP_OSPI_NOR_Erase_Block(0,BlockAddr, MX25UM51245G_ERASE_64K); | ||
Add Delay(*) in private Function
|
* This delay is necessary for read and write operations (refer to the memory datasheet).
Old file name | New file name | Location |
MX25LM512G_STM32U575I-EVAL.eww | MX25UM512G_STM32U5A9-DK.eww | MX25UM5124G_STM32U5A9-DK\Project\EWARM |
MX25LM512G_STM32U575I-EVAL.ewp | MX25UM51245G_STM32U5A9_DK.ewp | MX25UM5124G_STM32U5A9-DK\Project\EWARM |
File | Location | Modification |
MX25UM512G_STM32U5A9-DK.eww" | MX25UM512G_STM32U5A9-DK.ewwMX25UM5124G_ STM32U5A9-DK\Project\EWARM |
Change " <path>$WS_DIR$\MX25LM51245G_STM32U575_EVAL.ewp</path>" by" <path>$WS_DIR$\MX25UM51245G_STM32U5A9_DK.ewp</path>" |
File name | Source | Destination |
MX25UM5124G_STM32U5A9J-DK.stldr | MX25UM5124G_STM32U5A9-DK\Project\EWARM\Debug\Exe | Program Files\STMicroelectronics\ STM32Cube\ STM32CubeProgrammer \bin\ExternalLoader |
Open GPIO_IOToggle example from \Repository\STM32Cube_FW_U5_V1.3.0\Projects\STM32U5x9J-DK\Examples\GPIO\GPIO_IOToggle using STM32CubeIDE as shown in the below figure:
Right-click the GPIO_IOToggle project to modify its properties
Click to Debug then click to
Open STM32CubeProgrammer and click to External loaders, select MX25UM5124G_STM32U5A9J-DK.stldr and click to connect as in the figure below
Click on the icon "Erasing & programming":
Browse to the GPIO_IOToggle.bin binary created previously.
Choose the "Start address" 0x90000000 and select "Verify programming" to verify the download.
Click on "Start Programming".
Please make sure that the download verified successfully.
Click button reset and you can see LD3 and LD4 toggling.
Go to "Memory & File editing" and verify the same data output in 0x08000000 and in 0x90000000.
After following this guide, you should now be able to implement and use your own external flash loader. If you encounter any issues, we suggest that you create a post in the ST Community for further assistance.
GitHub: stm32-external-loader
UM2237: User manual - STM32CubeProgrammer software description
UM2967: User manual - discovery kit with STM32U5ANJ MCU
MX25UM51245G datasheet