cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L476 - Jump to flashloader from user code

confalonieri
Associate II
Posted on November 16, 2017 at 10:23

I am trying to jump to flash loader from user application. I am using a custom board based on the STM32L476.

Premising that the standard procedure 'Hw Reset + Boot0 pin setup' works flawlessly by using the examples from the forum I implemented the below reset firmware

        THUMB

        PUBWEAK Reset_Handler

        SECTION .text:CODE:NOROOT:REORDER(2)

Reset_Handler

;  ORIGINAL

;  LDR     R0, =SystemInit

;       BLX     R0

;       LDR     R0, =__iar_program_start

;       BX      R0

; modified reset checking flash loader

;

  LDR     R0, =0x20017ff0  ; ADR to check FW reload signature

  LDR  R1, =0xDEADBEEF  ; FW reload signature

  LDR  R2,[R0, &sharp0]   ;

  STR  R0,[R0, &sharp0]         ; Reset FW reload signature for successive start up

  CMP  R2,R1               ;

  BEQ  Reboot_Loader  ; Jump to flash loader

;

; NO FLASH LOADER CONTINUE WITH STD RESET

;

  LDR     R0, =SystemInit

        BLX     R0

        LDR     R0, =__iar_program_start

        BX      R0  

;

; reboot to flash loader

;

Reboot_Loader

        LDR  R0, =0x40021060

  LDR  R1, =0x00004001  ; SysCFG + UART1 CLK

  STR  R1, [R0, &sharp0]  ; Set it

  LDR  R0, =0x40010000

  LDR  R1, =0x00000001     ; Remap system memory

  STR  R1, [R0, &sharp0]  ; Set it

  LDR     R0, =0x1FFF0000     ; System memory address

  LDR  SP,[R0, &sharp0]   ; Load SP

  LDR  R0,[R0, &sharp4]   ; Load Start address

  BX  R0     ; Jump to flash loader

Unfortunately, when I run the STFlashLoader application  it did not recognise the SMT32L476.

Using the IAR debugger I saw that the jump to flashloader starts and loop inside. Anyhow the debugger show address  1fffxxxx.

Any idea ? What I am doing wrong ?

#stm32l476-flash-loader
8 REPLIES 8
Uwe Bonnes
Principal II
Posted on November 16, 2017 at 12:01

Check all Bootloader related pins and the values these pins expect in an2606. Look at the flowcharts in AN2606  and check that no unexpected value at some bootloader related pin hohs the bootloader.

Posted on November 16, 2017 at 12:19

Thank you.

This was my first thought. I think that the flash loader did not understand I want to communicate through the USART1. So I try with the board running under the same conditions using the HW reset and the boot0 pin !

It work flawlessly !

Anyhow I will follow your suggestion and double check again !

Thomas Roell
Associate III
Posted on November 16, 2017 at 13:40

Ran into similar problems. Here the code that I am using. I am triggering off the RTC_CR_BCK bit rather than a random memory location. The key things were VTOR and MEMRMP, as well as resetting the I/D cache. Latter on I hit badly on L433, but that doesn't mean it's not present on L476 as well.

