Skip to main content
Visitor II
January 7, 2024
Question

Boot to soft (STM32L151)

  • January 7, 2024
  • 3 replies
  • 3535 views

Hi,
II have a BIG problem: at a certain time, I was able to jump from bootloader to a soft but I can't do it anymore. Perhaps I modified something in the soft (it was with STMCubeIde but, sorry, I hate STMCubeIde because every time you change your programming machine you lost configuration)  so now I'm trying to do this with MikroC so I just have to copy directory on a USB key.
The only sure thing is that processor had serial port broken so I changed it and I bought it from China (instead Farnell because the had no more when I needed). I hope this is not the problem has I ordered 100... 

I want my bootloader jump to flash. Boot pin has a zero level and can't been changed.
"Bootloader" (vectors to 0x0) start at 0x200 , "soft" vectors adress start at 0xC400 and soft at 0xC800)
The "soft" vectors adress is a copy from original soft vectors (0x0) when soft has been tested, so "soft" vectors have been moved from 0x0 to 0xC400 in an ".bin" file adding "bootloader" file and "soft file".  
When control "p_Led10" on, I can see flash vectors copy (0x0800C400 to 0x20000000) is OK.
But I will have a simple bootloader reset.
Any help apprecied (in french ? ;))

//------------------------------------------------------------------------------

void JumpToProg(unsigned long *VectAd)
{
unsigned int x2;
unsigned long *flashAddress = VectAd;
unsigned long *sramStartAddress = (unsigned long *)0x20000000; // SRAM destination
unsigned long *sramAddress = sramStartAddress;
char txt[18];

DisableInterrupts();

//* vect copy to SRAM
for (x2 = 0; x2 < 256; x2 += 4)
{
*sramAddress++ = *flashAddress++;
}

RCC_APB2ENR.SYSCFGEN = 1;
delay_ms(20);

//SCB_VTOR =(unsigned long)sramStartAddress; // no change

// Configuration des bits BOOT_MODE pour Embedded SRAM boot mode
SYSCFG_MEMRMP |= 0x03; // boot mode to SRAM

//EnableInterrupts(); // problem here: freeze if used
p_Led10=1;
delay_ms(3000);

SCB_AIRCR=0x05FA0004; //5FA05=key , 0x4=0b100=reset

while (1)
{
p_WDC=~p_WDC; // wait reset (this to avoid external electronic watchdog security)
}
}

