STM32H7R7/S7系列是一款基于bootflash的MCU,具有Cortex®-M7内核,运行频率高达600 MHz,拥有64 KB用户bootflash、可灵活配置的620 KB SRAM以及带Flex ECC的32 x 32 KB缓存。STM32H7R7/S7系列支持高速外部存储器接口和XiP,提供5种不同封装,以在极低成本下实现出色性能。专用图形系列可利用NeoChrom GPU、JPEG编解码器和LTDC实现类似MPU的GUI,最大程度减少CPU的介入。 - Bootflash闪存: STM32H7R7/S7系列MCU配备了64KB的Bootflash(用户Flash),可用于存储用户代码或外部存储器配置。这种设计提供了更大的灵活性和可扩展性。
- SRAM:MCU还集成了高达620KB的SRAM(其中部分可配置为TCM),支持实时应用中所需的零等待访问。这确保了高速的数据处理能力。
- 外部存储器接口:MCU提供了高速外部存储器接口,如FMC(支持NAND、NOR、SDRAM的并行接口)和xSPI接口,允许连接任何类型的外部存储器。这种设计使得MCU能够灵活匹配未来不同的应用需求。
Bootflash的MCU具有以下特点: - 内置Bootflash存储器:这是Bootflash MCU的核心特色,它提供了可靠的存储空间,用于保存启动代码、配置参数或其他关键数据。这种存储器通常具有较长的数据保持时间,即使在断电的情况下也能保持数据不丢失。
- 高性能:Bootflash的MCU通常采用高性能的处理器核心,如ARM Cortex-M系列等,具有强大的处理能力和丰富的外设接口。这使得它们能够处理复杂的任务,并满足各种应用需求。
- 安全性:由于Bootflash存储器中存储了启动代码和其他关键数据,因此Bootflash的MCU通常具有较高的安全性。它们可能采用各种安全机制来保护这些数据,如加密、解密、认证等,以防止未经授权的访问或篡改。
- 灵活性:Bootflash的MCU提供了灵活的启动选项。例如,它们可能支持从内部存储器(如Bootflash)或外部存储器(如SD卡、eMMC等)启动系统。这种灵活性使得它们能够适应不同的应用场景和需求。
- 广泛的应用领域:由于Bootflash的MCU具有高性能、安全性和灵活性等特点,它们被广泛应用于各种领域,如工业自动化、智能家居、医疗设备、汽车电子等。在这些领域中,Bootflash的MCU能够发挥重要作用,提高系统的可靠性和稳定性。
STM32的XIP(eXecute In Place,原地执行)是一种允许代码直接在非易失性存储器(如Flash)中执行的技术,而无需将代码复制到易失性存储器(如SRAM)中。这种执行方式具有一些独特的优点和特性,下面将对其进行详细解释:
一、XIP的基本概念
XIP技术允许CPU直接从存储代码的存储器(如Flash)中读取并执行指令,而无需先将代码加载到RAM中。这对于资源受限的单片机系统来说尤其重要,因为它可以减少对RAM的需求,从而降低成本并优化系统性能。
二、STM32中的XIP实现
在STM32单片机中,XIP通常通过特定的存储器映射和启动配置来实现。以下是一些关键点:
存储器映射:STM32的存储器架构允许将外部或内部Flash存储器映射到CPU可以访问的地址空间。当使用XIP时,代码被存储在Flash中,并通过存储器映射直接由CPU访问和执行。
启动配置:STM32的启动配置可以通过设置BOOT引脚来选择不同的启动模式。例如,可以选择从主闪存(Flash)启动,或者从系统存储器(通常包含Bootloader)启动。在XIP模式下,通常是从包含代码的Flash区域启动。
中断向量表:在XIP模式下,中断向量表(IVT)通常也存储在Flash中。当CPU响应中断时,它会从IVT中读取中断处理程序的地址,并跳转到相应的处理程序执行。因此,在XIP模式下,IVT的地址必须与Flash中的代码地址相匹配。
三、XIP的优点
减少RAM需求:由于代码直接在Flash中执行,因此无需将代码复制到RAM中。这可以显著减少对RAM的需求,从而降低系统成本。
快速启动:由于代码已经存储在Flash中,并且可以直接执行,因此系统可以更快地启动并运行。
易于更新:由于代码存储在Flash中,因此可以通过简单的编程操作来更新代码,而无需拆卸硬件或更换存储器芯片。
四、XIP的应用场景
XIP技术特别适用于以下场景:
资源受限的系统:在这些系统中,RAM的容量有限,而Flash存储器则相对充裕。使用XIP可以减少对RAM的需求,从而优化系统性能。
需要快速启动的系统:在这些系统中,启动时间是一个关键因素。使用XIP可以加快启动速度,从而缩短系统的响应时间。
需要频繁更新代码的系统:在这些系统中,代码需要经常更新以修复漏洞或添加新功能。使用XIP可以通过简单的编程操作来更新代码,而无需拆卸硬件。
代码分析:
STM32CubeH7RS软件包中提供了XIP项目模板,项目专有文件位于子目录。Projects\STM32H7S78-DK\Templates\Template_XIP
项目表述
Templates_XIP Example Description</b>
- This project provides a reference template based on the STM32Cube HAL API that can be used
to build any firmware application to execute from external Flash (Sub-project Appli). It boots from internal Flash
and jumps to the application code in external Flash (Sub-project Boot).
- This project is targeted to run on STM32H7S7xx device on STM32H7S78-DK board from STMicroelectronics.
At the beginning of the main program, the HAL_Init() function is called to reset
all the peripherals and initialize the systick used as 1ms HAL timebase.
- This project runs from the external Flash memory. It is launched from a first boot stage and inherits from this boot project
configuration (caches, MPU regions [regions 0, 1 and 2 here], system clock at 600 MHz and external memory interface at the highest speed).
Note that the boot part is automatically downloaded from the IDE environment via the board project Templates/Template_XIP/Binary/Boot_XIP.hex file.
- The template project calls also SCB_EnableICache() and SCB_EnableDCache() functions in order to enable
the Layer 1 Core Instruction and Data Caches. This is provided as template implementation that the User may
integrate in his application in order to enhance the performance.
#### <b>Notes</b>
1. Care must be taken when using HAL_Delay(), this function provides accurate delay (in milliseconds)
based on variable incremented in SysTick ISR. This implies that if HAL_Delay() is called from
a peripheral ISR process, then the SysTick interrupt must have higher priority (numerically lower)
than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
To change the SysTick interrupt priority you have to use HAL_NVIC_SetPriority() function.
2. The application needs to ensure that the SysTick time base is always set to 1 millisecond
to have correct HAL operation.
3. Whenever the application is using ITCM/DTCM memories (@0x0000000 / @0x20000000: not cacheable and only accessible
by the Cortex M7 and the GPDMA/HPDMA), there is no need for cache maintenance.
If the application needs to put DMA buffers in AXI SRAM (starting from @0x24000000), the user has to:
- either define a non-cacheable region in the MPU and linker configuration file to locate DMA buffers
(a proposed noncacheable_buffer section is available from CMSIS Device linker template file and its size must
be adapted to the application requirements)
- or to ensure cache maintenance operations to ensure the cache coherence between the CPU and the DMAs.
This is true also for any other data buffers accessed by the CPU and other masters (DMA2D, LTDC).
The addresses and the size of cacheable buffers (shared between CPU and other masters)
must be properly defined to be aligned to data cache line size (32 bytes) and of a size of being multiple
of this cache line size.
Please refer to the AN4838 "Managing memory protection unit (MPU) in STM32 MCUs".
Please refer to the AN4839 "Level 1 cache on STM32F7 Series".
### <b>Keywords</b>
Reference, Template, Boot, Loader, XiP
### <b>Directory contents</b>
#### <b>Sub-project Boot</b>
File | Description
--- | ---
Templates/Template_XIP/Boot/Inc/main.h | Header for main.c module
Templates/Template_XIP/Boot/Inc/extmem_manager.h | Header for extmem_manager.c module
Templates/Template_XIP/Boot/Inc/stm32h7rsxx_hal_conf.h | HAL Configuration file
Templates/Template_XIP/Boot/Inc/stm32h7rsxx_it.h | Interrupt handlers header file
Templates/Template_XIP/Boot/Inc/stm32h7s78_discovery_conf.h | BSP Configuration file
Templates/Template_XIP/Boot/Inc/stm32_extmem_conf.h | External memory manager Configuration file
Templates/Template_XIP/Boot/Src/main.c | Main program
Templates/Template_XIP/Boot/Src/extmem_manager.c | code to initialize external memory
Templates/Template_XIP/Boot/Src/stm32h7rsxx_hal_msp.c | HAL MSP module
Templates/Template_XIP/Boot/Src/stm32h7rsxx_it.c | Interrupt handlers
Templates/Template_XIP/Boot/Src/system_stm32h7rsxx.c | STM32H7RSxx system source file
#### <b>Sub-project Appli</b>
File | Description
--- | ---
Templates/Template_XIP/Appli/Inc/main.h | Header for main.c module
Templates/Template_XIP/Appli/Inc/stm32h7rsxx_hal_conf.h | HAL Configuration file
Templates/Template_XIP/Appli/Inc/stm32h7rsxx_it.h | Interrupt handlers header file
Templates/Template_XIP/Appli/Inc/stm32h7s78_discovery_conf.h | BSP Configuration file
Templates/Template_XIP/Appli/Src/main.c | Main program
Templates/Template_XIP/Appli/Src/stm32h7rsxx_hal_msp.c | HAL MSP module
Templates/Template_XIP/Appli/Src/stm32h7rsxx_it.c | Interrupt handlers
Templates/Template_XIP/Appli/Src/system_stm32h7rsxx.c | STM32H7RSxx system source file
#### <b>Sub-project ExtMemLoader</b>
File | Description
--- | ---
Templates/Template_XIP/ExtMemLoader/Inc/extmem_manager.h | Header for extmem_manager.c module
Templates/Template_XIP/ExtMemLoader/Inc/extmemloader_init.h | Header for system initialization
Templates/Template_XIP/ExtMemLoader/Inc/stm32_extmem_conf.h | External memory manager Configuration file
Templates/Template_XIP/ExtMemLoader/Inc/stm32_extmemloader_conf.h | Header with externam memory device information
Templates/Template_XIP/ExtMemLoader/Inc/stm32h7rsxx_hal_conf.h | HAL Configuration file
Templates/Template_XIP/ExtMemLoader/Src/extmem_manager.c | code to initialize external memory
Templates/Template_XIP/ExtMemLoader/Src/extmemloader_init.c | code to perform system initialization
Templates/Template_XIP/ExtMemLoader/Src/stm32h7rsxx_hal_msp.c | HAL MSP module
Templates/Template_XIP/ExtMemLoader/Src/system_stm32h7rsxx.c | STM32H7RSxx system source file
Templates/Template_XIP/ExtMemLoader/Config/extmemloader.board | Configuration file
Templates/Template_XIP/ExtMemLoader/Config/extmemloader.flash | Configuration file
Templates/Template_XIP/ExtMemLoader/Config/extmemloader.mac | Configuration file
### <b>Hardware and Software environment</b>
- This template runs on STM32H7S7xx devices.
- This template has been tested with STMicroelectronics STM32H7S78-DK
boards and can be easily tailored to any other supported device
and development board.
- On STM32H7S78-DK board, the BOOT0 mechanical slide switch must be set to SW1.
- User Option Bytes requirement (with STM32CubeProgrammer tool):
- XSPI1_HSLV=1 I/O XSPIM_P1 High speed option enabled
- XSPI2_HSLV=1 I/O XSPIM_P2 High speed option enabled
- VDDIO_HSLV=0 I/O speed optimized to operate at 3.3V
### <b>How to use it ?</b>
In order to make the program work, you must do the following:
#### <b>IAR</b>
1. Open your toolchain
2. Open Multi-projects workspace file Project.eww
> <b>Optional:</b>
>
> - Select first "Template_XIP_Boot" workspace
> - Rebuild all files from sub-project Boot
> - If no modification is done on boot project, this step could be skipped.
3. Select then "Template_XIP_Appli" workspace
4. Rebuild all files from sub-project Appli and load your images into memories: This sub-project
will first load the Appli part in External memory available on STM32H7S78-DK board, then load
the Template_XIP_Boot.hex in internal Flash.
5. Run the example
NB: For this target, following switches are set in C/C++ preprocessor settings:
- STM32_EXTMEMLOADER_EWARMTARGET
- STM32_EXTMEMLOADER_STM32CUBETARGET_NA
- STM32_EXTMEMLOADER_STM32CUBEOPENBLTARGET_NA
#### <b>MDK-ARM</b>
1. Open your toolchain
2. Open Multi-projects workspace file Project.uvmpw
> <b>Optional:</b>
>
> - Select first "Template_XIP_Boot" workspace
> - Rebuild all files from sub-project Boot
> - If no modification is done on boot project, this step could be skipped.
3. Select then "Template_XIP_Appli" workspace
4. Rebuild all files from sub-project Appli and load your images into memories: This sub-project
will first load the Appli part in External memory available on STM32H7S78-DK board, then load
the Boot_XIP.hex in internal Flash.
5. Run the example
NB: For this target, following switches are set in C/C++
preprocessor settings:
- STM32_EXTMEMLOADER_MDKARMTARGET
- STM32_EXTMEMLOADER_STM32CUBETARGET_NA
- STM32_EXTMEMLOADER_STM32CUBEOPENBLTARGET_NA
#### <b>STM32CubeIDE</b>
1. Open your toolchain
2. Open Multi-projects workspace file .project
> <b>Optional:</b>
>
> - Select the "Template_XIP_Boot" project
> - Build the project
> - If the project is not compiled, Appli debugging will manage its compilation
> for debugging
> - With the debug icon select the configuration “Template_XIP_Boot Debug”.
> This operation loads the boot in internal Flash.
3. Select the "Template_XIP_Appli" project
4. Build the project
5. With the Debug icon select the configuration “Template_XIP_Appli Debug”. This sub-project
will first load the Boot binary in internal Flash, then load the Appli binary in
External memory available on STM32H7S78-DK board
6. Run the example
#### <b>STM32CubeProgrammer</b>
> The ExtMemLoader project uses an environment variable to copy the generated stdlr file inside
> the cube programmer tool.
> This variable is defined by the tool during its installation but if the version used does not
> include this functionality, the environment variable can be declared manually.
>
> STM32_PRG_PATH=C:/Program Files/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin
When targeting to build ExtMemLoader to be used in Cubepogrammer, please ensure the following switches are set in C/C++ preprocessor settings:
- STM32_EXTMEMLOADER_EWARMTARGET_NA
- STM32_EXTMEMLOADER_STM32CUBETARGET
- STM32_EXTMEMLOADER_STM32CUBEOPENBLTARGET_NA
#### <b>External memory programming using BootLoader Interfaces</b>
> When using a bootloader interface such as USB or USART, the standard ExtMemLoader cannot be used.
>Instead, a specific ExtMemLoader must be built for use with OpenBootloader. To accomplish this, you should carry out the following steps:
>
>- Modify the target switches in the C/C++ preprocessor settings to:
>
> - STM32_EXTMEMLOADER_EWARMTARGET_NA
> - STM32_EXTMEMLOADER_STM32CUBETARGET
> - STM32_EXTMEMLOADER_STM32CUBEOPENBLTARGET
>- Choose the appropriate file for your linker script based on the file extension (.sct, .ld, or .icf). The file should be renamed to match the following pattern, depending on the extension:
> * stm32h7rsxx_extmemloader_stm32cubeopenbl.sct
> * stm32h7rsxx_extmemloader_stm32cubeopenbl.ld
> * stm32h7rsxx_extmemloader_stm32cubeopenbl.icf
>- The initialization section of extmemloader_init() should be updated as follows:
>
> #if !defined(STM32_EXTMEMLOADER_STM32CUBEOPENBLTARGET)
>
> /* Init system */
> SystemInit();
>
> /* disable all the IRQ */
>
> __disable_irq();
>
> /* MCU Configuration--------------------------------------------------------*/
>
> /* Enable the CPU Cache */
>
> /* Enable I-Cache---------------------------------------------------------*/
>
> SCB_EnableICache();
>
> /* Enable D-Cache---------------------------------------------------------*/
>
> SCB_EnableDCache();
>
> /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
>
> HAL_Init();
>
> /* USER CODE BEGIN Init */
>
> /* USER CODE END Init */
>
> /* Configure the system clock */
>
> SystemClock_Config();
>
> #else
> /* Reset of all peripherals, Initializes the Flash interface. */
>
> __HAL_RCC_SBS_CLK_ENABLE();
>
> /* System interrupt init*/
>
> /* Enable the XSPIM_P2 interface */
>
> HAL_PWREx_EnableXSPIM2();
>
> /* high speed low voltage config */
>
> HAL_SBS_EnableIOSpeedOptimize(SBS_IO_XSPI1_HSLV);
>
> HAL_SBS_EnableIOSpeedOptimize(SBS_IO_XSPI2_HSLV);
>
> #endif
本项目提供了一个基于 STM32Cube HAL API 的参考模板,可用于构建任何固件应用程序以从外部闪存执行(子项目应用程序)。它从内部 Flash 启动,并跳转到外部 Flash 中的应用程序代码(子项目启动)。 本项目提供了一个基于 STM32Cube HAL API 的参考模板,可用于构建任何固件应用程序以从外部闪存执行(子项目应用程序)。它从内部 Flash 启动,并跳转到外部 Flash 中的应用程序代码(子项目启动)。
该项目的目标是在 STMicroelectronics 的 STM32H7S78-DK 板上的 STM32H7S7xx 器件上运行。在主程序开始时,调用 HAL_Init() 函数来重置所有外围设备并初始化用作 1ms HAL 时基的系统。 该项目的目标是在 STMicroelectronics 的 STM32H7S78-DK 板上的 STM32H7S7xx 器件上运行。在主程序开始时,调用 HAL_Init() 函数来重置所有外围设备并初始化用作 1ms HAL 时基的系统。
此项目从外部 Flash 存储器运行。它从第一个引导阶段启动,并继承自此引导项目配置(缓存、MPU 区域 [此处为区域 0、1 和 2]、600 MHz 的系统时钟和最高速度的外部存储器接口)。请注意,引导部件是通过板项目 Templates/Template_XIP/Binary/Boot_XIP.hex 文件从 IDE 环境自动下载的。 此项目从外部 Flash 存储器运行。它从第一个引导阶段启动,并继承自此引导项目配置(缓存、MPU 区域 [此处为区域 0、1 和 2]、600 MHz 的系统时钟和最高速度的外部存储器接口)。请注意,引导部件是通过板项目 Templates/Template_XIP/Binary/Boot_XIP.hex 文件从 IDE 环境自动下载的。
模板项目还调用 SCB_EnableICache() 和 SCB_EnableDCache() 函数,以启用第 1 层内核指令和数据缓存。这是作为模板实现提供的,用户可以将其集成到其应用程序中以提高性能。 模板项目还调用 SCB_EnableICache() 和 SCB_EnableDCache() 函数,以启用第 1 层内核指令和数据缓存。这是作为模板实现提供的,用户可以将其集成到其应用程序中以提高性能。
Notes 注意
使用 HAL_Delay() 时必须小心,此函数根据 SysTick ISR 中递增的变量提供准确的延迟(以毫秒为单位)。这意味着,如果 HAL_Delay() 是从外围 ISR 进程调用的,则 SysTick 中断必须具有比外围中断更高的优先级(数值上更低)。否则,调用方 ISR 进程将被阻止。要更改 SysTick 中断优先级,您必须使用 HAL_NVIC_SetPriority() 函数。 使用 HAL_Delay() 时必须小心,此函数根据 SysTick ISR 中递增的变量提供准确的延迟(以毫秒为单位)。这意味着,如果 HAL_Delay() 是从外围 ISR 进程调用的,则 SysTick 中断必须具有比外围中断更高的优先级(数值上更低)。否则,调用方 ISR 进程将被阻止。要更改 SysTick 中断优先级,您必须使用 HAL_NVIC_SetPriority() 函数。
应用程序需要确保 SysTick 时基始终设置为 1 毫秒,才能执行正确的 HAL 操作。 应用程序需要确保 SysTick 时基始终设置为 1 毫秒,才能执行正确的 HAL 操作。
每当应用程序使用 ITCM/DTCM 内存(@0x0000000 / @0x20000000:不可缓存,只能由 Cortex M7 和 GPDMA/HPDMA 访问)时,就不需要缓存维护。如果应用程序需要将 DMA 缓冲区放入 AXI SRAM 中(从 @0x24000000 开始),用户必须: 每当应用程序使用 ITCM/DTCM 内存(@0x0000000 / @0x20000000:不可缓存,只能由 Cortex M7 和 GPDMA/HPDMA 访问)时,无需缓存维护。如果应用程序需要将 DMA 缓冲区放入 AXI SRAM 中(从 @0x24000000 开始),用户必须:
在 MPU 和链接器配置文件中定义不可缓存区域以查找 DMA 缓冲区(CMSIS 设备链接器模板文件中提供了建议的 noncacheable_buffer 部分,其大小必须适应应用程序要求) 在 MPU 和链接器配置文件中定义不可缓存区域以查找 DMA 缓冲区(CMSIS 设备链接器模板文件中提供了建议的 noncacheable_buffer 部分,其大小必须适应应用程序要求)
或确保缓存维护操作,以确保 CPU 和 DMA 之间的缓存一致性。这也适用于 CPU 和其他主站(DMA2D、LTDC)访问的任何其他数据缓冲区。地址和可缓存缓冲区的大小(在 CPU 和其他 masters之间共享)必须正确定义,以便与数据缓存行大小(32 字节)保持一致,并且大小是此缓存行大小的倍数。请参阅 AN4838“在 STM32 MCU 中管理内存保护单元 (MPU)”。请参阅 AN4839 “STM32F7 系列上的 1 级缓存”。 或确保缓存维护操作,以确保 CPU 和 DMA 之间的缓存一致性。这也适用于 CPU 和其他主站(DMA2D、LTDC)访问的任何其他数据缓冲区。地址和可缓存缓冲区的大小(在 CPU 和其他 masters之间共享)必须正确定义,以便与数据缓存行大小(32 字节)保持一致,并且大小是此缓存行大小的倍数。请参阅 AN4838“在 STM32 MCU 中管理内存保护单元 (MPU)”。请参阅 AN4839 “STM32F7 系列上的 1 级缓存”。
针对核心代码: void MX_EXTMEM_MANAGER_Init(void)
{
/* USER CODE BEGIN MX_EXTMEM_Init_PreTreatment */
/* USER CODE END MX_EXTMEM_Init_PreTreatment */
HAL_RCCEx_DisableClockProtection(RCC_CLOCKPROTECT_XSPI);
/* Initialization of the memory parameters */
memset(extmem_list_config, 0x0, sizeof(extmem_list_config));
/* EXTMEMORY_1 */
extmem_list_config[0].MemType = EXTMEM_NOR_SFDP;
extmem_list_config[0].Handle = (void*)&hxspi2;
extmem_list_config[0].ConfigType = EXTMEM_LINK_CONFIG_8LINES;
EXTMEM_Init(EXTMEMORY_1, HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_XSPI2));
/* USER CODE BEGIN MX_EXTMEM_Init_PostTreatment */
/* USER CODE END MX_EXTMEM_Init_PostTreatment */
}
BootROM 模型基于从选定的易失性存储器中执行代码。当二进制数据存储在非内存映射模式的存储器(比SDCARD)中时,该执行模型非常适合。当二进制数据存储在低吞吐量的存储器(比如 SPI-NOR(使用单线 QSPI进行仿真))中时,此模型也适用。外部存储器启动应用程序基于 memory.h 文件中的用户配置对下列其中两个易失存储器进行配置:SDRAM、SRAM、PSRAM 或内部 SRAM。在该模型中,二进制数据从一个非易失性存储器复制到一个易失性存储器,然后由外部存储器启动应用程序执行。第二个易失性存储器用于数据。
下面的流程图说明了 BootROM 模型的操作流程:
附件文件为原理详细解读,会用即可,原理理解需要假以时日。
外部代码执行原理.pdf
(1.32 MB)
|