How to jump into app from bootloader ,52833?

I wrote a bootloader code. The flash space range of bootloader is 0x27000-0x3b000, and the flash space of app is 0x3b000-0x80000, but the app doesn't work. What's the problem?

My project consists of STM32 + 4G + nrf52833. When the 52833 firmware needs to be updated, the cloud service will send the 52833 firmware to STM32, and then STM32 will send the firmware to 52833 through the UART interface.

sdk:nRF5_SDK_17.0.2_d674dde

The flash distribution framework is as follows:

 bootloader:

typedef  void (*iapfun)(void);				
#define FLASH_APP1_ADDR		0x3B000			//app code start address
iapfun jump2app;
__asm void MSR_MSP(uint32_t addr) 
{
	MSR MSP, r0 							//set Main Stack value
	BX r14
}

//Jump to application segment
//appxaddr:app code start address
void iap_load_app(uint32_t appxaddr)
{
	jump2app=(iapfun)*(uint32_t*)(appxaddr+4);			//The second word in the user code area is the program start address (reset address)	

	#if 1
		MSR_MSP(*(uint32_t*)appxaddr);					//Initialize the app stack pointer ,(the first word in the user code area is
	#else												//used to store the stack top address)
		__set_MSP(appxaddr);
	#endif
	
	jump2app();									    	//jump to APP.
}		 


timer_out_st timer_period;
void handle_period_event(void)
{
	static uint32_t jump_to_app_timer = 0, pir_detect_ok_num = 0;
	static uint8_t dataW,dataR;
	if(!IsTimeOut(&timer_period)) return;
	TimeOutSet(&timer_period,10);
	
	mcu_led_set();

	if(++jump_to_app_timer > 300)
	{
		jump_to_app_timer=0;
	
		{	 
			printf("jump to app,0x3B000=%08x\n",*(uint32_t*)(FLASH_APP1_ADDR));
			nrf_delay_ms(100);

			// Turn off the peripherals used 
			uart_close(0);
			uart_close(1);
			sk_timer_set(0);
			iap_load_app(FLASH_APP1_ADDR);						
		}

		// This information will not be printed if it works properly
		printf("***err to jump app\n");
	}
}

app:

SCB->VTOR =  0x3B000;				// remap interrupt vector table address

  • hi,

    Referring to the example of [nrf5_sdk_17.0.2_52833 \ nrf5_sdk_17.0.2_d674dde \ examples \ DFU] nrf_bootloader_app_start() api, I added the following code to the bootloader code,  the app code that enables the ble function cannot work.

    #if 1
    sd_mbr_command_t command =
    {
    .command = SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET,
    .params.irq_forward_address_set.address = FLASH_APP1_ADDR,
    };

    sd_mbr_command(&command);
    #endif

    void jump_app(void)
    {
    	const uint32_t current_isr_num = (__get_IPSR() & IPSR_ISR_Msk);
    	
    	// The app's Stack Pointer is found as the first word of the vector table.
    	const uint32_t new_msp		   = *((uint32_t *)(FLASH_APP1_ADDR));		
    
    	// The app's Reset Handler is found as the second word of the vector table.
    	const uint32_t reset_handler   = *((uint32_t *)(FLASH_APP1_ADDR + sizeof(uint32_t))); 
    
    
    	__set_CONTROL(0x00000000);   // Set CONTROL to its reset value 0.
    	__set_PRIMASK(0x00000000);   // Set PRIMASK to its reset value 0.
    	__set_BASEPRI(0x00000000);   // Set BASEPRI to its reset value 0.
    	__set_FAULTMASK(0x00000000); // Set FAULTMASK to its reset value 0.
    
    
    	NVIC->ICER[0]=0xFFFFFFFF;
    	NVIC->ICPR[0]=0xFFFFFFFF;
    ////    NVIC->ICER[1]=0xFFFFFFFF;
    ////    NVIC->ICPR[1]=0xFFFFFFFF;
    ////
    ////	// If this is triggered, the CPU is currently in an interrupt.
    ////	ASSERT(current_isr_num == 0); 
    
    
    #if 1
    	sd_mbr_command_t command =
    	{
    		.command = SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET,
    		.params.irq_forward_address_set.address = FLASH_APP1_ADDR,
    	};
    
    	sd_mbr_command(&command);
    #endif
    
    
    	// The CPU is in Thread mode (main context).
    	// Jump directly to the App's Reset Handler.
    	jump_to_addr(new_msp, reset_handler); 
    }
    
    

    In devzone, I see many people have the same problem, but unfortunately, there is no solution.

    thanks again.

  • Hi,

    Please take a look at the nrf_bootloader_app_start() implementation from SDK 14.2 again. You are missing some important parts, and the order is wrong. This function does exactly what you need in this case, and so you should do the same.

Related