cancel
Showing results for 
Search instead for 
Did you mean: 

CUSTOM BOOTLOADER

Vishwajeet
Associate

 

ISSUE: STM32F7 Custom Bootloader - Main Application Not Running After Jump
Details:
Bootloader Memory Definition:
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
QUADSPI (r) : ORIGIN = 0x90000000, LENGTH = 16M
Application Memory Definition:
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K

FLASH (rx) : ORIGIN = 0x8020000, LENGTH = 896K

QUADSPI (r) : ORIGIN = 0x90000000, LENGTH = 16M

Validation Points:
Bootloader erase & write operations are working correctly.
Custom bootloader successfully writes the application code to both internal and external segments.
A test application that prints text ("I am application") works properly after jumping from the bootloader.


Debug points :

1 > memory utilization by main application

 

RAM : ORIGIN = 0x20000000, utilization = 320 K

FLASH : ORIGIN = 0x8020000, utilization = 896 K

QUADSPI : ORIGIN = 0x90000000, utilization = 5.18 M

 

2 > Jump steps after writing application (by custom bootloader)

/*********************************************************************************************
if(gParsePacketData.data[0] == BOOT_STATUS)
{

#define APP_ADDRESS  0x08020000 
typedef void (*pFunction)(void);
pFunction JumpToApplication;
uint32_t JumpAddress;
int Temp = 0 ;
vc_prepare_packet_and_send(&huart6,FEEDBACK_COMMAND,FEEDBACK_SUCCESS,&Temp,sizeof(Temp));


// Disable interrupts
    __disable_irq();

    // Deinitialize peripherals and clocks if needed

    // Set vector table to application address
    SCB->VTOR = APP_ADDRESS;

    // Read the application's stack pointer address
    __set_MSP(*(volatile uint32_t*)APP_ADDRESS);

    // Get the application's reset vector (entry point)
    JumpAddress = *(volatile uint32_t*) (APP_ADDRESS + 4);
    JumpToApplication = (pFunction) JumpAddress;

    // Enable interrupts (optional, the application should handle it)
    __enable_irq();

    // Jump to application
    JumpToApplication();
/**********************************************************************************/

We would be grateful for any guidance or suggestions you can provide.

1 ACCEPTED SOLUTION

Accepted Solutions

> The jump function works correctly when the application is downloaded using the STM32 Programming Utility, but it fails when the main application is downloaded via my custom application.

Suggests the bug is in your application download. Compare the flash between the two methods to find out what is different.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

10 REPLIES 10
Karl Yamashita
Principal
  1. find system_stm32f7xx.c file
  2. Uncomment this define
  3. Change value to your application address

 

KarlYamashita_0-1740554407540.png

 

Don't worry, I won't byte.
TimerCallback tutorial! | UART and DMA Idle tutorial!

If you find my solution useful, please click the Accept as Solution so others see the solution.

Vishwajeet_0-1740554948571.png

Vishwajeet_1-1740554977566.png

Thank you for your valuable reply, but the changes have already been made and tested.

SSten.1705
Associate

I am using a bootloader that checks checksum and jumps to it, using struct and code below. Make sure not to have any DMA or interrupts being active when jumping.

// Struct for relaxed addressing
typedef struct
{
   void *stack;					//0
   void (* appentry)(void);		//1
   u32 pad[5]; 					//2 3 4 5 6	
   void (* frestrict)(int code); 	//7
   u32  checksum;				//8
   u32  flashend; 				//9
   u32  version;				//10  0x08000028
} APPINFO;

// jump to application if valid
// called also after successfull firmware upgrade 

#define APPSTART 0x08020000

void checkapp(bool reset)
{
	u32 xs = 0;
	
	const u32 *bin = (u32 *)(APPSTART);
	
	const APPINFO *ai = (APPINFO *)bin;

	u32 fend = ai->flashend;
	
	if((fend <  APPSTART) || (fend > 0x080E0000) )	return;	// should be reasonable, last sector for storage?
	
	while(bin < (u32 *)fend) xs += *bin++;
		
	if(xs == 0)
	{
		if(reset) ResetPeriph();
		ai->appentry(); 					// bye!
	}
}

