on
2024-01-19
06:35 AM
- edited on
2024-06-27
01:01 AM
by
Laurids_PETERSE
This article presents a quick guidance on how to prevent HardFault occurrences when the ICACHE is enabled on the STM32H5 MCU.
This article explains why a HardFault may occur when accessing the following:
The internal reference voltage (VREFINT), the internal temperature sensor (VSENSE), the unique device ID, and the package ID data are located in RO and OTP areas.
By default, all the AHB memory range is cacheable. For OTP and RO regions, caching is not practical and MPU has to be used to disable local cacheability.
The embedded flash memory offers a 2-Kbyte memory area to store read-only data. This area is mapped as described in the below table:
OTP data is organized as 32 blocks of 32 OTP words, as shown in the below table:
It is also important to note that for 8-bit accesses, an AHB bus error is generated. For OTP and RO sectors in memory, a 6-bit ECC code is associated with each 16-bit data flash word. So, the embedded flash memory supports only16-bit or 32-bit write operations. Therefore, the burst access is not supported for these regions.
You can refer to the following MPU configuration to disable cacheability for OTP and RO regions
#include "stm32h5xx_hal.h"
void MPU_Config(void);
/* MPU attribute setting */
#define DEVICE_nGnRnE 0x0U /* Device, noGather, noReorder, noEarly acknowledge. */
#define DEVICE_nGnRE 0x4U /* Device, noGather, noReorder, Early acknowledge. */
#define DEVICE_nGRE 0x8U /* Device, noGather, Reorder, Early acknowledge. */
#define DEVICE_GRE 0xCU /* Device, Gather, Reorder, Early acknowledge. */
#define WRITE_THROUGH 0x0U /* Normal memory, write-through. */
#define NOT_CACHEABLE 0x4U /* Normal memory, non-cacheable. */
#define WRITE_BACK 0x4U /* Normal memory, write-back. */
#define TRANSIENT 0x0U /* Normal memory, transient. */
#define NON_TRANSIENT 0x8U /* Normal memory, non-transient. */
#define NO_ALLOCATE 0x0U /* Normal memory, no allocate. */
#define W_ALLOCATE 0x1U /* Normal memory, write allocate. */
#define R_ALLOCATE 0x2U /* Normal memory, read allocate. */
#define RW_ALLOCATE 0x3U /* Normal memory, read/write allocate. */
#define OUTER(__ATTR__) ((__ATTR__) << 4U)
#define INNER_OUTER(__ATTR__) ((__ATTR__) | ((__ATTR__) << 4U))
/**
* @brief Configure the MPU attributes.
* @note The Base Address is RO area
* None
* @retval None
*/
void MPU_Config(void)
{
MPU_Attributes_InitTypeDef attr;
MPU_Region_InitTypeDef region;
/* Disable MPU before perloading and config update */
HAL_MPU_Disable();
/* Define cacheable memory via MPU */
attr.Number = MPU_ATTRIBUTES_NUMBER0;
attr.Attributes = INNER_OUTER(NOT_CACHEABLE);
HAL_MPU_ConfigMemoryAttributes(&attr);
/* BaseAddress-LimitAddress configuration */
region.Enable = MPU_REGION_ENABLE;
region.Number = MPU_REGION_NUMBER0;
region.AttributesIndex = MPU_ATTRIBUTES_NUMBER0;
region.BaseAddress = 0x08FFF800;
region.LimitAddress = 0x08FFFFFF;
region.AccessPermission = MPU_REGION_ALL_RW;
region.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
region.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
HAL_MPU_ConfigRegion(®ion);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
void MX_ICACHE_Init(void)
{
/* USER CODE BEGIN ICACHE_Init 0 */
/* USER CODE END ICACHE_Init 0 */
/* USER CODE BEGIN ICACHE_Init 1 */
/* USER CODE END ICACHE_Init 1 */
/** Enable instruction cache in 1-way (direct mapped cache)
*/
if (HAL_ICACHE_ConfigAssociativityMode(ICACHE_1WAY) != HAL_OK)
{
Error_Handler();
}
if (HAL_ICACHE_Enable() != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ICACHE_Init 2 */
/* USER CODE END ICACHE_Init 2 */
}
The STM32H503xx microcontrollers features an integrated ICACHE that combines instructions and data into a single cache. This cache is introduced on the C-AHB code bus of the Cortex®-M33 processor. This is to improve performance when fetching instructions (or data) from internal memories (SRAM1 and SRAM2).
The STM32H562xx, STM32H563xx, and STM32H573xx microcontrollers features:
Using the term "ICACHE" for this was a quintessentially horrible idea. Thanks for the permanent confusion!
Going to back link to failure examples to help search/index
I've read this 3 times back and forth but still cannot understand ((
So, does the ICACHE in H503xx mean Integrated or Instruction cache?
And why exactly it causes a fault when accessing the RO & OTP area?
The "128-bit cacheline refill" probably is the burst operation mentioned in the article. But how is it related to 8-bit access vs. 16 or 32 bit? Does it mean that any access, even 32 bit, to this area triggers the cacheline load?
How about the main flash array - is cacheline refill OK there?
Finally why in the example code access is RW and not RO? are we going to write there?
region.AccessPermission = MPU_REGION_ALL_RW;
I'm pretty sure it's "integrated". Beyond that it looks like an integrated mess.