2016-05-05 08:39 AM
I am using a stm32f4discovery. When SB18 is removed (underside) to make boot0=1, to boot from system-bootloader, my windows7 sucessfully detects the USB DFU interface (it appears in Device manager in the ''Universal Serial Bus Controllers'' node as ''STM Device in DFU Mode''. Great!).
Next, I replaced SB18 to boot from user flash at 0x08000000. AN2606 revision 27 page 20 clearly states that ''..user can execute bootloader by performing a jump to system memory from user code.'' Exactly what address do I jump to.???? Page 93 says says bootloader starts at 0x1fff0000 (size 30688 bytes). However this is vector table. containing an intial SP and PC of 20001d80 and 1fff3da1. In my usercode I have NOT enables any PLL,interrupts, peripherals, so right at the start of main() I simply jump to 1fff3da1 (1fff3da0 in thumb2 mode) using instructions; __set_MSP(0x20001d80); __set_PSP(0x20001d80); __ASM volatile (''b 0x1fff3da1\n''); but my windows7 does NOT detect the USB DFU interface. Can anyone tell me how to make this work?What actually happens is that I get hard-fault because when I jump to 0x1fff3da1 the debugger takes me to ''*ABS*0x1fff3da0_veneer'' at 0x08005f28. I have tried jumping to 1fff3da0. Same result.I am using GNU C++ in SW4STM32. #it's-deja-vu-all-over-again2016-05-05 08:59 AM
2016-05-05 09:35 AM
2016-05-05 10:27 AM
For USB/DFU yes, as it is far more involved. The USART System Loader, on the F1, and in my experience generally, does not need interrupts. I suspect the code doesn't explicitly set SCB->VTOR, which it assumes is zero (per processor default), one could set that to the ROM base, and I'd suspect it would have the same effect.
Anyway, one should generally jump through the vector table rather than specifying explicit addresses, as the ''ROM'' has a tendency to change with different versions of the loader.I've been doing this stuff long before the App Note, so I'm not sure who wrote it or where they lost the plot.2016-05-06 07:09 AM
Follow up;
Actually a jump to bootloader from C language works in principle, the compiler was objecting to syntax __ASM volatile (''b 0x1fff3da1\n'');1. Replacing it with __ASM volatile (''ldr R0, =0x1fff3da1\n''); __ASM volatile (''bx R0\n'');Works. Or
2. replacing it with with; void (*func)(void) = (void (*)(void))0x1fff3da1; func(); works, or3. replacing it with a call to extern ''C'' void loader(void); loader(); works, where ''loader'' is an assembler function in the startup.s file alongside Reset_Handler that looks like this .weak loader .type loader, %function loader: LDR R0, =0x1FFF0000 LDR SP, [R0, #0] LDR R0, [R0, #4] BX R0Or
4. replacing it with this C implementation typedef void (*fptr_t)(void); //function ptr type uint32_t* tableptr = (uint32_t*)0x1fff0000; //vector table in sys mem fptr_t function = (fptr_t)tableptr[1]; //jump destination function(); //jumpworks - and uses the vector table at start of system memory.
( - Also I replaced wrong SP inititialization
__set_MSP(0x20001d80); __set_PSP(0x20001d80);with
__ASM volatile (''ldr sp, =0x20001d80\n'');- )
Works, although it is better to get the initial SP from the vector table at 0x1fff0000 like this __ASM volatile (''ldr r0, =0x1fff0000\n ldr sp, [r0, #0]\n'' : : : ''sp'');Yes this deliberately ignores the bigger picture, the idea is to test the claim that we can simply jump to the bootloader from main flash C code, and the answer is yes we can. Other posts, and AN2606, deal very well with the details of how you do this properly. For me that is a separate step.