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; }
copy code from flash to RAM and then execute it from RAM
Started by ●October 7, 2005
Reply by ●October 7, 20052005-10-07
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
Reply by ●October 11, 20052005-10-11
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 >