"Goto" difference between STM32F051 and STM32L151 ?

General discussion on mikroC PRO for ARM.
Post Reply
Author
Message
orpheedulogis
Posts: 240
Joined: 16 Jan 2010 22:26

"Goto" difference between STM32F051 and STM32L151 ?

#1 Post by orpheedulogis » 12 May 2023 12:29

Hi,

For the STM32F051 I use this to "goto" a soft at 0x400 and it work:


Code: Select all

void Set_VectorsCodes(unsigned long SP,unsigned long PC) // OK
{
    unsigned int x2;
    unsigned long *ptr=VECT_PG_ADDR+8,x4,y4;

    x4=*ptr;
    ptr++;
    y4=*ptr;
    if(x4!=SP || y4!=PC ) // purpose: do not write at each request if no difference
    {
        FLASH_Unlock();
        FLASH_ErasePage(VECT_PG_ADDR);
        FLASH_Write_HalfWord(VECT_PG_ADDR, 0x4801);
        FLASH_Write_HalfWord(VECT_PG_ADDR+2, 0x4685);
        FLASH_Write_HalfWord(VECT_PG_ADDR+4, 0x4801);
        FLASH_Write_HalfWord(VECT_PG_ADDR+6, 0x4700);
        x2=(unsigned int)SP;
        FLASH_Write_HalfWord(VECT_PG_ADDR+8, x2);  
        x2=(unsigned int)(SP>>16);
        FLASH_Write_HalfWord(VECT_PG_ADDR+10, x2); 
        x2=(unsigned int)PC;
        FLASH_Write_HalfWord(VECT_PG_ADDR+12, x2); 
        x2=(unsigned int)(PC>>16);
        FLASH_Write_HalfWord(VECT_PG_ADDR+14, x2); 
        FLASH_Lock();
    }
}
So I decided to do the same thing for a STM32L151 ... but it doesn't work (it freeze as soon I call 0x400 soft)

Code: Select all

//------------------------------------------------------------------------------
void Set_VectorsCodes(unsigned long SP,unsigned long PC) /
{
    unsigned long *ptr=VECT_PG_ADDR+8,x4,y4;

    x4=*ptr;
    ptr++;
    y4=*ptr;
    if(x4!=SP || y4!=PC ) // purpose: do not write at each request if no difference
    {
        FLASH_Unlock();
        FLASH_ErasePage(VECT_PG_ADDR);
        FLASH_Write_Word(VECT_PG_ADDR, 0x48014685);
        FLASH_Write_Word(VECT_PG_ADDR+4, 0x48014700);
        FLASH_Write_Word(VECT_PG_ADDR+8, SP);  
        FLASH_Write_Word(VECT_PG_ADDR+12,PC); 
        FLASH_Lock();
    }
}
Is there something different to call a "goto" on STM32F0 and STM32L1 ?
( of course I read the flash at VECT_PG_ADDR and have : 48014685 48014700 2000BFFC 00000401 )

Thanks for help

orpheedulogis
Posts: 240
Joined: 16 Jan 2010 22:26

Re: "Goto" difference between STM32F051 and STM32L151 ?

#2 Post by orpheedulogis » 12 May 2023 16:26

I'm pretty sure it's asm codes (cortex M0 vs M3)
I tried this but it doesn't work too

Code: Select all

        FLASH_Write_Word(VECT_PG_ADDR,    0xA4046012);
        FLASH_Write_Word(VECT_PG_ADDR+4,  0xA4046811);
        FLASH_Write_Word(VECT_PG_ADDR+8,  0x46984612);
        FLASH_Write_Word(VECT_PG_ADDR+12, 0x68084700);
        FLASH_Write_Word(VECT_PG_ADDR+16, SP);
        FLASH_Write_Word(VECT_PG_ADDR+20, PC);

AntiMember
Posts: 136
Joined: 02 Jan 2020 19:00

Re: "Goto" difference between STM32F051 and STM32L151 ?

#3 Post by AntiMember » 13 May 2023 19:20

