2026-02-04 11:21 PM
I'm currently using an STM32H7S78-DK, and I'm correctly able to run TouchGFX with FreeRTOS and everything. I also an error handler function that, in case of a crash of TouchGFX it writes directly to the framebuffer.
Now, I would like to do a similar thing but on the boot code, so basically before the classic jump if (BOOT_OK != BOOT_Application())
I have an external RAM mapped at the address 0x90000000 which works correctly in TouchGFX with .icf like
define symbol __region_EXTRAM_start__ = 0x90000000;
define symbol __region_EXTRAM_end__ = 0x91FFFFFF;
define region EXTRAM_region = mem:[from __region_EXTRAM_start__ to __region_EXTRAM_end__];
place in EXTRAM_region { first section TouchGFX_Framebuffer
, section Video_RGB_Buffer
, section Nemagfx_Stencil_Buffer };I wanted to use the same section of memory in the Boot, accessing the framebuffer directly, so I edited the .icf of the boot with
define symbol __region_EXTRAM_start__ = 0x90000000;
define symbol __region_EXTRAM_end__ = 0x91FFFFFF;
define region EXTRAM_region = mem:[from __region_EXTRAM_start__ to __region_EXTRAM_end__];
place in EXTRAM_region { first section Boot_Framebuffer };And in the main.c
#pragma location = "Boot_Framebuffer"
__no_init uint32_t frameBuf[(800 * 480 * 2 + 3) / 4 * 2];Using J-Link and IAR, during the debug, I'm seeing the frameBuf is correctly mapped from address 0x90000000 but, as soon as I try to access the memory address, for instance wiping the frameBuf with
memset((void*)frameBuf, 0, sizeof(frameBuf));The code goes into HardFault. I have set the correct address for the LTDC with
LTDC_Layer1->CFBAR = (uint32_t)frameBuf;
LTDC->SRCR = (uint32_t)LTDC_SRCR_IMR;and I'm correctly initializing the XSPI as they return HAL_OK
MX_XSPI1_Init(); // External flash
MX_XSPI2_Init(); // External PSRAMI've alos configured the MPU region for the EXT RAM with
static void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32MB;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}I suspect that the CPU does not have the address of the external RAM mapped in its internal registries; could it be? Is there a way to access this frame buffer and read/write it to/from the external RAM
Solved! Go to Solution.
2026-02-05 2:31 AM
The issue seemed to be that in the MX_EXTMEM_MANAGER_Init it wasn't defined
if (EXTMEM_MemoryMappedMode(EXTMEMORY_2, EXTMEM_ENABLE) != EXTMEM_OK)
{
Error_Handler();
}
2026-02-04 11:48 PM
> .. as soon as I try to access the memory address, for instance wiping the frameBuf with ... The code goes into HardFault.
This is to be expected.
External busses (and external RAM attached to it) need to be initialized before you can access it.
This is usually done in the context of the SystemInit() function, located in system_stm32xxxx.c.
So you most probably need to find and replicate this code in your bootloader.
2026-02-05 12:07 AM - edited 2026-02-05 12:45 AM
Hi @Ozone
thanks for pointing it out; I didn't know it.
I've just checked my system_stm32h7rsxx.c
and I'm seeing the
void SystemInit(void)
{
/* Configure the Vector Table location -------------------------------------*/
SCB->VTOR = INTVECT_START;
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */
#endif
}Also, in the startup_stm32h7rsxx.s it is called like
THUMB
PUBWEAK Reset_Handler
SECTION .text:CODE:NOROOT:REORDER(2)
Reset_Handler
LDR R0, =SystemInit
BLX R0
LDR R0, =__iar_program_start
BX R0Do I just need to call the SystemInit function from my main() in the Boot?
Also, in the boot the memory manager is initialized
/**
* Init External memory manager
* @retval None
*/
void MX_EXTMEM_MANAGER_Init(void)
{
/* USER CODE BEGIN MX_EXTMEM_Init_PreTreatment */
/* USER CODE END MX_EXTMEM_Init_PreTreatment */
HAL_RCCEx_EnableClockProtection(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;
/* EXTMEMORY_2 */
extmem_list_config[1].MemType = EXTMEM_PSRAM;
extmem_list_config[1].Handle = (void*)&hxspi1;
extmem_list_config[1].ConfigType = EXTMEM_LINK_CONFIG_16LINES;
extmem_list_config[1].PsramObject.psram_public.MemorySize = HAL_XSPI_SIZE_256MB;
extmem_list_config[1].PsramObject.psram_public.FreqMax = 200 * 1000000u;
extmem_list_config[1].PsramObject.psram_public.NumberOfConfig = 1u;
/* Config */
extmem_list_config[1].PsramObject.psram_public.config[0].WriteMask = 0x40u;
extmem_list_config[1].PsramObject.psram_public.config[0].WriteValue = 0x40u;
extmem_list_config[1].PsramObject.psram_public.config[0].REGAddress = 0x08u;
/* Memory command configuration */
extmem_list_config[1].PsramObject.psram_public.ReadREG = 0x40u;
extmem_list_config[1].PsramObject.psram_public.WriteREG = 0xC0u;
extmem_list_config[1].PsramObject.psram_public.ReadREGSize = 2u;
extmem_list_config[1].PsramObject.psram_public.REG_DummyCycle = 4u;
extmem_list_config[1].PsramObject.psram_public.Write_command = 0xA0u;
extmem_list_config[1].PsramObject.psram_public.Write_DummyCycle = 4u;
extmem_list_config[1].PsramObject.psram_public.Read_command = 0x20u;
extmem_list_config[1].PsramObject.psram_public.WrapRead_command = 0x00u;
extmem_list_config[1].PsramObject.psram_public.Read_DummyCycle = 4u;
EXTMEM_Init(EXTMEMORY_1, HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_XSPI2));
EXTMEM_Init(EXTMEMORY_2, HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_XSPI1));
/* USER CODE BEGIN MX_EXTMEM_Init_PostTreatment */
/* USER CODE END MX_EXTMEM_Init_PostTreatment */
}It seems that, when I try to debug the App, the memory is already attached and working, as TouchGFX is easily using it, when debugging the Boot, it doesn't work
2026-02-05 2:31 AM
The issue seemed to be that in the MX_EXTMEM_MANAGER_Init it wasn't defined
if (EXTMEM_MemoryMappedMode(EXTMEMORY_2, EXTMEM_ENABLE) != EXTMEM_OK)
{
Error_Handler();
}