EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

copy code from flash to RAM and then execute it from RAM

Started by karabliley October 7, 2005
I'm currently programming in C and using IAR Workbench.

My goal is to copy a function from flash into RAM and then execute 
the function from RAM; the function has a few variables that need to 
be passed in.

I'm able to copy the code from flash to RAM, but I'm having trouble 
with the execution, especially because I have variables that need to 
be passed. Below I've included an excerpt of my code. I declared a 
function pointer, but then I don't what to set it to. If I set it 
to "load_program" which is the name of the function, it points to the 
function at its flash memory location.

Thanks for your help,
Kara

An excerpt of my code (my apologies for the wrapping):  

void updateFirmware() {
    unsigned long res;
    unsigned long addr,filesize;
    unsigned int seg_start_addr,seg_end_addr;
    unsigned char *Flash_ptr,*RAM_ptr,*RAM_start;
    int **tmpPtr;
    int (*RAM_load_program)(unsigned long addr,unsigned long 
filesize,unsigned short flash_addr, unsigned char resetFlag) &load_program; 
//but this makes it point to the function in flash

//    tmpPtr =  (int **)RAM_load_program; // other tries, that failed
//    *(*tmpPtr) = (FAT_mem;

    //RAM_load_program = FAT_mem;

    fileEntry = fopen("FIRM",0);

    if(!fileEntry) return;

    addr = getAddrOnDisk(fileEntry);
    SD_ReadDataBlock(addr, 1, userBuffer);
    filesize = fileEntry->Size;

    //copy load program to RAM
      seg_start_addr = 0xF800;
      seg_end_addr = 0xFDFF;
      
      Flash_ptr = (unsigned char *) seg_start_addr;
      RAM_start = FAT_mem; //FAT_mem points to address in RAM not used
      RAM_ptr = RAM_start;
      do{
        *RAM_ptr = *Flash_ptr;

        RAM_ptr++;
        Flash_ptr++;
      }while((unsigned int)(Flash_ptr) <= seg_end_addr);

      //run load_program from RAM
      //*(load_program_ptr_in_RAM)(args)
      (*RAM_load_program)(addr,filesize,0x1100,1); //STILL POINTING 
TO FLASH MEMORY LOCATION OF LOAD_PROGRAM


    //load_program(addr,fileEntry->Size,0x1100,1);
    
    return;

}






Beginning Microcontrollers with the MSP430

Kara,

I've used these advanced compiler features many times before, for Flash
programming on other micros. I guess that's what you are doing ?
Although it's a bit unusual to need RAM code on MSP430 when you can
program Flash whilst execution from Flash (albeit 40usec delay). If you
need to receive comms data at the same time, you need to execute RAM
code, copied from ROM, yes? It's a tricky subject if you've not done
it
before. And it's been a while, 

So from memory, there are a couple of critical IAR aspects you need to
get your head round:-
1) Create NEW code & constant segments in the linker command file.
2) Use he linker -P & -Q options, to associate the separate execution
and storage areas.
3) Separate any RAM overlays eg erase function and flash-write function
into separate source files because the #pragma code segment and can only
be used ONCE per file, and don't forget to also use #pragma
new_const_area.
4) Create and remember to call a segment copy routine.

The above will mean all your debug symbols will be in the correct place
at run time. Despite tightly packed segments built storage for ROM
space. If you are reprogramming Flash you have to be careful the
routines don't call any library functions. So, once you got it working
remember NOT to change the global optimisation settings for these
separate files. Ideally, remove these source files from the project and
instead add only the *.rxx files back to the project, to avoid a global
make, destroying the test case build.

I'm sorry I've scribbled this down a bit quick, but it should be
enough
to point you in the right direction. I have to go now. Good luck.

Colin,
 
-----Original Message-----
From: msp430@msp4... [mailto:msp430@msp4...] On Behalf
Of karabliley
Sent: 07 October 2005 20:09
To: msp430@msp4...
Subject: [msp430] copy code from flash to RAM and then execute it from
RAM