00000000 01 48 LDR R0, =0x400
00000002 85 46 MOV SP, R0
00000004 01 48 LDR R0, = DCD 0x300
00000006 00 47 BX R0 ; //DCD loc_300
00000008 00 04 00 00 off_8 DCD 0x400
0000000C 00 03 00 00 off_C DCD loc_300

This is true for M0 (ARM6M) and M3 (ARM7M).
01 48 85 46 01 48 00 47 00 04 00 00 00 03 00 00

orpheedulogis
Posts: 240
Joined: 16 Jan 2010 22:26

Re: "Goto" difference between STM32F051 and STM32L151 ?

#4 Post by orpheedulogis » 14 May 2023 17:21

Hi AntiMember
You are my last hope: I tried many many thing with no success !

So, according to your suggestion, I wrote the following code but it doesn't work. If I take a look on registers PC is at 0x5CFDE (bootloader area)
I précise that the principle is exactly the same as that used with the STM32F051 (who works): the contents of address 0x0 and 0x4 are stored at the 'orgall' address of the program that must be launched minus 8 bytes. In fact I use a file including bootloaders and 2 softs, one start at 0x400 and one at 0x2E000

Many thanks for help.

Code: Select all

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

void Set_VectorsCodes(unsigned long SP2,unsigned long PC2) // here SP2 and PC2 are initial vectors (initial adresses 0x0 and 0x4) of soft who start at 0x400 (or 0x0x2E000) - Those vectors are writed at 0400-8 (or 0x2E000-8)
{
    unsigned int x2;
    unsigned long *ptr=VECT_PG_ADDR+8,x4,y4;

    x4=*ptr;
    ptr++;
    y4=*ptr;
    if(x4!=SP2 || y4!=PC2 )
    {
        FLASH_Unlock();
        FLASH_ErasePage(VECT_PG_ADDR);
       
        FLASH_Write_Word((unsigned long)(VECT_PG_ADDR),   0x01488548);  // LDR R0, =0x400  + MOV SP, R0
        FLASH_Write_Word((unsigned long)(VECT_PG_ADDR+4), 0x01480047);  // LDR R0,=DCD 0x300    +  BX R0
        FLASH_Write_Word((unsigned long)(VECT_PG_ADDR+8), 0x00040000);  // DCD 0x400
        FLASH_Write_Word((unsigned long)(VECT_PG_ADDR),   0x00030000);  // DCD loc_300
        FLASH_Lock();
        

        #ifdef OLED
        Display_LineCode(5,"SP: ",VALUETYPE_HEXA32,SP2,0);
        Display_LineCode(6,"PC: ",VALUETYPE_HEXA32,PC2,0);
        #endif
        

    }
}

AntiMember
Posts: 136
Joined: 02 Jan 2020 19:00

Re: "Goto" difference between STM32F051 and STM32L151 ?

#5 Post by AntiMember » 14 May 2023 19:11

FLASH_Write_Word((unsigned long)(VECT_PG_ADDR), 0x46854801); // LDR R0, =0x400 + MOV SP, R0
FLASH_Write_Word((unsigned long)(VECT_PG_ADDR+4), 0x47004801); // LDR R0,=DCD 0x300 + BX R0

orpheedulogis
Posts: 240
Joined: 16 Jan 2010 22:26

Re: "Goto" difference between STM32F051 and STM32L151 ?

#6 Post by orpheedulogis » 14 May 2023 19:58

I first tried those codes but it doesn't works

Code: Select all

//------------------------------------------------------------------------------
void Set_VectorsCodes(unsigned long SP,unsigned long PC) /
{
    unsigned long *ptr=VECT_PG_ADDR+8,x4,y4;

    x4=*ptr;
    ptr++;
    y4=*ptr;
    if(x4!=SP || y4!=PC ) // purpose: do not write at each request if no difference
    {
        FLASH_Unlock();
        FLASH_ErasePage(VECT_PG_ADDR);
        FLASH_Write_Word(VECT_PG_ADDR, 0x48014685);
        FLASH_Write_Word(VECT_PG_ADDR+4, 0x48014700);
        FLASH_Write_Word(VECT_PG_ADDR+8, SP);  
        FLASH_Write_Word(VECT_PG_ADDR+12,PC); 
        FLASH_Lock();
    }
}
Last edited by orpheedulogis on 15 May 2023 10:02, edited 1 time in total.

