2025-04-07 5:57 AM
Hello there, I am working with STM32 TouchGFX with STM32L496ZG-P with AT25Q128A NOR Flash, using this setup my application is to fetch the large amount of data (touchGFX images) from the external flash (AT25Q128A NOR Flash) and to dump it inside the main mcu before the compilation. I created loader file using "Controllers Tech Tutorial" https://controllerstech.com/w25q-flash-series-part-10-qspi-ext-loader-in-h750/ . On inserting the external loader file in the debug configurations, by enabling the two check boxes of "Enable" and "Initialize" (refer to the image attached herewith) my HAL_delay() is not working, further i came to know that, it is because of not reception of the interrupt (so that the "uwTick" is not getting incremented) from the sysTick, but when i tried pressing the onboard reset button, the code continues execution specifically HAL_Delay() is also working, NOTE: When i pressed on board reset button, it starts executing from the point it stopped not from the starting (i.e. not from HAL_Init(), if my code stops at 3rd line HAL_Delay() normally it does not work, but when i press reset button, it starts executing from the 3rd line the control is getting out from the 3rd line and further delays present in the other lines also working). As i need to upload the huge amount of data into the core at the run time using external loader do i need to initialize. Kindly give me suggestions to 1. To make HAL_Delay() work even when i enabled the two check boxes of "enable" and "initialize" in the debug mode.
Hoping for responses.
Thank you,
Finally control is getting stuck inside the above function. the above code is debugged with HSI clock but for HSE also i am facing the same issue.
Solved! Go to Solution.
2025-04-12 7:14 AM
Ok, so calling the External Loader in this context is to allow the debugger to see into the 0x90000000 memory space *before* your own application code does this. ARM's model would be to bring it up SystemInit(), but ST does this much later in code they call from main().
At the end of the day, if the FLASH basis for you code is 0x08000000, then SCB->VTOR needs to equal 0x08000000
I'd use the Vector Table symbol to do this, but again ST does it with defines you have to fiddle with independently of linker, and linker script
Please use the </> icon to in-line code
extern uint32_t *g_pfnVector;
SCB->VTOR = (uint32_t)&g_pfnVectors[0]; // For FLASH, expect to be 0x08000000, or where you've placed it
2025-04-11 10:20 AM
If it's breaking your application, it's probably because you're disabling interrupts as you leave the loader..
Don't do that, or __enable_irq() in your main() function to get the MCU back into a normal operational state.
Perhaps add to your SystemInit() function, and check SCB->VTOR is correct
2025-04-12 1:11 AM
@Tesla DeLorean By using the __enable_irq(); at the main my code is getting into some signal handler with some address that i had attached below. Even using the enable_irq() at the system_init() i am still having the same issue
kindly help me out.
2025-04-12 4:48 AM - edited 2025-04-12 4:49 AM
Looks to be using the loader's vector table in RAM. Make sure SCB->VTOR points to your FLASH vector table for the application
2025-04-12 5:20 AM
Will try out and let you know @Tesla DeLorean , thanks
2025-04-12 5:36 AM
After Checking the SCB->VTOR whether it is mapping to the FLASH or not , kindly let me know am i supposed to uncomment the line 126 "/* #define USER_VECT_TAB_ADDRESS */" in the file "system_stm32l4xx.c" in the application code (not in the loader file generating project) so that the FLASH_BASE will map to the System_Init() function in the same file. Kindly refer to the below images.
Also could you let me know is it necessary to tick the checkbox of the "initialize" in the debug configuration, because previously i have referred to the response of https://community.st.com/t5/stm32-mcus-touchgfx-and-gui/custom-loaders-for-the-stm32l496-with-mt25ql128-quadspi-external/td-p/718723/page/2 author recommended to not to use in general, as i am using the loader file for touchGFX application for flashing the images to the core at the debug mode, i am bit confused whether to tick the check box or not. Once again thanks for your valuable response.
2025-04-12 7:14 AM
Ok, so calling the External Loader in this context is to allow the debugger to see into the 0x90000000 memory space *before* your own application code does this. ARM's model would be to bring it up SystemInit(), but ST does this much later in code they call from main().
At the end of the day, if the FLASH basis for you code is 0x08000000, then SCB->VTOR needs to equal 0x08000000
I'd use the Vector Table symbol to do this, but again ST does it with defines you have to fiddle with independently of linker, and linker script
Please use the </> icon to in-line code
extern uint32_t *g_pfnVector;
SCB->VTOR = (uint32_t)&g_pfnVectors[0]; // For FLASH, expect to be 0x08000000, or where you've placed it
2025-04-13 10:34 AM
Thanks a lot @Tesla DeLorean finally HAL_Delay(); got working!!. I have made the changes to two areas to make the HAL_Delay() work, 1. Locate the stm32l4xx_hal.c file under the folder <project_name>/core/src/stm32l4xx_hal.c and go to the line 126 and uncomment the line "#define USER_VECT_TAB_ADDRESS" and that's it. 2. Open the declaration of the HAL_Delay(); and use the function __enable_irq(); after the variable initializations. Justifications as follows, on using the external loader, the external memory is mapped as a internal flash so, at the System_init(); function definition (inside the same file of stm32l4xx_hal.c) SCB->VTOR expects the internal flash's location, which is further enabled by uncommenting the "#define VECT_TAB_ADDRESS" not define the QSPI_BASE to VECT_TAB_ADDRESS (because i tried it, it doesn't work, as it is only the starting address of the external memory, not sure we can use the VTOR over there).
When the external loader is used for application project, initially all the interrupts are disabled, to eliminate the context switching besides, disrupting the flash write sequence and corrupting the data, you can observe the line __set_PRIMASK(1); //disable interrupts (an ARM register which enables or disables all maskable interrupts except NMI, Hard Fault, Reset)in the loader_src.c file in the github repo of stm32 contrib branch https://github.com/STMicroelectronics/stm32-external-loader/blob/contrib/Loader_Files/other%20devices/Loader_Src.c#L58 so, Systick (a Maskable Interrupt) which is responsible for creating the HAL_Delay(); is disabled as a result of external loader usage, so we are supposed to enable the interrupts again, by using the function call "__enable_irq();" after the variable initializations inside the HAL_Delay()'s Function definition (press F3 or right click and select open declaration). Kindly let me know if there are any other approaches for this or any changes to be made in my justification