Friday, 9 August 2019

stm32 - STM32F091 Jump to Bootloader from application


I'm trying to implement a jump to the STM32F091 USART1 bootloader from my application.


I'm using the following function(based on https://community.st.com/thread/40238-stm32l476rg-jump-to-bootloader-from-software):


void SB_SystemBootloaderJump()

{
typedef void (*pFunction)(void);
pFunction JumpToApplication;

HAL_RCC_DeInit();

SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;


/**
* Step: Disable all interrupts
*/
__disable_irq();

/* ARM Cortex-M Programming Guide to Memory Barrier Instructions.*/
__DSB();

// __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH()
// ;


// /* Remap is bot visible at once. Execute some unrelated command! */
// __DSB();
// __ISB();

JumpToApplication = (void (*)(void)) (*((uint32_t *) ((0x1FFFD800 + 4))));

/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) 0x1FFFD800);


JumpToApplication();
}

From APP Note AN2606: System Memory address as in picture: https://i.imgur.com/nVcgoBg.png


From SWD Utility, memory contents at System Memory: https://i.imgur.com/PeepkrX.png


From Debugger, SP and Reset handler as picture: https://i.imgur.com/PagQng0.png


Program execution up to breakpoint at Bootloader address : https://i.imgur.com/koKfObe.png


Considering: A - Using a jumper to VCC on BOOT0 pin, I can successfully access the system bootloader via STM32 Flash Loader Demo. The same is not true if I jump to the bootloader from my app. B - I'm using a FTDI FT230x USBxSerial Bridge.


Questions:


1 - Since I'm using the absolute system memory address, there is no need to use __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(). Correct?



2 - Am I missing something on this function?


3 - Is there a timeout between the bootloader starting and receiving the "0x7F" byte on USART1?


4 - Will opening/closing the serial port affect the bootloader? Do I have to reset the MCU if I close the serial port and open it again?



Answer



The problem was with the USART1 peripheral state. The USART1 config register values were being carried to the bootloader execution, possibly causing trouble for the proprietary bootloader. Solution was to reset USART1 via RCC_APB2RSTR.


The function now is:


void SB_SystemBootloaderJump()
{
typedef void (*pFunction)(void);
pFunction JumpToApplication;


__HAL_RCC_USART1_FORCE_RESET();
HAL_Delay(5);
__HAL_RCC_USART1_RELEASE_RESET();
HAL_Delay(5);

HAL_RCC_DeInit();

SysTick->CTRL = 0;
SysTick->LOAD = 0;

SysTick->VAL = 0;

/**
* Step: Disable all interrupts
*/
__disable_irq();

/* ARM Cortex-M Programming Guide to Memory Barrier Instructions.*/
__DSB();


__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH()
;

/* Remap is bot visible at once. Execute some unrelated command! */
__DSB();
__ISB();

JumpToApplication = (void (*)(void)) (*((uint32_t *) ((0x1FFFD800 + 4))));

/* Initialize user application's Stack Pointer */

__set_MSP(*(__IO uint32_t*) 0x1FFFD800);

JumpToApplication();
}

No comments:

Post a Comment

arduino - Can I use TI's cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...