2024-11-25 04:30 AM - edited 2024-11-26 04:33 AM
The primary objective of this article is to provide a comprehensive step-by-step guide on creating an external flash loader to interface with external memories. This demonstration uses the STM32H7S3L8H6 microcontroller and XSPI to interface with the external memory, but it can be easily tailored for other microcontrollers.
To create an external flash loader, follow the steps outlined below. The required tools for this process include STM32CubeProgrammer, STM32CubeMX, and STM32CubeIDE.
If the microcontroller operates under 2.5 V, High-Speed Low Voltage (HSLV) must be enabled. In this case, according to the datasheet, the flash memory operates at 1.8 V. Consequently, HSLV on I/O port 2 needs to be enabled, where the memory is interfaced. You can determine which port your memory uses by consulting the alternate functions section in your microcontroller's DS14360 Rev 2.
We developed this article using the Nucleo-H7S3L8, but to make it more generic started from the MCU itself. That’s why you should:
To enable the created external flash loader to operate on the microcontroller, you need to select the proper power supply. In this case, the Nucleo-H7S3L8 features a Low-dropout regulator (LDO) and doesn’t include a switched-mode power supply (SMPS) according to UM3276 - Rev 1. To configure it, you need to perform the steps below:
In this scenario, the external flash memory is interfaced with XSPI1 in [Octo SPI] mode on the second port, with the chip select pin set to [NCS1]. Refer to board schematics MB1737-B02.
Next, you need to select the memory manufacturer (memory type), memory size, chip select high time cycle, and delay hold quarter cycle from the memory datasheet and application note AN5050. In this case:
Memory type: Macronix
Memory size: 256 Mbit/s (maximum size is 256 Mbit/s according to the memory datasheet)
Chip select high time: 2 (found in the memory datasheet under "AC CHARACTERISTICS”)
Delay hold quarter cycle: Enabled (as the memory is used in DTR mode, per application note AN5050)
To prevent speculative reads from undesired external memory regions, the memory protection unit (MPU) needs to be enabled to allow access only from specific regions. In this case there are two MPU instances, one for the boot subproject, and the other for the application subproject. To configure the one relative to boot context, (CORTEX_M7_BOOT) the steps are as follows:
For further information about MPU attributes, refer to AN4838
As for the application context (CORTEX_M7_APPLI):
As mentioned above (section 2.1) HSLV needs to be used in this case. To activate it, you need to configure option bytes and SBS (secure boot system). In this case, I/O HSLV FOR XSPIM2 needs to be enabled.
External memory manager is a middleware that generates necessary drivers to interface with external memories and generates boot code. It needs to be configured as follows:
External memory loader is a middleware that makes generating custom external memory loaders more user-friendly. That’s why it needs to be configured.
*Refer to memory datasheet under “ERASE AND PROGRAMMING PERFORMANCE”
The operating frequency is up to 600 MHz for the STM32H7Rx/Sx family. For maximum performance, set the CPUCLK value to the mentioned frequency.
According to the memory datasheet, the maximum operating speed of the memory in DTR mode is 200 MHz However, the microcontroller, datasheet states that the XSPI interface can reach 190 MHz To fully use the clock speed of XSPI, you need to:
Before generating your custom external flash loader, you need to access the [Project Manager] and configure the following settings:
Using STM32CubeIDE:
After generating your project using STM32CubeMX, the next step is selecting the external memory loader subproject and building it. This step will generate your external flash loader.
Note: If your STM32CubePogrammer is installed in a privileged location, open STM32CubeIDE as administrator to authorize the copying of your generated folder under STM32CubeProgrammer path.
Note: If a "cp: can’t create 'C:\XX\XX' warning: File copy failed" error occurs, make sure that STM32CubeProgrammer is installed in an unprivileged directory, and that your project path doesn’t contain spaces.
A message should appear in the console, indicating that your loader has been successfully built. This occurs because the "Selected Toolchain" option is chosen in section 2.8.
Finally, you can find your external loader added to your project configuration if you are using STM32CubeIDE or are added into external loaders if you are using STM32CubeProgrammer. Furthermore, you can locate your loader in STM32CubeProgrammerPATH\bin\ExternalLoader\.If you’re using STM32CubeIDE, your loader should be added automatically. You can verify this in the [Debug Configurations] under [Debugger].
Then, an extra step should be done before debugging, which is adding the boot context image to be built and executed. Proceed with the following steps in debug configurations under startup:
Using STM32CubeProgrammer:
Under [External Loaders] select your loader to interact with your external memory by its address.