2010-05-07 10:20 AM
Jump to internal bootloader
#bootloader-gpio2011-05-17 04:50 AM
Yes, just set up the MSP and PC.
2011-05-17 04:50 AM
You have to disable IRQ, reset USART1 and RCC before setting MSP/PC. If you want to have correct hard fault handling, you have to change the interrupt table address to 0x1FFFF000. WARNING: The hard fault initiates a hard reset! If you haven't changed the boot pins, the STM32 will try to start at code position. Some commands of the internal bootloader also initiate a hard reset! Be sure, that you have runnable code ;)
The internal bootloader expects some registers to be in reset state.2011-05-17 04:50 AM
Thanks guys. I've tried this code below (which I've used previously in my own bootloader) and it does not get me into the ST bootloader. Any ideas?
#define RESET_VECTOR_TABLE_OFFSET 4 // 1st 32 bit location is reserved, 2nd is reset vector #define ST_BOOTLOADER_ADDRESS 0x1FFFF000 #define APPLICATION_RESET_VECTOR_ADDRESS (ST_BOOTLOADER_ADDRESS + RESET_VECTOR_TABLE_OFFSET) typedef void (*pFunction)(void); pFunction Jump_To_Application; u32 JumpAddress; . . . // Need to reset USART1 and RCC before jumping to bootloader RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); RCC_DeInit(); ctl_global_interrupts_set(0); // disable interrupts JumpAddress = *(vu32*)APPLICATION_RESET_VECTOR_ADDRESS; Jump_To_Application = (pFunction) JumpAddress; // Initialize user application's Stack Pointer __MSR_MSP(*(vu32*) ST_BOOTLOADER_ADDRESS); Jump_To_Application(); // should never get here2011-05-17 04:50 AM
As damh indicates, getting the processor into a suitable state from an application can be difficult. I would not do it this way.
I get into the boot loader by reseting the device, and having a code path in my assembler startup code to fork into the boot loader. This can be done very early prior to any peripherals, interrupts or vectors being set up. Instead of checking for a button, I check for a magic constant in RAM, but you could do both or either.2011-05-17 04:50 AM
Hi Clive1,
A magic constant in RAM sounds good. I take it you mean normal RAM and not backup register domain? Are you able to share the assembly code you used to set up the MSP and PC? Thanks Trevor.2011-05-17 04:50 AM
I had it posted here
https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/STM32%20Internal%20Bootloader The content of the main RAM (0x20000000..0x2000????) survives a reset. This is for Keil, but the basic concept should port to IAR, Rowley, etc. -Clive You can call code in the Boot ROM as you can any other. If you want to run the whole thing, don't expect it to return to your application, or have the clocks/interrupt set in the way you had them. Generally I would recommend reseting into the Boot ROM so it starts without random clocks and interrupts enabled from your application. In application.c // 1FFFF000 -> 20000200 -> SP // 1FFFF004 -> 1FFFF021 -> PC printf(''Entering Boot Loader..\r\n''); *((unsigned long *)0x2000FFF0) = 0xDEADBEEF; // 64KB STM32F103 NVIC_GenerateSystemReset(); In startup.s ; Reset Handler Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main LDR R0, =0x2000FFF0 LDR R1, =0xDEADBEEF LDR R2, [R0, #0] STR R0, [R0, #0] ; Invalidate CMP R2, R1 BEQ Reboot_Loader LDR R0, =__main BX R0 ENDP Reboot_Loader PROC EXPORT Reboot_Loader LDR R0, =0x1FFFF000 LDR SP,[R0, #0] LDR R0,[R0, #4] BX R0 ENDP2011-05-17 04:50 AM
Great, thanks.
LDR SP,[R0, #0] I get this errorError: lo register required -- `ldr sp,[r0,#0]' I have tried using a literal address but get the same error. I'm using Rowley (GCC). Any ideas?2011-05-17 04:50 AM
LDR R13,[R0, #0]
2011-05-17 04:50 AM
I tried that but get same error. SP is used without error in other parts of the assembly code anyway. r0 - r7 work but all other registers cause this error -- hence the error message referring to the ''lo'' register required. I also tried to use STR instead of LDR and got the same error. Is this a thumb/thumb2 or code allignment issue? The file has this at the top
.section .init, ''ax'' .code 16 .align 2 Thanks Trevor