cancel
Showing results for 
Search instead for 
Did you mean: 

Stm32f103 Memory Jumping with parameters

cnhx27
Associate III
Posted on December 17, 2014 at 13:46

Hello,

I'm working with the STM32f103RB and I'm trying to jump to a section of flash where I will begin executing another program there

My code should look like this (variable ApplicationAddress is 0x08008000) :

 

__disable_irq();

  JumpAddress = (uint32_t) (void *) ApplicationAddress + 4;

  Jump_To_Application = (pFunction) JumpAddress;

  /* Initialize user application's Stack Pointer */

  __set_MSP(*(__IO uint32_t*) ApplicationAddress;

  Jump_To_Application();

But I will executing another program with paramaters (like main(int argc, char * argv[])

Is it possible ? Have you some idea to do that ?

Thank you

#stm32f1xx #jump-address-flash
9 REPLIES 9
ivani
Associate II
Posted on December 17, 2014 at 15:10 For example:

typedef void(*pfunc_arg)(int argc, char * argv[]);
(( pfunc_arg )0x08008000)(1, arg);

But it is not quite a good idea to jump directly to main(). Before jumping to it the compiler first initializes the global variables, which will not be done if you jump directly.
Posted on December 17, 2014 at 16:09

Thumb code addresses would be ODD, parameters for most ABI will use R0..R3 for the first 4 parameters.

You would change the function pointer to define parameters, as you would with the classic qsort() function passing scheme.

As Ivan indicates main() really isn't the first thing called, typically some C run time start up code initializes statics (copies or zeros RAM based data). If you expect the call to return you should also be careful that the RAM regions between the two do not overlap.

A common method to pass command line data would be to have a memory structure the both loader/app share. This could be a fixed location carved out of the memory space they would otherwise use.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
cnhx27
Associate III
Posted on December 17, 2014 at 16:11

I don't want to jump directly to main() (main() is cited as an example).

I would jump to 

MyTestFunc(int n_argc, char * n_argv[])

I do this

    const char* n_argv[] = { ''param0'', ''param1'', ''param2'' };

    const int n_argc = 3;

   (( pfunc_arg )0x08008000)(n_argc, n_argv);

   

But in

MyTestFunc(...)

, it seems

n_argc

n_argv

contain no values, not initialize ?

cnhx27
Associate III
Posted on December 17, 2014 at 16:15

A common method to pass command line data would be to have a memory structure the both loader/app share. This could be a fixed location carved out of the memory space they would otherwise use.

clive1, do you have some example to do that ?
Posted on December 17, 2014 at 17:44

clive1, do you have some example to do that ?

I write code for a living...

typedef struct _PARMS {
int argc;
char *argv[32]; // Enough to hold # parameters
char *allocptr;
char buffer[512]; // Enough to hold parameter strings
} PARMS;
PARMS *parms = (PARMS *)0x2000FC00; // 1KB at the end of 64KB
void buildparms(int argc, char *argv[])
{
int i;
memset(parms, 0x00, sizeof(PARMS));
parms->allocptr = parms->buffer;
parms->argc = argc;
for(i=0; i<
argc
; i++)
{
parms->argv[i] = parms->allocptr;
strcpy(parms->argv[i], argv[i]);
parms->allocptr += strlen(argv[i]) + 1;
}
} // sourcer32@gmail.com

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ivani
Associate II
Posted on December 17, 2014 at 20:50

Thumb code addresses would be ODD

Yes, it was my oversight.
cnhx27
Associate III
Posted on December 17, 2014 at 21:11

With STM32F103 : 128 Kbytes of Flash & 20 Kbytes of SRAM

/* Flash Memory */

#define FLASH_START           (0x08000000)

#define FLASH_SIZE            (0x00020000)  // 128 KBytes

/* SRAMMemory */

#define SRAM_START            (0x20000000)

#define SRAM_SIZE             (0x00005000)  // 20 KBytes

#define PAGE_SIZE             (0x400)       // 1 Kbyte

From

your example

, I made

this code

.

Program.bin

=>

Load Updater.bin

in Flash memory (at address:

0x0801c400

) => Load

demo_key.bin

(at address:

0x08000000

)

but

, in Updater.bin,

it does not work

if use directly

ParamsUpdater.FlashMemoryAdress

.

If initialize

ParamsUpdater.FlashMemoryAdress

to 

0x08000000

, It's OK

Program.bin

 

=========

typedef  void (*pFunction)(void);

uint32_t JumpAddress;

pFunction Jump_To_Application;

typedef struct {

    // Name of the program to load

    char ProgrammName[11];

    // Address where program is loaded in flash memory

    uint32_t FlashMemoryAdress;

    // if is equal to 1 then software reset

    uint8_t SoftReset;

    // if is equal to 1 then call program

    uint8_t StartProgramm;

} structParamsUpdater;

#define AdressParamsUpdater  (*((structParamsUpdater *) (SRAM_START + SRAM_SIZE - 0x14))) // Reserved 20 bytes => sizeof(structParamsUpdater)

int main(void)

{

    structParamsUpdater ParamsUpdater = AdressParamsUpdater;

    memset(&ParamsUpdater, 0x00, sizeof(structParamsUpdater));

    strcpy(ParamsUpdater.ProgrammName,''demo_key.bin'');

    ParamsUpdater.FlashMemoryAdress = 0x08000000;

    ParamsUpdater.SoftReset = 1;

    ParamsUpdater.StartProgramm = 2;

    // Program to load in flash is programmed starting from this address

    uint32_t ProgramLoadAddress = (FLASH_START + FLASH_SIZE - 15 * PAGE_SIZE);

    if (FLASH_LoadBin(''Updater.bin'', ProgramLoadAddress) == FLASH_OK) {

        // User loaded in Flash and programmed starting from address ''ProgramLoadAddress''

        if (((*(volatile uint32_t*)ProgramLoadAddress) & 0x2FFE0000 ) == 0x20000000)

        {

            // Initialize user application's Stack Pointer

            __set_MSP(*(volatile uint32_t*) ProgramLoadAddress);

            // Jump to user application

            uint32_t JumpAddress = *(volatile uint32_t*) (ProgramLoadAddress + 4);

            pFunction Jump_To_Application = (pFunction) JumpAddress;

          Jump_To_Application();

          }

    }

    return 0;

}

Updater.bin

 

=========

typedef  void (*pFunction)(void);

uint32_t JumpAddress;

pFunction Jump_To_Application;

typedef struct {

    char ProgrammName[11];

    uint32_t FlashMemoryAdress;

    uint8_t SoftReset;

    uint8_t StartProgramm;

} structParamsUpdater;

#define AdressParamsUpdater  (*((structParamsUpdater *) (SRAM_START + SRAM_SIZE - 0x14))) // Reserved 20 bytes => sizeof(structParamsUpdater)

int main()

{

    // When generating bin, make sure to

    //  1- To compile the image at correct address (0x0801c400 in this case) => Configuration Memory Area Start : 0x0801c400

    //  2- Call function NVIC_SetVectorTable(NVIC_VectTab_FLASH, OffsetAddress) with correct offset (0x1c400 in this case) => NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x1c400);

    // Program to load in flash is programmed starting from this address: 0x0801c400

    uint32_t ProgramAddress =  (FLASH_START + FLASH_SIZE - 15 * PAGE_SIZE);

    uint32_t OffsetAddress = ProgramAddress - FLASH_START;

    NVIC_SetVectorTable(NVIC_VectTab_FLASH, OffsetAddress);

    structParamsUpdater ParamsUpdater = AdressParamsUpdater;

    //ParamsUpdater.FlashMemoryAdress = 0x08000000; // => It's OK

    if (FLASH_LoadBin(''demo_key.bin'', ParamsUpdater.FlashMemoryAdress) == FLASH_OK) {  // => It''s KO

          // Initialize user application's Stack Pointer

          __set_MSP(*(volatile uint32_t*) ParamsUpdater.FlashMemoryAdress);

          // Jump to user application

          uint32_t JumpAddress = *(volatile uint32_t*) (ParamsUpdater.FlashMemoryAdress + 4);

          pFunction Jump_To_Application = (pFunction) JumpAddress;

          Jump_To_Application();

    }

    return 0;

}

ivani
Associate II
Posted on December 18, 2014 at 08:34 Probably something is overwriting the location of ParamsUpdater. Where is the stack of all these functions located? Could it be at the end of the RAM? Also, you have defined

char ProgrammName[11];

but the names you write there are longer. It's true that ParamsUpdater.FlashMemoryAdress is initialized after the string, but anyway.
cnhx27
Associate III
Posted on December 19, 2014 at 15:20

clive1, Thanks for your example. With this I found my error.

It's OK with this code

typedef struct {

    // Name of the program to load

    char ProgrammName[12];

    // Address where program is loaded in flash memory

    uint32_t FlashMemoryAdress;

    // if is equal to 1 then software reset

    uint8_t SoftReset;

    // if is equal to 1 then call program

    uint8_t StartProgramm;

} structParamsUpdater;

Program.bin

=========

    structParamsUpdater *parms = (structParamsUpdater *) (SRAM_START + SRAM_SIZE - sizeof(structParamsUpdater)); // at the end of 20KB

    memset(parms, 0x00, sizeof(structParamsUpdater));

    strcpy(parms->ProgrammName,''demo_key.bin'');

    parms->FlashMemoryAdress = 0x08000000;

    parms->SoftReset = 1;

    parms->StartProgramm = 2;

Updater.bin

 

=========

    structParamsUpdater *parms = (structParamsUpdater *) (SRAM_START + SRAM_SIZE - sizeof(structParamsUpdater));

    if (FLASH_LoadBin(parms->ProgrammName, parms->FlashMemoryAdress) == FLASH_OK) { .... }