AntiMember
Posts: 136
Joined: 02 Jan 2020 19:00

Re: "Goto" difference between STM32F051 and STM32L151 ?

#7 Post by AntiMember » 14 May 2023 20:25

Once again:

Code: Select all

//------------------------------------------------------------------------------
void Set_VectorsCodes(unsigned long SP,unsigned long PC) /
{
    unsigned long *ptr=VECT_PG_ADDR+8,x4,y4;

    x4=*ptr;
    ptr++;
    y4=*ptr;
    if(x4!=SP || y4!=PC ) // purpose: do not write at each request if no difference
    {
        FLASH_Unlock();
        FLASH_ErasePage(VECT_PG_ADDR);
        FLASH_Write_Word(VECT_PG_ADDR, 0x46854801);
        FLASH_Write_Word(VECT_PG_ADDR+4, 0x47004801);
        FLASH_Write_Word(VECT_PG_ADDR+8, SP);  
        FLASH_Write_Word(VECT_PG_ADDR+12,PC); 
        FLASH_Lock();
    }
}

orpheedulogis
Posts: 240
Joined: 16 Jan 2010 22:26

Re: "Goto" difference between STM32F051 and STM32L151 ?

#8 Post by orpheedulogis » 15 May 2023 06:18

Please take a look at this


For the STM32F051, this works:

Declarations:

Code: Select all

#define BaseAd 0x5C00
#pragma orgall BaseAd
#define BOOTLOADER_START_ADDR BaseAd
#define VECT_PG_ADDR 0x7C00
#define PROGRAM1_ADDR 0x400
#define PROGRAM2_ADDR 0x3000
Code:

Code: Select all

//------------------------------------------------------------------------------
void Set_VectorsCodes(unsigned long SP2,unsigned long PC2)
{
    unsigned int x2;
    unsigned long *ptr=VECT_PG_ADDR+8,x4,y4;

    x4=*ptr;
    ptr++;
    y4=*ptr;
    if(x4!=SP2 || y4!=PC2 )
    {
        FLASH_Unlock();
        FLASH_ErasePage(VECT_PG_ADDR);
        FLASH_Write_HalfWord(VECT_PG_ADDR, 0x4801);
        FLASH_Write_HalfWord(VECT_PG_ADDR+2, 0x4685);
        FLASH_Write_HalfWord(VECT_PG_ADDR+4, 0x4801);
        FLASH_Write_HalfWord(VECT_PG_ADDR+6, 0x4700);
        x2=(unsigned int)SP2;
        FLASH_Write_HalfWord(VECT_PG_ADDR+8, x2); 
        x2=(unsigned int)(SP2>>16);
        FLASH_Write_HalfWord(VECT_PG_ADDR+10, x2); 
        x2=(unsigned int)PC2;
        FLASH_Write_HalfWord(VECT_PG_ADDR+12, x2); 
        x2=(unsigned int)(PC2>>16);
        FLASH_Write_HalfWord(VECT_PG_ADDR+14, x2); 
        FLASH_Lock();
    }
}
At VECT_PG_ADDR I can read: 46854801 47004801 20001FFC 00003001
In my test I can alternatively use "PROGRAM1"(0x400) and "PROGRAM2" (0x0x3000)


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

For the STM32L151 this doesn't work:

Declarations:

Code: Select all

#define BOOTLOADER_ADRESS 0x5B000  
#define VECT_PG_ADDR      0x5FF00  
#define PROGRAM1_ADDR     0x400  
#define PROGRAM2_ADDR     0x2E000  
#pragma orgall BOOTLOADER_ADRESS

Code:

Code: Select all