//------------------------------------------------------------------------------

    This topic has been closed for replies.

    3 replies

    Super User
    January 7, 2024

    > //EnableInterrupts(); // problem here: freeze if used

    What interrupt gets called? Look at VECTACTIVE or VECTPENDING fields in SCB registers.

    > delay_ms(20);

    Does this use systick? Probably want to disable that before the jump. I don't see you actually making the jump anywhere.

     

    Perhaps go off of the code to jump to bootloader, but modify it to suit your target location and vector table scheme.

    https://community.st.com/t5/stm32-mcus/how-to-jump-to-system-bootloader-from-application-code-on-stm32/ta-p/49424

     

    JFELI.13Author
    Visitor II
    January 8, 2024

    Thanks a lot for your answer.
    I tried to make some change to see what happened.
    It's seem it's always the same: when "JumpToProg()" has been called, I can see 


    #define BOOTLOADER_AD 0x200
    #define PROG1_VECT_AD 0xC400
    #define PROG1_AD 0xC800 
    #pragma orgall BOOTLOADER_AD

    //------------------------------------------------------------------------------

    void JumpToProg(unsigned long *VectAd)
    {
    unsigned int x2;
    unsigned long *flashAddress = VectAd;
    unsigned long *sramStartAddress = (unsigned long *)0x20000000; // SRAM destination
    unsigned long *sramAddress = sramStartAddress;
    char txt[18];

    DisableInterrupts();

    //* vect copy to SRAM
    for (x2 = 0; x2 < 256; x2 += 4)
    {
    *sramAddress++ = *flashAddress++;
    }

    RCC_APB2ENR.SYSCFGEN = 1;
    //delay_ms(20);


    STK_CTRL=STK_CTRL & (~0b11); // SYSTICK off (no systick exception + disabled)
    //cleat interrupts
    NVIC_ICER0=0xFFFFFFFF;
    NVIC_ICPR0=0xFFFFFFFF;
    NVIC_ICER1=0xFFFFFFFF;
    NVIC_ICPR1=0xFFFFFFFF;
    //SCB_VTOR =(unsigned long)sramStartAddress; // no change
    SYSCFG_MEMRMP |= 0x03; // boot mode to SRAM

    //EnableInterrupts(); // problem here: freeze if used

    // control so I know the soft doesn't freeze before
    p_Led10=1;
    delay_ms(3000);
    //

    SCB_AIRCR=0x05FA0004; //5FA05=key , 0x4=0b100=reset

    while (1)
    {
    p_WDC=~p_WDC; // wait reset (this to avoid external electronic watchdog security)
    }
    }

    //------------------------------------------------------------------------------


    void main() org START_BOOTLOADER_ADDR
    {
    char x1,y1=0,TimeCtrl,Rx5_Flag=FAUX;


    #ifdef OLED
    char Texte1[18];
    char Hexa[6];
    #endif

    InitSetUp();

    #ifdef OLED
    OLED_Init();
    OLED_Fill(0);
    #endif


    while(1)
    {
    #ifdef OLED
    SSD1306_DisplayText8X8(LINE_0, 3, "BOOTLOADER", x1 );
    x1=~x1;
    #endif
    p_WDC=~p_WDC;
    delay_ms(200);
    p_Led10=~p_Led10;
    y1++;
    if(y1>20)
    {
    p_Led10=0;
    JumpToProg(PROG1_VECT_AD);
    y1=0;
    }
    }

    }



    JFELI.13Author
    Visitor II
    January 8, 2024
    And, this is also a try with STM32CubeIde with no sucess:


    #define PROG1_VECT_AD        0x0800C400 
    #define PROG1_AD             0x0800C800
     
    void (*SysMemBootJump)(void);
     
    bool jump_to_application(uint32_t VectAd) // l'adresse doit être multiple de 512 (0xC400 et 0x36000 le sont)
    {
    // For STM32L151, system memory is on 0x1FF0 0000
    SysMemBootJump=(void (*)(void))(*((uint32_t*)VectAd+4));
        IEEPROM_Write_32(IEE_PGACTIVE_ADDR, VectAd); // sauvegarde de l'adresse vecteurs
        // Désactiver l'I2C
        HAL_I2C_DeInit(&hi2c1); // Assurez-vous que hi2c1 est votre instance I2C
     
     
    // pointe sur l'adresse reset vecteur PC
    //void (*app_reset_handler)(void) = (void*)(*((volatile uint32_t*) (VectAd + 4+1)));
     
     
    // désactive RCC (horloge interne, pas de PLL...)
    HAL_RCC_DeInit();
     
    // désactive timer SysTick
    SysTick->CTRL=0;
    SysTick->LOAD=0;
    SysTick->VAL =0;
     
    __set_PRIMASK(1); // disbale interupts
     
    //__set_MSP(VectAd);
    // modifie VTOR pour réorienter les vecteurs
    //SCB->VTOR = VectAd;
     
    // Charge la valeur du pointeur de pile principal (MSP) depuis l'adresse vectAd
    __set_MSP(*((volatile uint32_t *)VectAd));
     
    SysMemBootJump();
     
     
     
    //__disable_irq(); // nécessaire ou non ?
    //__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(); // remapping de la mémoire pour adresser 0x0
     
    //app_reset_handler();
    //HAL_GPIO_WritePin(Led10_GPIO_Port, Led10_Pin, GPIO_PIN_SET);
    return true; // (note: en théorie on n'atteint pas cetet ligne (programme externe démarré)
    }
     
    (main)
    jump_to_application(PROG1_VECT_AD); 
    Super User
    January 8, 2024

    > It's seem it's always the same: when "JumpToProg()" has been called, I can see 

    Is there more to this sentence? It doesn't explain anything.

    Your code is still quite different from the examples given.

    JFELI.13Author
    Visitor II
    January 8, 2024

    Oups ! it appears I forgot some words ...
    I'm trying to be more clear.
    1) I'm using a soft, writed with MikroC and quite big in size (GPS tracking, satellite sending...) 

    2) this soft, at this time, has no radio updating capability and, now, I'm looking for adding this possibility
    3) the purpose is to have 3 areas in flash: bootloader, program1, program2. There is another area with a "backup" copy done in external EEPROM, to add another security.
    4) the bootloader will look actual functionnal soft (so program1 or program2), will control some security datas (example how many abnormal resets for a current program, updating state ...)
    5) the bootloader has to be "small" in size so the two program areas can be higher. bootloader org is 0x08000400, PROG1_AD is 0x0800C800, PROG2_AD is 0x08036400
    6) PROGx adress is the "org" adress. Before this adress, at exactly adress-0x400, I have vectors for them. The "bin" file used for this is done with Visual Studio who mix bootloader "bin" file, move program "bin" vectors area to program adress-0x400 and add, of course, program file.

    So , actually I 'm just trying to jump from bootloader to a program.  That's why it's not important I did it whith MikoC or StmCube32Ide (except, has I mentionned it, STMCube is not usefull at all for working on different PCs).

    //------------------------------------------------------------------
    #define BOOTLOADER_AD 0x200
    #define PROG1_VECT_AD 0xC400
    #define PROG1_AD 0xC800 
    #pragma orgall BOOTLOADER_AD

    //------------------------------------------------------------------------------

    void JumpToProg(unsigned long *VectAd)
    {
    unsigned int x2;
    unsigned long *flashAddress = VectAd;
    unsigned long *sramStartAddress = (unsigned long *)0x20000000; // SRAM destination
    unsigned long *sramAddress = sramStartAddress;
    //char txt[18]; // just for debug

    DisableInterrupts();

    //* vect copy to SRAM: notice x2 is in RAM so I could be a problem but it work ... 
    for (x2 = 0; x2 < 256; x2 += 4)
    {
    *sramAddress++ = *flashAddress++;
    }

    RCC_APB2ENR.SYSCFGEN = 1;
    //delay_ms(20); // that was to test effect only


    STK_CTRL=STK_CTRL & (~0b11); // SYSTICK off (no systick exception + disabled)
    //clear interrupts (I just added this in case of pending interrupts)
    NVIC_ICER0=0xFFFFFFFF;
    NVIC_ICPR0=0xFFFFFFFF;
    NVIC_ICER1=0xFFFFFFFF;
    NVIC_ICPR1=0xFFFFFFFF;
    //SCB_VTOR =(unsigned long)sramStartAddress; // no change. I don't think it's needed
    SYSCFG_MEMRMP |= 0x03; // boot mode to SRAM

    //EnableInterrupts(); // problem here: freeze if used

    // control so I know the soft doesn't freeze before
    p_Led10=1;
    delay_ms(3000);
    //

    SCB_AIRCR=0x05FA0004; //5FA05=key , 0x4=0b100=reset

    while (1)
    {
    p_WDC=~p_WDC; // wait reset (this to avoid external electronic watchdog security)
    }
    }

    //------------------------------------------------------------------------------


    void main() org START_BOOTLOADER_ADDR
    {
    char x1,y1=0,TimeCtrl,Rx5_Flag=FAUX;


    #ifdef OLED
    char Texte1[18];
    char Hexa[6];
    #endif

    InitSetUp();

    #ifdef OLED
    OLED_Init();
    OLED_Fill(0);
    #endif


    while(1)
    {
    #ifdef OLED
    SSD1306_DisplayText8X8(LINE_0, 3, "BOOTLOADER", x1 );
    x1=~x1;
    #endif
    p_WDC=~p_WDC;
    delay_ms(200);
    p_Led10=~p_Led10;
    y1++;
    if(y1>20)
    {
    p_Led10=0;
    JumpToProg(PROG1_VECT_AD);
    y1=0;
    }
    }

    }

    Super User
    January 8, 2024

    >SYSCFG_MEMRMP |= 0x03; // boot mode to SRAM

    Data in SRAM usually survives software reset. But SYSCFG? What do you think happens to your "boot mode" after reset?

     

    JFELI.13Author
    Visitor II
    January 8, 2024

    You're probably wright and this explain classic boot. But how can I do ? 

    Super User
    January 8, 2024

    > But how can I do ? 

    You have to actually make the jump as "SysMemBootJump();" does in the previously linked code after setting MSP.

    https://community.st.com/t5/stm32-mcus/how-to-jump-to-system-bootloader-from-application-code-on-stm32/ta-p/49424