Can you execute code directly from RAM

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Can you execute code directly from RAM

2,720 Views
mikemandeville
Contributor II

I am currently running into some issues with our In Application Programming.   What I am trying to do is to copy the flash routines into RAM then call them.  I know have copied the routines into RAM correctly (they reside at 0x1FFF0000). I also tried to put them in the upper SRAM region as well.  When I step through the code... as soon as I try to execute from RAM, I get a USAGE FAULT, unaligned access.  But the address is cast as a ULONG*.  I also manually check the address and it is 32-bit aligned. 

What am I missing?  IS there some settings I need to enable to allow the executing code from RAM?


What I did was a create a section in the scatter file that defines the RAM section (I labeled it IAP, but that doesn't matter) I'm going to copy the flash upgrade routine to:

IAP 0x1FFFF000 UNINIT 0x000FFF ;
{
appFirmwareUpgradeRam.o (*)
}

and in that I declare the flashfunc().  Then I write to the address of that function. (I still get a usage fault, though). And a few related questions:

1) Does the Kinetis have some protection or settings that may prevent execution from RAM?
2) Does the Kinetis have user/privilege modes that need to be manipulated?
3) The K64 only has a thumb mode. How does that affect my memory addressing of instructions?


Labels (1)
4 Replies

1,693 Views
bobpaddock
Senior Contributor III

"But the address is cast as a ULONG*. "

size_t may be more appropriate, however that would fix the problem.

"1) Does the Kinetis have some protection or settings that may prevent execution from RAM?
2) Does the Kinetis have user/privilege modes that need to be manipulated? "


Varies with the part,  in general no.  Check data sheet.

"3) The K64 only has a thumb mode. How does that affect my memory addressing of instructions? "


Set bit-0 of the address.


This the code I use at startup to come items from Flash to RAM.

The linker script builds a table of the items.

/* ---------------------------------------------------------------------------------- */

static void __copy_rom_section_to_ram( uint8_t *dst_u8_ptr, uint8_t const *src_u8_ptr, uint32_t const size_to_copy );

static void __copy_rom_section_to_ram( uint8_t *dst_u8_ptr, uint8_t const *src_u8_ptr, uint32_t const size_to_copy )

{

  if( dst_u8_ptr != src_u8_ptr )

    {

      uint32_t len = size_to_copy; /* MISRA deviation */

      watchdog_service();

      while( 0U != len--)

        {

          *dst_u8_ptr++ = *src_u8_ptr++;

        }

    }

  watchdog_service();

}

/*

* Copy all sections of data and/or code that need to be in RAM

* from Flash at startup.

*

* flash_to_ram_tbl is automatically generated by the linker

* if it is referenced by the program.  It is a table of

* flash_to_ram_data structures.  The final entry in the table

* has all-zero fields.

*/

typedef struct flash_to_ram_data{

  uint32_t src_u32;     /* Source */

  uint32_t dst_u32;     /* Destination */

  uint32_t size_u32;    /* Number of bytes to copy */

}flash_to_ram_data;

extern flash_to_ram_data __flash_to_ram_tbl[];

static void __copy_rom_sections_to_ram( void );

static void __copy_rom_sections_to_ram( void )

{

  flash_to_ram_data *flash_to_ram_entry;

  /*

   * Go through the entire table, copying sections from Flash to

   * RAM, until find a zero marker in the size field:

   */

  for( flash_to_ram_entry = __flash_to_ram_tbl; (0UL != flash_to_ram_entry->size_u32); ++flash_to_ram_entry )

    {

      __copy_rom_section_to_ram( (uint8_t *) flash_to_ram_entry->dst_u32, (uint8_t *) flash_to_ram_entry->src_u32, flash_to_ram_entry->size_u32 );

    }

}

/* ---------------------------------------------------------------------------------- */

1,693 Views
mjbcswitzerland
Specialist V

Hi

I can confrm that the problem is probably that the RAM code is being called incorrectly.

It must be called as Thumb 2 code for the Cortex to execute it correctly - however I think that Bob may have made a mistake in the description because Thumb 2 requires the call with Address 0 set to '1' and not '0'.

Eg.

If the code in RAM is at 0x20000000 call it at address 0x20000001.

Regards

Mark

Kinetis: µTasker Kinetis support

K64: µTasker Kinetis FRDM-K64F support / µTasker Kinetis TWR-K64F120M support

For the complete "out-of-the-box" Kinetis experience and faster time to market

1,693 Views
bobpaddock
Senior Contributor III

Just love this system.  Nice formated code turned into crap. :-(

0 Kudos

1,693 Views
mjbcswitzerland
Specialist V

Bob

Try the advanced editor and using the C++ formatted insert (it works well as long as there are only single spaces between code and comments).

Otherwise use the HTML view (just when adding code blocks) and place the code it in a <pre></pre> block so that it remains untouched by the editor interface.

Regards

Mark