//------------------------------------------------------------------------------
void Set_VectorsCodes(unsigned long SP2,unsigned long PC2) 
{
    unsigned int x2;
    unsigned long *ptr=VECT_PG_ADDR+8,x4,y4;

    x4=*ptr;
    ptr++;
    y4=*ptr;
    if(x4!=SP2 || y4!=PC2 )
    {
        FLASH_Unlock();
        FLASH_ErasePage(VECT_PG_ADDR);

        FLASH_Write_Word(VECT_PG_ADDR, 0x46854801);
        FLASH_Write_Word(VECT_PG_ADDR+4, 0x47004801);
        FLASH_Write_Word(VECT_PG_ADDR+8, SP2);
        FLASH_Write_Word(VECT_PG_ADDR+12,PC2);
        FLASH_Lock();
}
//------------------------------------------------------------------------------
This code cause:
At VECT_PG_ADDR I can read: 46854801 47004801 2000BFFC 00000401
PC register : 0x5CFEA (so in bootloader area) and , of course, impossible to run 0x400


orpheedulogis
Posts: 240
Joined: 16 Jan 2010 22:26

Re: "Goto" difference between STM32F051 and STM32L151 ?

#10 Post by orpheedulogis » 16 May 2023 13:57

I think the problem come from VTOR (STM32F051 has no VTOR). Cortex M0 and M3 are different.

I made this but PC register value is 0x501A . Better than before (it was staying at bootloader area) but not correct

Code: Select all

#define BOOTLOADER_ADRESS 0x5B000
#define VECT_PG_ADDR      0x5FE00 
#define VECT_OFFSET 0x200
#define PROGRAM1_ADDR     0x600  
#define PROGRAM2_ADDR     0x2E050 

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

#pragma orgall BOOTLOADER_ADRESS

void TestJump()
{
    unsigned long x4;
    FunctionPointer functionPointer;

    union 
    {
        unsigned long addr;
        FunctionPointer funcPtr;
    } jump;
    
    jump.addr = PROGRAM1_ADDR;
    x4=PROGRAM1_ADDR-VECT_OFFSET;
    //SCB_VTOR=x4;
    SCB_VTOR=0x8000400; 
    x4=SCB_VTOR;
    asm ISB  // Instruction Synchronization Barrier
    asm DSB  // Data Synchronization Barrier
    asm SEV  // Send Event
    jump.funcPtr();
    delay_ms(3000);
}

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



orpheedulogis
Posts: 240
Joined: 16 Jan 2010 22:26

Re: "Goto" difference between STM32F051 and STM32L151 ?

#11 Post by orpheedulogis » 16 May 2023 16:07

Where I'm actually. The "best" result: PC register is in program area.
Can mikroC team take a look here ? how do you make your "uartbootloader" for STM32 M3 or M4 ?? it's only works for M0.
Here I copy values from original program bin file vectors (adress 0... ) in bootloader file, at PROGRAM1_ADDR-0x200
If I look flash values everything is correct: I have a mix from bootloader, program vectors and program.

Code: Select all

#define BOOTLOADER_ADRESS 0x5B000  
#define VECT_PG_ADDR      0x5FE00  
#define VECT_OFFSET 0x200 // indicate where values from original program bin file are copied (of course bootloader keep is area)
#define PROGRAM1_ADDR     0x600    // ... <0x326FF 
#define PROGRAM2_ADDR     0x2E200  // ... <0x5B000


void TestJump() //  PC=4671
{
    unsigned long x4;
    FunctionPointer functionPointer;

    union
    {
        unsigned long addr;
        FunctionPointer funcPtr;
    } jump;

    jump.addr = PROGRAM1_ADDR; //0x600
    x4=PROGRAM1_ADDR-VECT_OFFSET;
    SCB_VTOR=x4;

    x4=SCB_VTOR;
    #ifdef OLED
    Display_LineCode(3,"VTOR:",VALUETYPE_HEXA32,x4,0);
    #endif
    asm ISB  // Instruction Synchronization Barrier
    asm DSB  // Data Synchronization Barrier
    asm SEV  // Send Event
    jump.funcPtr();  //-> PC=4672 - this equal flash value from  PC+8 (4671) increased by 1
    delay_ms(3000);

}

orpheedulogis
Posts: 240
Joined: 16 Jan 2010 22:26

Re: "Goto" difference between STM32F051 and STM32L151 ?

#12 Post by orpheedulogis » 22 May 2023 18:32

And I found the solution... using STM32CubeIDE !

Post Reply

Return to “mikroC PRO for ARM General”