I'm currently programming in C and using IAR Workbench.

My goal is to copy a function from flash into RAM and then execute the
function from RAM; the function has a few variables that need to be
passed in.

I'm able to copy the code from flash to RAM, but I'm having trouble
with
the execution, especially because I have variables that need to be
passed. Below I've included an excerpt of my code. I declared a function
pointer, but then I don't what to set it to. If I set it to
"load_program" which is the name of the function, it points to the
function at its flash memory location.

Thanks for your help,
Kara

An excerpt of my code (my apologies for the wrapping):  

void updateFirmware() {
    unsigned long res;
    unsigned long addr,filesize;
    unsigned int seg_start_addr,seg_end_addr;
    unsigned char *Flash_ptr,*RAM_ptr,*RAM_start;
    int **tmpPtr;
    int (*RAM_load_program)(unsigned long addr,unsigned long
filesize,unsigned short flash_addr, unsigned char resetFlag) &load_program; 
//but this makes it point to the function in flash

//    tmpPtr =  (int **)RAM_load_program; // other tries, that failed
//    *(*tmpPtr) = (FAT_mem;

    //RAM_load_program = FAT_mem;

    fileEntry = fopen("FIRM",0);

    if(!fileEntry) return;

    addr = getAddrOnDisk(fileEntry);
    SD_ReadDataBlock(addr, 1, userBuffer);
    filesize = fileEntry->Size;

    //copy load program to RAM
      seg_start_addr = 0xF800;
      seg_end_addr = 0xFDFF;
      
      Flash_ptr = (unsigned char *) seg_start_addr;
      RAM_start = FAT_mem; //FAT_mem points to address in RAM not used
      RAM_ptr = RAM_start;
      do{
        *RAM_ptr = *Flash_ptr;

        RAM_ptr++;
        Flash_ptr++;
      }while((unsigned int)(Flash_ptr) <= seg_end_addr);

      //run load_program from RAM
      //*(load_program_ptr_in_RAM)(args)
      (*RAM_load_program)(addr,filesize,0x1100,1); //STILL POINTING TO
FLASH MEMORY LOCATION OF LOAD_PROGRAM


    //load_program(addr,fileEntry->Size,0x1100,1);
    
    return;

}








.

 
Yahoo! Groups Links



 





Colin-

Thanks for the note.  I think that I am completing the steps that you 
suggest.  In the build options, I define the specific segments 
correctly within the flash memory.   The code that I originally 
posted copies the code from the pre-defined flash segment to RAM.  
The RAM segment is not specifically defined to a region of RAM, the 
compiler is allocating the chunk of RAM to meet my needs (esentially, 
I define a variable that is 512b in size and use that for several 
purposes).  In using the IAR debugger, it appears that everything 
copies correctly.

My primary problem is executing the code out of RAM.  I can't seem to 
get my function point to point correctly to the function in RAM.  
Basically, the compiler throws an error whenever I put in the address 
that I want to execute from.

I am hoping that there is only a syntax error in my c code, but I am 
not sure.  So, I need to find the correct method for dynamically 
calling a function from RAM.  

Thanks

kara

