2021-10-25 07:18 AM
Hi,
I am working on STM32L072CZY3TR controller. i performed the dfu using boot switch on the device but my requirement is to perform DFU on my device without using boot switch and enter in to boot mode from user application.is it possible from user app?i found some code on the internet for this but it doesn't seem to be working.Can some one help on this.below is the code i am using for this.i am calling this function when i want to run in boot mode. Is there something that i am missing here?Please help
TIA,
Bipin
#define STACK_PTR_ADDR 0xD0140020 /*referred from memory presentation in STM32cubeide*/
#define BOOTLOADER_SA 0x1FF00004 /*referred from application note*/
extern osThreadId_t CntrlTaskHandle;
extern osThreadId_t HostTxTaskHandle;
extern osThreadId_t SensorTaskHandle;
void (*SysMemBootJump) (void);
void BootLoaderInit(void);
void BootLoaderInit(void)
{
SysMemBootJump = (void (*)(void)) (*((unsigned long *) 0x1ff00004));
vTaskDelete(CntrlTaskHandle);
vTaskDelete(HostTxTaskHandle);
vTaskDelete(SensorTaskHandle);
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
HAL_RCC_DeInit();/*Resets the RCC clock configuration to the default reset state.*/
__disable_irq();/*disable IRQ*/
__set_MSP(STACK_PTR_ADDR);/*set stack pointer address*/
SysMemBootJump();/*jump to bootloader*/
NVIC_SystemReset();
}
2021-10-25 07:52 AM
At a minimum, you will need to have interrupts enabled. Instead of globally disabling them, disable them at the peripheral level and reset any peripherals you've initialized. You can disable them globally temporarily similar to:
https://community.st.com/s/article/STM32H7-bootloader-jump-from-application
STACK_PTR_ADDR looks wrong and probably should be 0x1FF00000.
You might need to exit the FreeRTOS scheduler to perform the jump so you're not jumping from within an interrupt.
2021-10-25 11:00 PM
Thanks for the response!
I did the changes according to suggestions but not sure whether its going in bootloader or not. How will i come to know that device is in bootloader now?(will it show my device name as "stm in dfu mode " under usb device in device manager?)After that how can i upgrade the FW using USB?
Thanks!,
Bipin
2021-10-26 02:52 AM
Update-this is the code i was using earlier-
void BootLoaderInit(void)
{
uint32_t i=0;
void (*SysMemBootJump)(void);
// vTaskDelete(CntrlTaskHandle);
// vTaskDelete(HostTxTaskHandle);
// vTaskDelete(SensorTaskHandle);
// vTaskEndScheduler();
// osKernelSuspend();
/* Set the address of the entry point to bootloader */
volatile uint32_t BootAddr = 0x1FF00000;
/* Disable all interrupts */
__disable_irq();
/* Disable Systick timer */
SysTick->CTRL = 0;
/* Set the clock to the default state */
HAL_RCC_DeInit();
/* Clear Interrupt Enable Register & Interrupt Pending Register */
for (i=0;i<5;i++)
{
NVIC->ICER[i]=0xFFFFFFFF;
NVIC->ICPR[i]=0xFFFFFFFF;
}
SCB->ICSR = 0;
/* Re-enable all interrupts */
__enable_irq();
/* Set up the jump to booloader address + 4 */
SysMemBootJump = (void (*)(void)) (*((uint32_t *) ((BootAddr + 4))));
/* Set the main stack pointer to the bootloader stack */
__set_MSP(*(uint32_t *)BootAddr);
/* Call the function to jump to bootloader location */
SysMemBootJump();
NVIC_SystemReset();
/* Jump is done successfully */
while (1)
{
/* Code should never reach this loop */
}
}
Now using following code and it seems like device is going in boot mode but its not able to read that it has to be in DFU now.
void JumpToBootloader(void)
{
HAL_SuspendTick();
/* Clear Interrupt Enable Register & Interrupt Pending Register */
for (int i=0;i<5;i++)
{
NVIC->ICER[i]=0xFFFFFFFF;
NVIC->ICPR[i]=0xFFFFFFFF;
}
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
// RM0351 Rev 7 Page 93/1903
// AN2606 Rev 44 Page 23/372
SET_BIT(FLASH->OPTR, FLASH_OPTR_nRST_STDBY_Msk);
SET_BIT(FLASH->OPTR, FLASH_OPTR_nRST_STDBY_Msk);
// CLEAR_BIT(FLASH->OPTR, 1);
//
// CLEAR_BIT(FLASH->OPTR, FLASH_OPTR_nBOOT0);
// SET_BIT(FLASH->OPTR, FLASH_OPTR_nBOOT1);
// CLEAR_BIT(FLASH->OPTR, FLASH_OPTR_nSWBOOT0);
//
// SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
while(READ_BIT(FLASH->SR, FLASH_SR_BSY));
HAL_FLASH_OB_Launch();
}
2021-10-26 07:14 AM
I suspect the RTOS is not uninitialized and is causing issues. Consider setting a magic value in SRAM, resetting the chip, and upon booting up, before initializing anything, check for the magic value and jump to the bootloader if present.
2021-10-27 03:52 AM
Hi,
Two points here-
1)using below code it is jumping to bootloader from user app but as bootloader is not able to detect the condition under which it should go to DFU hence it is again jumping to user application. i want to know how programmatically we can generate such condition in which bootloader will get to know that it should go to dfu? if i physically press and hold the Boot0 switch and reboot the device its going to dfu. i don't want to handle the boot0 pin physically. it should all happen within the code.How can i achieve it?
2)is it compulsary to handle Boot0 pin to be in dfu mode when bootloader is invoked?
Thanks,
Bipin
void JumpToBootloader( void )
{
HAL_RCC_DeInit();
SysTick->CTRL = SysTick->LOAD = SysTick->VAL = 0;
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
const uint32_t p = (*((uint32_t *) 0x1FF00000));
__set_MSP( p );
SCB->VTOR = BOOTLOADER_SA;
void (*SysMemBootJump)(void);
FLASH->OPTR = 0x80000000;
SET_BIT(FLASH->OPTR, FLASH_OPTR_BFB2);
SysMemBootJump = (void (*)(void)) (*((uint32_t *) 0x1FF00004));
SysMemBootJump();
while( 1 ) {}
}
2021-10-27 07:15 AM
If you jump to the bootloader (as opposed to resetting), the BOOT0 pin value is not read. Perhaps your code is causing a reset.
Once the bootloader is loaded, it will jump to USB DFU bootloader if it detects a USB connection.
I would still recommend my last advice:
Consider setting a magic value in SRAM, resetting the chip, and upon booting up, before initializing anything, check for the magic value and jump to the bootloader if present.
2021-10-28 06:33 AM
Hi,
Jumping to the bootloader is not the issue now.its jumping to bootloader from user app and as it sees the valid code in user bank1/2 its jumping back to the user app.
Referring to AN2606(system memory boot mode)
below is the only case where bootloader will go to flash update
i need to achieve above conditions so that it will go to dfu. i tried to erase the bank 1 and 2 but no luck. need some more information on it.how can i erase the both banks before jumping to bootloader from user app?
PLease correct if my understanding is wrong.working first time on STM device
this is something i am trying to do-
void JumpToBootloader( void )
{
uint32_t val = READ_REG(FLASH->OPTR);
HAL_RCC_DeInit();
SysTick->CTRL = SysTick->LOAD = SysTick->VAL = 0;
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
const uint32_t p = (*((uint32_t *) 0x1FF00000));
__set_MSP( p );
//SCB->VTOR = BOOTLOADER_SA;
void (*SysMemBootJump)(void);
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
SET_BIT(FLASH->OPTR,FLASH_OPTR_BFB2_Pos);
int volatile * const p_reg = (int *) 0x08000000 ;
*p_reg = 0x00000000;
int volatile * const q_reg = (int *) 0x08018000 ;
*q_reg = 0x00000000;
SysMemBootJump = (void (*)(void)) (*((uint32_t *) 0x1FF00004));
SysMemBootJump();
while( 1 ) {}
}
Thanks,
Bipin
2021-10-28 07:01 AM
Setting flash to 0 is not the same as erasing it. The erased value would be 0xFFFFFFFF.