Reputation: 1
Requirement: Keep BOOT0 held high so the STM32 is in DFU mode upon initial connection to computer. The computer software can either flash or leave immediately to 0x08000000 running the flash program.
Issue: The DFU leave command does not work while BOOT0 is held high.
Potential Solutions: Users have solved this issue on STMF4 products due to it having a Cortex-M3/M4 https://community.st.com/t5/stm32-mcus-embedded-software/leave-dfu-while-boot0-is-high-stm32f4/td-p/556307
Uncommenting this lines solves the issue on those products as well.
#define USER_VECT_TAB_ADDRESS
However I haven't found resources with a step by step solution for Cortex-M0 (STM32F072RBT)
I have tried relocating the vector tables and booting from SRAM. However, since I never found a clear way of doing this I believe all my attempts had corrupted code.
Large Picture Motivation: Release a product (STM32F072RBT) with no buttons or toggles on the PCB and allow customers to flash and interact with their product over USB serial interface.
Upvotes: 0
Views: 131
Reputation: 1
Sorry I thought I had deleted the post prior to approval. This is the answer: Located in system_stm32f0xx.c
or whatever your Cortex-M0 chips name is
void SystemInit(void) { SYSCFG->CFGR1 &= ~(0x1 << 5); }
Hopefully this will help someone else out!
Upvotes: 0
Reputation: 15092
I was trying to do something identical for a product I was working on. STM representative suggested the following solution: Always boot into your app but when your app wishes to go to into DFU mode write a magic value to RAM area you aren't already using and trigger a soft reset, then very early during your app boot check for the magic value and instead of running your normal startup sequence jump to the system bootloader.
You will need to lookup the correct system bootloader address in AN2606 for your chip. The code below uses the address from the STM32C011xx
// See Section STM32C011xx devices bootloader in AN2606
#define STM32C011xx_SYSTEM_BL_START_ADDR 0x1FFF0000 // FIXME: use address for your chip
// Pick somewhere in RAM that isn't currently used (soft reset doesn't wipe RAM itself)
#define STM32_SYSTEM_BL_MAGIC_ADDR 0x200003FC
// Something unique
#define STM32_SYSTEM_BL_MAGIC_VALUE 0xC0C1C2C3
void Reboot_To_Dfu(void)
{
*((volatile uint32_t *) STM32_SYSTEM_BL_MAGIC_ADDR) = STM32_SYSTEM_BL_MAGIC_VALUE;
// Memory barriers
__DSB();
__ISB();
// Soft reset
NVIC_SystemReset();
while (1);
}
void Handle_Dfu_Switch(void)
{
// Check if we should go into bootloader mode
if (*((volatile uint32_t *) STM32_SYSTEM_BL_MAGIC_ADDR) == STM32_SYSTEM_BL_MAGIC_VALUE) {
// Reset our trigger
*((volatile uint32_t *) STM32_SYSTEM_BL_MAGIC_ADDR) = 0x00000000;
uint32_t stack_pointer = ((const uint32_t *) STM32C011xx_SYSTEM_BL_START_ADDR)[0];
uint32_t jump_addr = ((const uint32_t *) STM32C011xx_SYSTEM_BL_START_ADDR)[1];
// Redirect vector table
SCB->VTOR = STM32C011xx_SYSTEM_BL_START_ADDR;
// Change MSP and PSP
__set_MSP(stack_pointer);
__set_PSP(stack_pointer);
// Memory barriers
__DSB();
__ISB();
void (*SysMemBootJump)(void) = (void (*)(void)) (jump_addr);
SysMemBootJump();
while (1);
}
}
In your system_stm32xyz.c (where xyz
depends on your chip) place this line at the top of the SystemInit
function:
void SystemInit(void)
{
// Consider jumping to DFU instead of normal boot
Handle_Dfu_Switch();
// typical SystemInit code continues here...
}
I didn't end up using this after all so I'm not 100% it works, would be great to know if you try it and it works for you.
Upvotes: 1