__attribute__((naked)) void reset_stm32l4xx(void) {     uint32_t flash_acr;      RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;      RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;  #if defined(STM32L432xx) || defined(STM32L433xx) || defined(STM32L496xx)     RCC->APB1ENR1 |= RCC_APB1ENR1_RTCAPBEN; #endif      /* Switch to Main Flash @ 0x00000000. Make sure the I/D CACHE is      * disabled to avoid stale data in the cache.      */      flash_acr = FLASH->ACR;      FLASH->ACR = flash_acr & ~(FLASH_ACR_ICEN | FLASH_ACR_DCEN);           SYSCFG->MEMRMP = 0;      PWR->CR1 |= PWR_CR1_DBP;          while (!(PWR->CR1 & PWR_CR1_DBP))     {     }          if (!(RCC->BDCR & RCC_BDCR_RTCEN))     {      RCC->BDCR |= RCC_BDCR_BDRST;            RCC->BDCR &= ~RCC_BDCR_BDRST;     }          /* If RTC_CR_BCK is set it means the reset was triggered to      * branch throu to the STM32 BOOTLOADER.      */     if (RTC->CR & RTC_CR_BCK)     {      RTC->WPR = 0xca;      RTC->WPR = 0x53;      RTC->CR &= ~RTC_CR_BCK;      RTC->WPR = 0x00;       SYSCFG->MEMRMP = SYSCFG_MEMRMP_MEM_MODE_0;       FLASH->ACR = (flash_acr & ~(FLASH_ACR_ICEN | FLASH_ACR_DCEN)) | (FLASH_ACR_ICRST | FLASH_ACR_DCRST);      FLASH->ACR = flash_acr;  #if defined(STM32L432xx) || defined(STM32L433xx) || defined(STM32L496xx)      RCC->APB1ENR1 &= ~RCC_APB1ENR1_RTCAPBEN; #endif       RCC->APB2ENR &= ~RCC_APB2ENR_SYSCFGEN;       RCC->APB1ENR1 &= ~RCC_APB1ENR1_PWREN;       SCB->VTOR = 0x00000000;            /* This needs to be assembly code as GCC catches NULL        * dereferences ...       */      __asm__ volatile ('   ldr     r2, =0x00000000                \n'                  '   ldr     r0, [r2, #0]                   \n'                  '   ldr     r1, [r2, #4]                   \n'                  '   msr     MSP, r0                        \n'                  '   dsb                                    \n'                  '   isb                                    \n'                  '   bx      r1                             \n');     }

Thomas Roell
Associate III
Posted on November 16, 2017 at 13:46

Looks like the code formatting does not work.

__attribute__((naked)) void reset_stm32l4xx(void)

{

uint32_t flash_acr;

RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;

RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;

#if defined(STM32L432xx) || defined(STM32L433xx) || defined(STM32L496xx)

RCC->APB1ENR1 |= RCC_APB1ENR1_RTCAPBEN;

#endif

/* Switch to Main Flash @ 0x00000000. Make sure the I/D CACHE is

* disabled to avoid stale data in the cache.

*/

flash_acr = FLASH->ACR;

FLASH->ACR = flash_acr & ~(FLASH_ACR_ICEN | FLASH_ACR_DCEN);

SYSCFG->MEMRMP = 0;

PWR->CR1 |= PWR_CR1_DBP;

while (!(PWR->CR1 & PWR_CR1_DBP))

{

}

if (!(RCC->BDCR & RCC_BDCR_RTCEN))

{

RCC->BDCR |= RCC_BDCR_BDRST;

RCC->BDCR &= ~RCC_BDCR_BDRST;

}

/* If RTC_CR_BCK is set it means the reset was triggered to

* branch throu to the STM32 BOOTLOADER.

*/

if (RTC->CR & RTC_CR_BCK)

{

RTC->WPR = 0xca;

RTC->WPR = 0x53;

RTC->CR &= ~RTC_CR_BCK;

RTC->WPR = 0x00;

SYSCFG->MEMRMP = SYSCFG_MEMRMP_MEM_MODE_0;

FLASH->ACR = (flash_acr & ~(FLASH_ACR_ICEN | FLASH_ACR_DCEN)) | (FLASH_ACR_ICRST | FLASH_ACR_DCRST);

FLASH->ACR = flash_acr;

#if defined(STM32L432xx) || defined(STM32L433xx) || defined(STM32L496xx)

RCC->APB1ENR1 &= ~RCC_APB1ENR1_RTCAPBEN;

#endif

RCC->APB2ENR &= ~RCC_APB2ENR_SYSCFGEN;

RCC->APB1ENR1 &= ~RCC_APB1ENR1_PWREN;

SCB->VTOR = 0x00000000;

/* This needs to be assembly code as GCC catches NULL

* dereferences ...

*/

__asm__ volatile (' ldr r2, =0x00000000 \n'

' ldr r0, [r2, #0] \n'

' ldr r1, [r2, #4] \n'

' msr MSP, r0 \n'

' dsb \n'

' isb \n'

' bx r1 \n');

}

Posted on November 16, 2017 at 12:53

Did you remap vtor?

Posted on November 16, 2017 at 13:23

No.

Do I need to change it (How ?) even if I came from a software reset ?

Posted on November 16, 2017 at 13:45

Can you please repost with better formatting? Thanks!

Posted on November 16, 2017 at 14:52

 ,

 ,

Thank you for the suggestions

I did the modification to my assembler code ,starting the flash loader as per your suggestions unfortunately it does not fix the , problem.

NEW code follows:

Reset_Handler

 ,

,  ,ORIGINAL

 ,

, , ,LDR , , , , R0, =SystemInit

 ,

, , , , , , , BLX , , , , R0

 ,

, , , , , , , LDR , , , , R0, =__iar_program_start

 ,

, , , , , , , BX , , , , , R0

 ,

, modified reset checking flash loader

 ,

,

 ,

 , ,LDR , , , , R0, =0x20017ff0 , ,, ADR to check FW reload signature

 ,

 , ,LDR , ,R1, =0xDEADBEEF , ,, FW reload signature

 ,

 , ,LDR , ,R2,[R0, ♯ 0] , , ,,

 ,

 , ,STR , ,R0,[R0, ♯ 0] , , , , , , , , , Reset FW relod signature for successive startup

 ,

 , ,CMP , ,R2,R1 , , , , , , , , , , , , , , ,

 ,

 , ,BEQ , ,Reboot_Loader , ,, Jump to flash loader

 ,

,

 ,

, NO FLASH LOADER CONTINUE WITH STD RESET

 ,

,

 ,

 , ,LDR , , , , R0, =SystemInit

 ,

 , , , , , , , BLX , , , , R0

 ,

 , , , , , , , LDR , , , , R0, =__iar_program_start

 ,

 , , , , , , , BX , , , , , R0 , ,

 ,

,

 ,

, reboot to flash loader

 ,

,

 ,

Reboot_Loader

 ,

 , LDR , ,R0, =0x40021060 , , , , , RCC_APB2ENR

 ,

 , ,LDR , ,R1, ,=0x00004001 , ,, SysCFG + UART1 CLK

 ,

 , ,STR , ,R1, [R0, ♯ 0] , ,, Set it ,

 ,

 , ,LDR , ,R0, =0x40021060 , , , , , RCC_APB1ENR1

 ,

 , ,LDR , ,R1, ,=0x10000000 , ,, PWR interface clock

 ,

 , ,STR , ,R1, [R0, ♯ 0] , ,, Set it

 , ,LDR , ,R0, ,=0x40010000 , , , , , SYSCFG_MEMRMP

 ,

 , ,LDR , ,R1, ,=0x00000001 , , , , , Remap system memory

 ,

 , ,STR , ,R1, [R0, ♯ 0] , ,, Set it

 , ,LDR , ,R0, ,=0x40022000 , , , , , FLASH->,ACR

 ,

 , ,LDR , ,R1, ,=0x00000000 , , , , , No Data Chache No Instr Chache

 ,

 , ,STR , ,R1, [R0, ♯ 0] , ,, Set it

 , ,LDR , ,R0, ,=0xE000ED08 , , , , , SCB-VTOR Address

 ,

 , ,LDR , ,R1, ,=0x1FFF0000 , , , , , Remap to system memory

 ,

 , ,STR , ,R1, [R0, ♯ 0] , ,, Set it

 ,

 , ,LDR , , , , R0, =0x1FFF0000 , , , , , System memory address

 ,

 , ,LDR , ,SP,[R0, ♯ 0] , , ,, Load SP

 ,

 , ,LDR , ,R0,[R0, ♯ 4] , , ,, Load Start address

 ,

 , ,BX , ,R0 , , , , ,, Jump to bootloader

By using the debugger I see it is running in the Flash loader (system memory)