2026-02-16 5:56 AM - last edited on 2026-02-16 5:58 AM by Andrew Neil
Hi everyone, I'm having trouble jumping to the app from the bootloader.
The application is located here, writing doesn't give me errors. So I assume the problem is Jump.
#define FLASH_USER_START_ADDR ADDR_FLASH_SECTOR_2_BANK1Il main del bootloader è costituito così
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* 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();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_QUADSPI_Init();
MX_SPI4_Init();
MX_I2C1_Init();
MX_RTC_Init();
MX_FMC_Init();
MX_USART6_UART_Init();
/* USER CODE BEGIN 2 */
HAL_GPIO_WritePin(ENABLE_3v3_WIFIPRINTER_uC_GPIO_Port, ENABLE_3v3_WIFIPRINTER_uC_Pin, GPIO_PIN_SET);
printf("\n\n*****START MAIN Bootloader *****\n\n");
if (!USB_VBUS_Present())
{
DebugApplicationHeader();
JumpToUserApplication();
}
.
.
.With
void DebugApplicationHeader(void)
{
printf("\n=== APPLICATION HEADER DUMP ===\n");
printf("Reading from: 0x%08lX\n", FLASH_USER_START_ADDR);
uint32_t *app = (uint32_t*)FLASH_USER_START_ADDR;
// Primi 16 vettori
for(int i = 0; i < 16; i++)
{
printf("[%2d] 0x%08lX: 0x%08lX", i, FLASH_USER_START_ADDR + (i*4), app[i]);
// Aggiungi descrizione
if(i == 0) printf(" <- Initial SP");
else if(i == 1) printf(" <- Reset Handler");
else if(i == 2) printf(" <- NMI");
else if(i == 3) printf(" <- HardFault");
printf("\n");
}
// Verifica se � tutto 0xFF (flash vuota)
bool isEmpty = true;
for(int i = 0; i < 64; i++)
{
if(app[i] != 0xFFFFFFFF && app[i] != 0x00000000)
{
isEmpty = false;
break;
}
}
if(isEmpty)
{
printf("\n WARNING: Flash appears empty or erased!\n");
}
printf("================================\n\n");
}
void JumpToUserApplication(void)
{
uint32_t appStack = *(__IO uint32_t*)FLASH_USER_START_ADDR;
uint32_t appEntry = *(__IO uint32_t*)(FLASH_USER_START_ADDR + 4);
// 1. Validazione
if (((appStack & 0x2FF00000) != 0x20000000) && ((appStack & 0x2FF00000) != 0x24000000))
{
printf("ERROR: Invalid application at 0x%08lX\n", FLASH_USER_START_ADDR);
return;
}
// 2. Debug
printf("Jumping to application at 0x%08lX\n", FLASH_USER_START_ADDR);
printf("SP: 0x%08lX, PC: 0x%08lX\n", appStack, appEntry);
HAL_Delay(50);
// 3. Disabilita interrupt
printf("Disabling IRQ...\n");
HAL_Delay(10);
__disable_irq();
printf("IRQ disabled\n"); // Questo potrebbe non stampare
// 4. Disabilita SysTick
printf("Disabling SysTick...\n");
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
printf("SysTick disabled\n");
// 5. Cache - PUNTO CRITICO
printf("Disabling I-Cache...\n");
SCB_DisableICache();
printf("I-Cache disabled\n");
printf("Disabling D-Cache...\n");
// SCB_DisableDCache();
printf("D-Cache disabled\n");
printf("Invalidating I-Cache...\n");
SCB_InvalidateICache();
printf("I-Cache invalidated\n");
printf("Invalidating D-Cache...\n");
// SCB_InvalidateDCache();
printf("D-Cache invalidated\n");
// 6. MPU
printf("Checking MPU...\n");
if (SCB->SHCSR & SCB_SHCSR_MEMFAULTENA_Msk)
{
printf("Disabling MPU...\n");
HAL_MPU_Disable();
printf("MPU disabled\n");
}
else printf("MPU not active\n");
// 7. NVIC
printf("Clearing NVIC...\n");
for (uint32_t i = 0; i < 8; i++)
{
NVIC->ICER[i] = 0xFFFFFFFF;
NVIC->ICPR[i] = 0xFFFFFFFF;
}
printf("NVIC cleared\n");
// 8. Deinit periferiche
// printf("Deinit UART...\n");
HAL_UART_DeInit(&huart6);
HAL_SPI_DeInit(&hspi4);
HAL_QSPI_DeInit(&hqspi);
HAL_I2C_DeInit(&hi2c1);
HAL_RTC_DeInit(&hrtc);
HAL_SDRAM_DeInit(&hsdram1);
// Dopo questo punto le printf non funzioneranno pi�!
// 9. HAL Deinit
HAL_DeInit();
// printf("Hal DeInit\n");
// 10. VTOR
SCB->VTOR = FLASH_USER_START_ADDR;
// printf("VTOR \n");
// 11. MSP
__set_MSP(appStack);
// printf("MSP\n");
// 12. Control
__set_CONTROL(0);
// printf("CONTROL\n");
// 13. Barriere
__DSB();
// printf("DSB\n");
__ISB();
// 14. JUMP!
// printf("Pre JUMP\n");
JumpToApplication = (pFunction)appEntry;
// printf("JUMP\n");
JumpToApplication();
// printf("After Jump\n");
}these are the prints instead
=== APPLICATION HEADER DUMP ===
Reading from: 0x08040000
[ 0] 0x08040000: 0x24064AB8 <- Initial SP
[ 1] 0x08040004: 0x08040371 <- Reset Handler
[ 2] 0x08040008: 0x0804B49D <- NMI
[ 3] 0x0804000C: 0x08048AEB <- HardFault
[ 4] 0x08040010: 0x0804B0AD
[ 5] 0x08040014: 0x08042105
[ 6] 0x08040018: 0x08050D29
[ 7] 0x0804001C: 0x00000000
[ 8] 0x08040020: 0x00000000
[ 9] 0x08040024: 0x00000000
[10] 0x08040028: 0x00000000
[11] 0x0804002C: 0x080402B1
[12] 0x08040030: 0x080427CD
[13] 0x08040034: 0x00000000
[14] 0x08040038: 0x0804030D
[15] 0x0804003C: 0x0804E0E5
================================
Jumping to application at 0x08040000
SP: 0x24064AB8, PC: 0x08040371
Disabling IRQ...
IRQ disabled
Disabling SysTick...
SysTick disabled
Disabling I-Cache...
I-Cache disabled
Disabling D-Cache...
D-Cache disabled
Invalidating I-Cache...
I-Cache invalidated
Invalidating D-Cache...
D-Cache invalidated
Checking MPU...
MPU not active
Clearing NVIC...
NVIC clearedHow can I correct this?
Solved! Go to Solution.
2026-02-16 8:07 AM
I solved it by moving the application start to sector 3 (0x08060000)
2026-02-16 7:07 AM
Hello,
This knowledge base may help you: How to jump to system bootloader from application code on STM32 microcontrollers
2026-02-16 7:36 AM - edited 2026-02-16 7:37 AM
Thanks for the reply, Meallem, but the shared thread mentions the application jump at bootloader. I need the opposite. I also added that I previously had to port from SMT32F7 to STm32H7. On the SMT32F7, I managed the application jump the same way, and it worked. Are there things that need to be implemented differently?
I use the same strategy to jump to the application on the SMT32L4, and I'm having no problems.
2026-02-16 8:07 AM
I solved it by moving the application start to sector 3 (0x08060000)