cancel
Showing results for 
Search instead for 
Did you mean: 

Boot to soft (STM32L151)

JFELI.13
Associate III

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)
}
}

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

15 REPLIES 15

> 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

If you feel a post has answered your question, please click "Accept as Solution".

If I understand correctly:

1) It is not possible to use the flash to launch a program (SYSCFG_MEMRMP |= 0x03;) because SCB_AIRCR will erase boot bits . I suppose it could be possible to use another kind of reset to do so...

2) no solution for MikroC (I suppose there is one but using asm codes (I assume that there is indeed a solution, but it involves using arrays of assembly code). Yet, a program in MikroC is much more convenient to transfer from one PC to another: Stm32CubeIde doesn't even allow renaming a folder on the same PC!


 

Right. Resetting is not a valid approach to jumping to code from non-default locations. All registers (well, almost all) are reset to their "reset values". Just like setting register values and toggling the NRST pin wouldn't do anything.

Why isn't the linked code able to be ran in MikroC?

Why can't you rename folders? STM32CubeIDE certainly doesn't have this restriction:

TDK_0-1704812812551.png

 

If you feel a post has answered your question, please click "Accept as Solution".

Here a new test, with STM32Cube. Of course it doesn't work

//------------------------------------------
 
(main.h)
#define BOOTLOADER_AD        0x08000400  
#define PROG1_VECT_AD        0x0800C400  
#define PROG1_AD             0x0800C800  
#define PROG2_VECT_AD        0x08036000  
#define PROG2_AD             0x08036400  
 
typedef void (application_t)(void);
 
typedef struct
{
uint32_t stack_addr;
application_t* func_p;
} JumpStruct;
 
//------------------------------------------
 
 
(main.c)
 
void jumpToApp(const uint32_t address)
{
const JumpStruct* vector_p = (JumpStruct*)address;
 
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOD_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
    __HAL_RCC_GPIOA_CLK_DISABLE();
    HAL_I2C_DeInit(&hi2c1);
HAL_RCC_DeInit();
HAL_DeInit();
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
 
    // asm to avoid stack optimization
    asm("msr msp, %0; bx %1;" : : "r"(vector_p->stack_addr), "r"(vector_p->func_p));
}
 
int main(void)
{
 
HAL_Init();
    SystemClock_Config();
MX_GPIO_Init();
M24M02_Init_Pins();
MX_ADC_Init();
Wait100ms(); 
MX_I2C1_Init();
Wait100ms();
LED_ON
 
 
I2C_Ctrl(); 
jumpToApp(PROG1_VECT_AD);

For renamed folders with STMCube, the problem is that I need to do a new project using "IOC" file , redo generating code and , after, copy saved "main.c"... 
If not I have link problems.
He you can see the "bin" file I have so vectors are OK but, anyway, it doesn't jump to 0xC800 (so here with last STM32CubeIde files) 

JFELI13_0-1704813802702.png

 

Two possibilities, no effect.  I'm pretty sure there's something special about STM32L151RDT6

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


void jump1(const uint32_t address)
{
const JumpStruct* vector_p = (JumpStruct*)address;
 
    HAL_I2C_DeInit(&hi2c1);
HAL_RCC_DeInit();
HAL_DeInit();
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
 
    // asm to avoid stack optimization
    asm("msr msp, %0; bx %1;" : : "r"(vector_p->stack_addr), "r"(vector_p->func_p));
 
while(1)
{
HAL_GPIO_TogglePin(Led10_GPIO_Port, Led10_Pin);
HAL_Delay(30);
}
}
 
//-----------------------------------------------------------------------------
 
bool jump2(uint32_t address)
{
 
uint32_t reset_handler_add = *((volatile uint32_t *) (address+4));
void (*app_reset_handler)(void) = (void*) reset_handler_add;
 
 
HAL_I2C_DeInit(&hi2c1);
HAL_RCC_DeInit();
HAL_DeInit();
 
 
SysTick->CTRL = 0x0;
SysTick->LOAD=0;
SysTick->VAL=0;
 
//disable interrupts
__disable_irq();
__DSB();
__ISB();
 
SCB->VTOR = address;
uint32_t msp_value = *((volatile uint32_t *)address);
__set_MSP(msp_value);
app_reset_handler();
while(1)
{
HAL_GPIO_TogglePin(Led10_GPIO_Port, Led10_Pin);
HAL_Delay(30);
}
return true; 
}