cancel
Showing results for 
Search instead for 
Did you mean: 

Is the H7 bootloader address still 0x1FF09800 for "V" CPUs?

PMath.4
Senior III

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

1 ACCEPTED SOLUTION

Accepted Solutions
berendi
Principal

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.

View solution in original post

5 REPLIES 5
berendi
Principal

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.

PMath.4
Senior III

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

berendi
Principal

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.

PMath.4
Senior III

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!!!!!

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.