I am  

On the app side, I would avoid doing any system clock (RCC) re-initialization, or that of the pins and the QSPI / External memory interfaces that the loader has already brought up to operational status.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
TDK
Guru

> A test application that prints text ("I am application") works properly after jumping from the bootloader.

If a test application works, but your main app doesn't, doesn't that suggest a bug with your main application? Certainly it means the jump is working as intended.

Debug the code, let the jump happen, pause the code and examine the state of the system. Could be that you're in an interrupt that now points to an invalid location. You don't actually disable any interrupts. Only temporarily.

How to jump to system bootloader from application ... - STMicroelectronics Community

If you feel a post has answered your question, please click "Accept as Solution".

Prioritize getting working HardFault_Handler() and Error_Handler() in both loader and app, that can give visible and definitive information if they arrive there. For the latter a source file and line would help pin things down quickly.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

void Bootloader_JumpToApp()

{

#define FLASH_APP_START_ADDRESS 0x8020000

typedef void (*fnc_ptr)(void);

 

memset(msg,0,sizeof(msg));

 

strcpy(msg,"going to application...");

 

HAL_UART_Transmit(&huart6, (uint8_t *)msg, strlen(msg), 1000);

 

/* Function pointer to the address of the user application. */

fnc_ptr jump_to_app;

jump_to_app = (fnc_ptr)(*(volatile uint32_t*) (FLASH_APP_START_ADDRESS+4u));

 

__disable_irq();

 

SysTick->CTRL = 0;

 

HAL_RCC_DeInit();

 

HAL_DeInit();

 

/* Disable SysTick */

 

SysTick->CTRL = 0;

 

SysTick->LOAD = 0;

 

SysTick->VAL = 0;

 

__enable_irq();

 

//HAL_DeInit();

/* Change the main stack pointer. */

__set_MSP(*(volatile uint32_t*)FLASH_APP_START_ADDRESS);

 

jump_to_app();

}

Issue Description:
I have developed a custom bootloader for an STM32F7 microcontroller that programs the main application via UART. My bootloader includes a button to jump to the main application. The jump function works correctly when the application is downloaded using the STM32 Programming Utility, but it fails when the main application is downloaded via my custom application.

I have verified that the application is downloaded correctly when programmed through my custom application, and no issues were found with the flashing process.

Bootloader Peripherals Used:
UART1 – Communication with PC
UART6 – Logging/debugging
QSPI APIs – Writing to the external flash segment
Main Application Peripherals:
Touch Screen, UART, SPI, GPIO, and other peripherals

JJhin.1
Senior II

Try this jump code:

void Jump_To_User_Application(void)
{

    // check if valid code is present on Application sector
  
    if((((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0xFF000000 ) == 0x20000000) || \
      (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0xFF000000 ) == 0x10000000))
    {
      JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);        // Take jump address from application sector
      Jump_To_Application = (pFunction) JumpAddress;

      /***************** Deinitialized every thing***************************/
      HAL_RCC_DeInit();
      HAL_DeInit();
    /* // This Commented part needed when if we are using timer or other interrupts
         for(int i=0;i<8;i++)
         {
           NVIC->ICER[ i ] = 0xFFFFFFFF ;
           NVIC->ICPR[ i ] = 0xFFFFFFFF ;
         }

         SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk ;
    
         SCB->SHCSR &= ~( SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk | SCB_SHCSR_MEMFAULTENA_Msk ) ;
    */		 
      SysTick->CTRL = 0;
      SysTick->LOAD = 0;
      SysTick->VAL  = 0;
      /******************Deinitialization end**********************************/
      SCB->VTOR = APPLICATION_ADDRESS;                                  // Change Vector Table address with user application address
			 
      __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);                 // Set Main Stack Pointer to User Application address location
      Jump_To_Application();                                            // Jump to application usinf pFunction
    }
  
}	

> The jump function works correctly when the application is downloaded using the STM32 Programming Utility, but it fails when the main application is downloaded via my custom application.

Suggests the bug is in your application download. Compare the flash between the two methods to find out what is different.

If you feel a post has answered your question, please click "Accept as Solution".