2020-02-15 12:38 AM
Revision "V" CPUs use the Version 9 bootloader rather than version 3.1 in "Y". I can't get Jump to bootloader as described in "FAQ: Jump to Bootloader from application on STM32H7 devices" to work on "V" parts although it works perfectly in "Y". As suggested in another thread I am setting the stackpointer in STM32H743II_FLASH.ld to 16 less than the end of the RAM section to avoid the Version 9 bootloader trying to pop an invalid address
Solved! Go to Solution.
2020-02-15 07:01 AM
OK, I've tested it on a Nucleo-H743ZI2 board with rev V (DBGMCU->IDCODE = 0x20036450), the bootloader is indeed at 0x1FF09800.
int main(void) {
volatile uint32_t * vect = 0x1FF09800;
asm volatile(
"mov sp, %[boot_sp]\n\t"
"bx %[boot_pc]\n\t"
::[boot_sp]"r"(vect[0]),[boot_pc]"r"(vect[1])
);
}
connecting the USB port I see this
$ lsusb | grep ST
Bus 001 Device 015: ID 0483:df11 STMicroelectronics STM Device in DFU Mode
which is good enough for me.
I did loading SP (with the value from 0x1FF09800) and jumping to the bootloader as one assembly block, because I don't like doing anything in C after messing with the stack pointer.
2020-02-15 01:33 AM
Strictly according to the reference manual, the bootloader vector table is at 0x1FF00000 (see the BOOT_ADD1 option register), so the initial value of SP is stored at 0x1FF00000, and the start address is stored at 0x1FF00004.
2020-02-15 01:46 AM
Yes, but on the H743 it has always been 0x1ff09800 as per the STM FAQ. If they have changed it between versions then it should be in AN5312 and it isn't
2020-02-15 07:01 AM
OK, I've tested it on a Nucleo-H743ZI2 board with rev V (DBGMCU->IDCODE = 0x20036450), the bootloader is indeed at 0x1FF09800.
int main(void) {
volatile uint32_t * vect = 0x1FF09800;
asm volatile(
"mov sp, %[boot_sp]\n\t"
"bx %[boot_pc]\n\t"
::[boot_sp]"r"(vect[0]),[boot_pc]"r"(vect[1])
);
}
connecting the USB port I see this
$ lsusb | grep ST
Bus 001 Device 015: ID 0483:df11 STMicroelectronics STM Device in DFU Mode
which is good enough for me.
I did loading SP (with the value from 0x1FF09800) and jumping to the bootloader as one assembly block, because I don't like doing anything in C after messing with the stack pointer.
2020-02-15 07:49 AM
berendi
Many thanks for testing this for me. Not sure whether the answer is good or bad though. Good is we now know the correct address. Bad is that it isn't working on "V" in my code despite working on "Y" and I'm using exactly the STM suupplied code so there must be something else different on the "V" that in my environment is stopping it. What makes it doubly difficult is that it is only one of my users who has a "V" so all testing is via remote "try this, try that". His "Y" works fine like mine - aaaaaagh!!!!!
2020-02-15 08:24 AM
As you can see, I've tested it straight in main(), no peripherals are brought up at all.
Can you try it with my code after the enable_irq() line in the FAQ article?
If it still doesn't work, try resetting all peripherals before enable_irq() through the RCC reset registers, like this
RCC->AHB1RSTR = ~0;
RCC->AHB1RSTR = 0;
repeated for all *RSTR registers.
Then put everything else back the way it is at reset. Switch back to HSI clock, reset flash latency, set every RCC register back to its reset value, or as close as possible. Unfortunately there are some "write once" register fields there, I don't know what to do with them.
I usually just do a NVIC_SystemReset() in the application when the user wants to start the bootloader, and check as early as possible if RCC->RSR indicates a soft reset (SFTRSTF), then jump straight to the system bootloader before bringing up anything else.