--- In msp430@msp4..., "Garlick, Colin" <c-garlick2@t...> 
wrote:
>
> 
> Kara,
> 
> I've used these advanced compiler features many times before, for 
Flash
> programming on other micros. I guess that's
what you are doing ?
> Although it's a bit unusual to need RAM code on MSP430 when you can
> program Flash whilst execution from Flash (albeit 40usec delay). If 
you
> need to receive comms data at the same time, you
need to execute RAM
> code, copied from ROM, yes? It's a tricky subject if you've not 
done it
> before. And it's been a while, 
> 
> So from memory, there are a couple of critical IAR aspects you need 
to
> get your head round:-
> 1) Create NEW code & constant segments in the linker command file.
> 2) Use he linker -P & -Q options, to associate the separate 
execution
> and storage areas.
> 3) Separate any RAM overlays eg erase function and flash-write 
function
> into separate source files because the #pragma
code segment and can 
only
> be used ONCE per file, and don't forget to
also use #pragma
> new_const_area.
> 4) Create and remember to call a segment copy routine.
> 
> The above will mean all your debug symbols will be in the correct 
place
> at run time. Despite tightly packed segments built
storage for ROM
> space. If you are reprogramming Flash you have to be careful the
> routines don't call any library functions. So, once you got it 
working
> remember NOT to change the global optimisation
settings for these
> separate files. Ideally, remove these source files from the project 
and
> instead add only the *.rxx files back to the
project, to avoid a 
global
> make, destroying the test case build.
> 
> I'm sorry I've scribbled this down a bit quick, but it should be 
enough
> to point you in the right direction. I have to go
now. Good luck.
> 
> Colin,
>  
> -----Original Message-----
> From: msp430@msp4... [mailto:msp430@msp4...] On 
Behalf
> Of karabliley
> Sent: 07 October 2005 20:09
> To: msp430@msp4...
> Subject: [msp430] copy code from flash to RAM and then execute it 
from
> RAM
> 
> I'm currently programming in C and using IAR Workbench.
> 
> My goal is to copy a function from flash into RAM and then execute 
the
> function from RAM; the function has a few
variables that need to be
> passed in.
> 
> I'm able to copy the code from flash to RAM, but I'm having
trouble 
with
> the execution, especially because I have variables
that need to be
> passed. Below I've included an excerpt of my code. I declared a 
function
> pointer, but then I don't what to set it to.
If I set it to
> "load_program" which is the name of the function, it points to
the
> function at its flash memory location.
> 
> Thanks for your help,
> Kara
> 
> An excerpt of my code (my apologies for the wrapping):  
> 
> void updateFirmware() {
>     unsigned long res;
>     unsigned long addr,filesize;
>     unsigned int seg_start_addr,seg_end_addr;
>     unsigned char *Flash_ptr,*RAM_ptr,*RAM_start;
>     int **tmpPtr;
>     int (*RAM_load_program)(unsigned long addr,unsigned long
> filesize,unsigned short flash_addr, unsigned char resetFlag) >
&load_program;  //but this makes it point to the function in flash
> 
> //    tmpPtr =  (int **)RAM_load_program; // other tries, that 
failed
> //    *(*tmpPtr) = (FAT_mem;
> 
>     //RAM_load_program = FAT_mem;
> 
>     fileEntry = fopen("FIRM",0);
> 
>     if(!fileEntry) return;
> 
>     addr = getAddrOnDisk(fileEntry);
>     SD_ReadDataBlock(addr, 1, userBuffer);
>     filesize = fileEntry->Size;
> 
>     //copy load program to RAM
>       seg_start_addr = 0xF800;
>       seg_end_addr = 0xFDFF;
>       
>       Flash_ptr = (unsigned char *) seg_start_addr;
>       RAM_start = FAT_mem; //FAT_mem points to address in RAM not 
used
>       RAM_ptr = RAM_start;
>       do{
>         *RAM_ptr = *Flash_ptr;
> 
>         RAM_ptr++;
>         Flash_ptr++;
>       }while((unsigned int)(Flash_ptr) <= seg_end_addr);
> 
>       //run load_program from RAM
>       //*(load_program_ptr_in_RAM)(args)
>       (*RAM_load_program)(addr,filesize,0x1100,1); //STILL POINTING 
TO
> FLASH MEMORY LOCATION OF LOAD_PROGRAM
> 
> 
>     //load_program(addr,fileEntry->Size,0x1100,1);
>     
>     return;
> 
> }
> 
> 
> 
> 
> 
> 
> 
> 
> .
> 
>  
> Yahoo! Groups Links
>






The 2024 Embedded Online Conference